From 8c42f2e171e57855001812ea42d5cfed8c0ff720 Mon Sep 17 00:00:00 2001 From: Muhammet Arslan Date: Fri, 1 Sep 2023 18:36:23 +0300 Subject: [PATCH 1/3] new storage context --- cmd/app/config/config.go | 3 + cmd/app/config/types.go | 5 ++ cmd/app/context/context.go | 2 + cmd/app/context/mocks/mock_app_contexter.go | 15 +++++ cmd/app/context/real_context.go | 9 ++- cmd/app/main.go | 13 ++++- pkg/storage/drivers/file/file.go | 62 +++++++++++++++++++++ pkg/storage/drivers/interface.go | 10 ++++ pkg/storage/interface.go | 8 +++ pkg/storage/options.go | 25 +++++++++ pkg/storage/storage.go | 33 +++++++++++ 11 files changed, 183 insertions(+), 2 deletions(-) create mode 100644 pkg/storage/drivers/file/file.go create mode 100644 pkg/storage/drivers/interface.go create mode 100644 pkg/storage/interface.go create mode 100644 pkg/storage/options.go create mode 100644 pkg/storage/storage.go diff --git a/cmd/app/config/config.go b/cmd/app/config/config.go index 6f82966..0525dee 100644 --- a/cmd/app/config/config.go +++ b/cmd/app/config/config.go @@ -26,4 +26,7 @@ func init() { if err := env.Parse(&Config.Nats); err != nil { panic(err) } + if err := env.Parse(&Config.Storage); err != nil { + panic(err) + } } diff --git a/cmd/app/config/types.go b/cmd/app/config/types.go index 4e353a0..21b41a3 100644 --- a/cmd/app/config/types.go +++ b/cmd/app/config/types.go @@ -55,4 +55,9 @@ type config struct { Nats struct { URL string `env:"NATS_URL" envDefault:"nats://localhost:4222"` } + + // Storage provides the storage configuration. + Storage struct { + Driver string `env:"STORAGE_DRIVER" envDefault:"file"` + } } diff --git a/cmd/app/context/context.go b/cmd/app/context/context.go index d2f6062..d561378 100644 --- a/cmd/app/context/context.go +++ b/cmd/app/context/context.go @@ -8,6 +8,7 @@ import ( "github.com/iammuho/natternet/pkg/logger" "github.com/iammuho/natternet/pkg/mongodb" "github.com/iammuho/natternet/pkg/nats" + "github.com/iammuho/natternet/pkg/storage" "github.com/iammuho/natternet/pkg/utils" ) @@ -19,6 +20,7 @@ type AppContext interface { GetJwtContext() jwt.JwtContext GetMongoContext() mongodb.MongoDBContext GetNatsContext() nats.NatsContext + GetStorageContext() storage.StorageContext GetHashingFactory() hashing.HashingFactory GetUUID() utils.UUID GetTimer() utils.Timer diff --git a/cmd/app/context/mocks/mock_app_contexter.go b/cmd/app/context/mocks/mock_app_contexter.go index 8f95d88..a609236 100644 --- a/cmd/app/context/mocks/mock_app_contexter.go +++ b/cmd/app/context/mocks/mock_app_contexter.go @@ -13,6 +13,7 @@ import ( logger "github.com/iammuho/natternet/pkg/logger" mongodb "github.com/iammuho/natternet/pkg/mongodb" nats "github.com/iammuho/natternet/pkg/nats" + storage "github.com/iammuho/natternet/pkg/storage" utils "github.com/iammuho/natternet/pkg/utils" gomock "go.uber.org/mock/gomock" ) @@ -124,6 +125,20 @@ func (mr *MockAppContextMockRecorder) GetNatsContext() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNatsContext", reflect.TypeOf((*MockAppContext)(nil).GetNatsContext)) } +// GetStorageContext mocks base method. +func (m *MockAppContext) GetStorageContext() storage.StorageContext { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetStorageContext") + ret0, _ := ret[0].(storage.StorageContext) + return ret0 +} + +// GetStorageContext indicates an expected call of GetStorageContext. +func (mr *MockAppContextMockRecorder) GetStorageContext() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageContext", reflect.TypeOf((*MockAppContext)(nil).GetStorageContext)) +} + // GetTimer mocks base method. func (m *MockAppContext) GetTimer() utils.Timer { m.ctrl.T.Helper() diff --git a/cmd/app/context/real_context.go b/cmd/app/context/real_context.go index 19c0cfa..3bc2794 100644 --- a/cmd/app/context/real_context.go +++ b/cmd/app/context/real_context.go @@ -8,6 +8,7 @@ import ( "github.com/iammuho/natternet/pkg/logger" "github.com/iammuho/natternet/pkg/mongodb" "github.com/iammuho/natternet/pkg/nats" + "github.com/iammuho/natternet/pkg/storage" "github.com/iammuho/natternet/pkg/utils" ) @@ -18,11 +19,12 @@ type appContext struct { mongoContext mongodb.MongoDBContext hashingFactory hashing.HashingFactory natsContext nats.NatsContext + storageContext storage.StorageContext UUID utils.UUID Timer utils.Timer } -func NewAppContext(logger *logger.Logger, jwt jwt.JwtContext, mongoContext mongodb.MongoDBContext, natsContext nats.NatsContext) AppContext { +func NewAppContext(logger *logger.Logger, jwt jwt.JwtContext, mongoContext mongodb.MongoDBContext, natsContext nats.NatsContext, storageContext storage.StorageContext) AppContext { ctx := context.Background() // Set the UUID @@ -41,6 +43,7 @@ func NewAppContext(logger *logger.Logger, jwt jwt.JwtContext, mongoContext mongo mongoContext: mongoContext, hashingFactory: hashingFactory, natsContext: natsContext, + storageContext: storageContext, UUID: uuid, Timer: timer, } @@ -77,3 +80,7 @@ func (c *appContext) GetHashingFactory() hashing.HashingFactory { func (c *appContext) GetNatsContext() nats.NatsContext { return c.natsContext } + +func (c *appContext) GetStorageContext() storage.StorageContext { + return c.storageContext +} diff --git a/cmd/app/main.go b/cmd/app/main.go index 0dc9de2..ceabdd9 100644 --- a/cmd/app/main.go +++ b/cmd/app/main.go @@ -19,6 +19,7 @@ import ( "github.com/iammuho/natternet/pkg/logger" "github.com/iammuho/natternet/pkg/mongodb" "github.com/iammuho/natternet/pkg/nats" + "github.com/iammuho/natternet/pkg/storage" "github.com/gofiber/fiber/v2" "github.com/gofiber/swagger" @@ -94,8 +95,18 @@ func main() { l.Panic("NATS Client failed to connect: %v", zap.Error(err)) } + // Add the storage + l.Info("Creating Storage", zap.String("driver", config.Config.Storage.Driver)) + storageContext, err := storage.NewStorage( + storage.WithStorageDriver(config.Config.Storage.Driver), + ) + + if err != nil { + l.Panic("Storage failed to initialize: %v", zap.Error(err)) + } + // Create the app context - ctx := context.NewAppContext(l, jwtContext, mongodbContext, natsContext) + ctx := context.NewAppContext(l, jwtContext, mongodbContext, natsContext, storageContext) // Register the routes v1 := httpServer.App.Group("/api/v1") diff --git a/pkg/storage/drivers/file/file.go b/pkg/storage/drivers/file/file.go new file mode 100644 index 0000000..c103cd2 --- /dev/null +++ b/pkg/storage/drivers/file/file.go @@ -0,0 +1,62 @@ +package file + +import ( + "log" + "os" + + "github.com/iammuho/natternet/pkg/storage/drivers" +) + +type file struct{} + +// NewFileStorage returns a new file storage +func NewFileStorage() drivers.DriverContext { + return &file{} +} + +// Get returns a file +func (f *file) Get() { + +} + +// Put puts a file +func (f *file) Put() { + +} + +// Delete deletes a file +func (f *file) Delete() { + +} + +// List lists files +func (f *file) List(path string) { + // list all files in a directory + dir, err := os.Open(path) + if err != nil { + panic(err) + } + // log + defer dir.Close() + + // get the list of files + files, err := dir.Readdir(0) + + // log + if err != nil { + panic(err) + } + + // log + for _, file := range files { + // log + if file.IsDir() { + // log + log.Print("Directory: ", file.Name()) + } else { + // log + log.Print("File: ", file.Name()) + } + } + +} diff --git a/pkg/storage/drivers/interface.go b/pkg/storage/drivers/interface.go new file mode 100644 index 0000000..ff23e0e --- /dev/null +++ b/pkg/storage/drivers/interface.go @@ -0,0 +1,10 @@ +package drivers + +// DriverContext is the interface for the storage driver +// TODO: add/refactor methods +type DriverContext interface { + Get() + Put() + Delete() + List(string) +} diff --git a/pkg/storage/interface.go b/pkg/storage/interface.go new file mode 100644 index 0000000..a565780 --- /dev/null +++ b/pkg/storage/interface.go @@ -0,0 +1,8 @@ +package storage + +import "github.com/iammuho/natternet/pkg/storage/drivers" + +// StorageContext is the interface for the storage +type StorageContext interface { + Driver() drivers.DriverContext +} diff --git a/pkg/storage/options.go b/pkg/storage/options.go new file mode 100644 index 0000000..860ec66 --- /dev/null +++ b/pkg/storage/options.go @@ -0,0 +1,25 @@ +package storage + +// Option is the func interface to assign options +type Option func(*StorageOptions) + +type Driver string + +const ( + // DriverFile is the file driver + DriverFile Driver = "file" + // DriverAWS is the AWS driver + DriverAWS Driver = "aws" +) + +// StorageOptions defines the options for the storage +type StorageOptions struct { + Driver Driver +} + +// WithStorageDriver sets the storage driver +func WithStorageDriver(driver string) Option { + return func(o *StorageOptions) { + o.Driver = Driver(driver) + } +} diff --git a/pkg/storage/storage.go b/pkg/storage/storage.go new file mode 100644 index 0000000..60bf31f --- /dev/null +++ b/pkg/storage/storage.go @@ -0,0 +1,33 @@ +package storage + +import ( + "github.com/iammuho/natternet/pkg/storage/drivers" + "github.com/iammuho/natternet/pkg/storage/drivers/file" +) + +type storage struct { + driver drivers.DriverContext + options StorageOptions +} + +func NewStorage(opts ...Option) (StorageContext, error) { + // Setup the driver + options := StorageOptions{} + for _, o := range opts { + o(&options) + } + + switch options.Driver { + case DriverFile: + return &storage{ + driver: file.NewFileStorage(), + options: options, + }, nil + } + + return &storage{}, nil +} + +func (s *storage) Driver() drivers.DriverContext { + return s.driver +} From 0bd953ac9241ad01d8bce5581234bf97709c5d45 Mon Sep 17 00:00:00 2001 From: Muhammet Arslan Date: Fri, 1 Sep 2023 18:42:23 +0300 Subject: [PATCH 2/3] changed list --- pkg/storage/drivers/file/file.go | 24 +++++++++++------------- pkg/storage/drivers/interface.go | 2 +- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/pkg/storage/drivers/file/file.go b/pkg/storage/drivers/file/file.go index c103cd2..e7ee85b 100644 --- a/pkg/storage/drivers/file/file.go +++ b/pkg/storage/drivers/file/file.go @@ -1,7 +1,6 @@ package file import ( - "log" "os" "github.com/iammuho/natternet/pkg/storage/drivers" @@ -30,11 +29,11 @@ func (f *file) Delete() { } // List lists files -func (f *file) List(path string) { +func (f *file) List(path string) ([]string, error) { // list all files in a directory dir, err := os.Open(path) if err != nil { - panic(err) + return nil, err } // log defer dir.Close() @@ -44,19 +43,18 @@ func (f *file) List(path string) { // log if err != nil { - panic(err) + return nil, err } - // log + // prepare the list of files + var fileList []string + + // loop through the files for _, file := range files { - // log - if file.IsDir() { - // log - log.Print("Directory: ", file.Name()) - } else { - // log - log.Print("File: ", file.Name()) - } + // append the file name to the list + fileList = append(fileList, file.Name()) } + // return the list of files + return fileList, nil } diff --git a/pkg/storage/drivers/interface.go b/pkg/storage/drivers/interface.go index ff23e0e..56f1fab 100644 --- a/pkg/storage/drivers/interface.go +++ b/pkg/storage/drivers/interface.go @@ -6,5 +6,5 @@ type DriverContext interface { Get() Put() Delete() - List(string) + List(string) ([]string, error) } From 7b25920dc5c32fe07554c5605b4ddf3179ac07c7 Mon Sep 17 00:00:00 2001 From: Muhammet Arslan Date: Fri, 1 Sep 2023 18:45:35 +0300 Subject: [PATCH 3/3] complete file driver --- pkg/storage/drivers/file/file.go | 61 +++++++++++++++++++++++++++++--- pkg/storage/drivers/interface.go | 6 ++-- 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/pkg/storage/drivers/file/file.go b/pkg/storage/drivers/file/file.go index e7ee85b..7c6265a 100644 --- a/pkg/storage/drivers/file/file.go +++ b/pkg/storage/drivers/file/file.go @@ -14,18 +14,69 @@ func NewFileStorage() drivers.DriverContext { } // Get returns a file -func (f *file) Get() { +func (f *file) Get(fileName string) ([]byte, error) { + // open the file + file, err := os.Open(fileName) + if err != nil { + return nil, err + } + + // close the file + defer file.Close() + + // get the file info + fileInfo, err := file.Stat() + + if err != nil { + return nil, err + } + + // prepare the buffer + buffer := make([]byte, fileInfo.Size()) + + // read the file + _, err = file.Read(buffer) + + if err != nil { + return nil, err + } + + return buffer, nil } // Put puts a file -func (f *file) Put() { +func (f *file) Put(fileName string, content []byte) error { + // create the file + file, err := os.Create(fileName) + + if err != nil { + return err + } + + // close the file + defer file.Close() + + // write the content + _, err = file.Write(content) + if err != nil { + return err + } + + return nil } // Delete deletes a file -func (f *file) Delete() { +func (f *file) Delete(fileName string) error { + // delete the file + err := os.Remove(fileName) + if err != nil { + return err + } + + return nil } // List lists files @@ -35,13 +86,13 @@ func (f *file) List(path string) ([]string, error) { if err != nil { return nil, err } - // log + + // close the directory defer dir.Close() // get the list of files files, err := dir.Readdir(0) - // log if err != nil { return nil, err } diff --git a/pkg/storage/drivers/interface.go b/pkg/storage/drivers/interface.go index 56f1fab..48c0831 100644 --- a/pkg/storage/drivers/interface.go +++ b/pkg/storage/drivers/interface.go @@ -3,8 +3,8 @@ package drivers // DriverContext is the interface for the storage driver // TODO: add/refactor methods type DriverContext interface { - Get() - Put() - Delete() + Get(string) ([]byte, error) + Put(string, []byte) error + Delete(string) error List(string) ([]string, error) }