custom interface; strategy pattern; service configuration; refactor
This commit is contained in:
+17
-4
@@ -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
|
||||
}
|
||||
|
||||
+2
-1
@@ -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"
|
||||
)
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ func Server() cli.Command {
|
||||
gr.Add(func() error {
|
||||
return service.Run()
|
||||
}, func(_ error) {
|
||||
|
||||
fmt.Println("shutting down grpc server")
|
||||
cancel()
|
||||
})
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
}
|
||||
+36
-33
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
_ "github.com/owncloud/ocis-accounts/pkg/store/filesystem"
|
||||
)
|
||||
Reference in New Issue
Block a user