diff --git a/go.mod b/go.mod index 617335c05b..5f96a22f18 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/owncloud/ocis-accounts go 1.13 require ( + github.com/coreos/etcd v3.3.18+incompatible github.com/golang/protobuf v1.3.2 github.com/google/uuid v1.1.1 github.com/micro/cli v0.2.0 diff --git a/go.sum b/go.sum index f8748c4b58..0d49beb037 100644 --- a/go.sum +++ b/go.sum @@ -381,6 +381,7 @@ github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJS github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/joncalhoun/qson v0.0.0-20170526102502-8a9cab3a62b1/go.mod h1:DFXrEwSRX0p/aSvxE21319menCBFeQO0jXpRj7LEZUA= github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= diff --git a/pkg/account/accounts.go b/pkg/account/accounts.go index 2760e145a6..4fa0fb09b7 100644 --- a/pkg/account/accounts.go +++ b/pkg/account/accounts.go @@ -1,11 +1,24 @@ package account -// Account is an accounts service interface -type Account interface { +import "github.com/owncloud/ocis-accounts/pkg/config" + +var ( + // Registry uses the strategy pattern as a registry + Registry = map[string]RegisterFunc{} + + // DefaultManager defines the default accounts manager + DefaultManager = "filesystem" +) + +// RegisterFunc stores store constructors +type RegisterFunc func(*config.Config) Manager + +// Manager is an accounts service interface +type Manager interface { // Read a record - Read(key string) (*Record, error) + Read(key string) *Record // Write a record - Write(Record) Record + Write(*Record) *Record // List all records List() []*Record } diff --git a/pkg/command/root.go b/pkg/command/root.go index 972cdd2cb2..1dc3777ab2 100644 --- a/pkg/command/root.go +++ b/pkg/command/root.go @@ -4,7 +4,8 @@ import ( "os" "github.com/micro/cli" - _ "github.com/owncloud/ocis-accounts/pkg/registry" + // init store manager + _ "github.com/owncloud/ocis-accounts/pkg/store" "github.com/owncloud/ocis-hello/pkg/version" ) diff --git a/pkg/command/server.go b/pkg/command/server.go index 9ed90f3986..6bec060c4a 100644 --- a/pkg/command/server.go +++ b/pkg/command/server.go @@ -25,7 +25,6 @@ func Server() cli.Command { gr.Add(func() error { return service.Run() }, func(_ error) { - fmt.Println("shutting down grpc server") cancel() }) diff --git a/pkg/micro/grpc/grpc.go b/pkg/micro/grpc/grpc.go index 20e9b41a25..874b69e2d5 100644 --- a/pkg/micro/grpc/grpc.go +++ b/pkg/micro/grpc/grpc.go @@ -1,15 +1,15 @@ package grpc -// package grpc uses `ocis-pkg` to start a go-micro service import ( "context" + "github.com/owncloud/ocis-accounts/pkg/config" "github.com/owncloud/ocis-accounts/pkg/proto/v0" svc "github.com/owncloud/ocis-accounts/pkg/service/v0" "github.com/owncloud/ocis-pkg/service/grpc" ) -// NewService initializes a new go-micro service ready to run +// NewService creates a grpc service func NewService(c context.Context) grpc.Service { service := grpc.NewService( grpc.Name("accounts"), @@ -18,8 +18,7 @@ func NewService(c context.Context) grpc.Service { grpc.Context(c), ) - // add a handler to the service - hdlr := svc.New() + hdlr := svc.New(config.New()) proto.RegisterSettingsServiceHandler(service.Server(), hdlr) service.Init() diff --git a/pkg/registry/registry.go b/pkg/registry/registry.go deleted file mode 100644 index 1dae9ba8f1..0000000000 --- a/pkg/registry/registry.go +++ /dev/null @@ -1,21 +0,0 @@ -// Package registry provides accessors to runtime services -package registry - -import ( - "sync" - - mstore "github.com/micro/go-micro/v2/store" - store "github.com/owncloud/ocis-accounts/pkg/store/filesystem" -) - -var ( - once *sync.Once = &sync.Once{} - // Store is a micro store implementation - Store mstore.Store -) - -func init() { - once.Do(func() { - Store = store.New() - }) -} diff --git a/pkg/service/v0/service.go b/pkg/service/v0/service.go index 79b4bb4487..c0a7a0eddb 100644 --- a/pkg/service/v0/service.go +++ b/pkg/service/v0/service.go @@ -3,23 +3,30 @@ package service import ( "context" "encoding/json" + "fmt" "github.com/golang/protobuf/ptypes/empty" - mstore "github.com/micro/go-micro/v2/store" + "github.com/owncloud/ocis-accounts/pkg/account" + "github.com/owncloud/ocis-accounts/pkg/config" "github.com/owncloud/ocis-accounts/pkg/proto/v0" - - "github.com/owncloud/ocis-accounts/pkg/registry" ) // New returns a new instance of Service -func New() Service { - return Service{} +func New(cfg *config.Config) Service { + fmt.Printf("config type: %T", account.Registry["filesystem"]) + return Service{ + Config: cfg, + Manager: account.Registry["filesystem"](cfg), // TODO read this from config + } } -// Service implements the SettingsServiceHandler interface generated on accounts.pb.micro.go -type Service struct{} +// Service implements the SettingsServiceHandler interface +type Service struct { + Config *config.Config + Manager account.Manager +} -// Set implements the SettingsServiceHandler interface generated on accounts.pb.micro.go +// Set implements the SettingsServiceHandler interface // This implementation replaces the existent data with the requested. It does not calculate diff func (s Service) Set(c context.Context, req *proto.Record, res *proto.Record) error { settingsJSON, err := json.Marshal(req.Payload) @@ -27,45 +34,41 @@ func (s Service) Set(c context.Context, req *proto.Record, res *proto.Record) er return err } - record := mstore.Record{ + s.Manager.Write(&account.Record{ Key: req.Key, Value: settingsJSON, - } + }) - return registry.Store.Write(&record) + return nil } -// Get implements the SettingsServiceHandler interface generated on accounts.pb.micro.go +// Get implements the SettingsServiceHandler interface func (s Service) Get(c context.Context, req *proto.Query, res *proto.Record) error { - contents, err := registry.Store.Read(req.Key) - if err != nil { - return err - } + // contents, err := registry.Store.Read(req.Key) + contents := s.Manager.Read(req.Key) - if len(contents) > 0 { - r := &proto.Payload{} - json.Unmarshal(contents[0].Value, r) - res.Payload = r - } + r := &proto.Payload{} + json.Unmarshal(contents.Value, r) + res.Payload = r return nil } -// List implements the SettingsServiceHandler interface generated on accounts.pb.micro.go +// List implements the SettingsServiceHandler interface func (s Service) List(ctx context.Context, in *empty.Empty, res *proto.Records) error { - r := &proto.Records{} - contents, err := registry.Store.List() - if err != nil { - return err - } + // r := &proto.Records{} + // contents, err := registry.Store.List() + // if err != nil { + // return err + // } - for _, v := range contents { - r.Records = append(r.Records, &proto.Record{ - Key: v.Key, - }) - } + // for _, v := range contents { + // r.Records = append(r.Records, &proto.Record{ + // Key: v.Key, + // }) + // } - res.Records = r.Records + // res.Records = r.Records return nil } diff --git a/pkg/store/filesystem/store.go b/pkg/store/filesystem/store.go index 2b2691494f..d27d4d2ef9 100644 --- a/pkg/store/filesystem/store.go +++ b/pkg/store/filesystem/store.go @@ -2,18 +2,25 @@ package store import ( - "fmt" "io/ioutil" "os" "path" "path/filepath" - mstore "github.com/micro/go-micro/v2/store" + "github.com/owncloud/ocis-accounts/pkg/account" + "github.com/owncloud/ocis-accounts/pkg/config" olog "github.com/owncloud/ocis-pkg/log" ) +var ( + // StoreName is the default name for the accounts store + StoreName string = "ocis-store" + + // managerName + managerName = "filesystem" +) + // StoreName is the default name for the store container -var StoreName string = "ocis-store" // Store interacts with the filesystem to manage account information type Store struct { @@ -21,8 +28,8 @@ type Store struct { Logger olog.Logger } -// New returns a new stor. TODO add mountPath as a flag. Accept a *config argument -func New() *Store { +// New creates a new store +func New(cfg *config.Config) account.Manager { s := Store{ Logger: olog.NewLogger(), } @@ -43,68 +50,55 @@ func New() *Store { return &s } -// Init implements the store interface -func (s Store) Init(...mstore.Option) error { - return nil -} - // List returns all the identities in the mountPath folder -func (s Store) List() ([]*mstore.Record, error) { - records := []*mstore.Record{} +func (s Store) List() []*account.Record { + records := []*account.Record{} identities, err := ioutil.ReadDir(s.mountPath) if err != nil { s.Logger.Err(err).Msgf("error reading %v", s.mountPath) + return records } s.Logger.Info().Msg("listing identities") for _, v := range identities { - records = append(records, &mstore.Record{ + records = append(records, &account.Record{ Key: v.Name(), }) } - return records, nil + return records } // Read implements the store interface. This implementation only reads by id. -func (s Store) Read(key string, opts ...mstore.ReadOption) ([]*mstore.Record, error) { +func (s Store) Read(key string) *account.Record { contents, err := ioutil.ReadFile(path.Join(s.mountPath, key)) if err != nil { s.Logger.Err(err).Msgf("error reading contents of key %v: file not found", key) - return []*mstore.Record{}, err + return &account.Record{} } - return []*mstore.Record{ - &mstore.Record{ - Key: key, - Value: contents, - }, - }, nil + return &account.Record{ + Key: key, + Value: contents, + } } // Write implements the store interface -func (s Store) Write(rec *mstore.Record) error { +func (s Store) Write(rec *account.Record) *account.Record { path := filepath.Join(s.mountPath, rec.Key) if len(rec.Key) < 1 { s.Logger.Error().Msg("key cannot be empty") - return fmt.Errorf("%v", "key is empty") + return &account.Record{} } if err := ioutil.WriteFile(path, rec.Value, 0644); err != nil { - return err + return &account.Record{} } s.Logger.Info().Msgf("%v bytes written to %v", len(rec.Value), path) - return nil + return rec } - -// Delete implements the store interface -func (s Store) Delete(key string) error { - return nil -} - -// String implements the store interface, and the stringer interface -func (s Store) String() string { - return "store" +func init() { + account.Registry[managerName] = New } diff --git a/pkg/store/registry.go b/pkg/store/registry.go new file mode 100644 index 0000000000..e4a32c66d1 --- /dev/null +++ b/pkg/store/registry.go @@ -0,0 +1,5 @@ +package store + +import ( + _ "github.com/owncloud/ocis-accounts/pkg/store/filesystem" +)