From 29a75bced9addab4237b5b48dfc00daff4008c9b Mon Sep 17 00:00:00 2001 From: mr Date: Thu, 18 Jul 2024 11:51:12 +0200 Subject: [PATCH] organize + graph --- calendar.go | 1 - data.go | 20 -- data/data.go | 23 -- data/data_mongo_accessor.go | 38 ---- data/data_test.go | 47 ----- data/datacenter_workflows.go | 1 - data_mongo_accessor.go | 33 --- data_test.go | 46 ---- datacenter.go | 37 ---- datacenter/datacenter.go | 39 ---- datacenter/datacenter_mongo_accessor.go | 33 --- datacenter/datacenter_test.go | 47 ----- datacenter_mongo_accessor.go | 28 --- datacenter_test.go | 46 ---- datacenter_workflows.go | 1 - dbs/dbs.go | 22 ++ {mongo => dbs/mongo}/mongo.go | 150 +++++++------ mongo_test.go => dbs/mongo/mongo_test.go | 4 +- {mongo => dbs/mongo}/mongo_utils.go | 37 ++-- graph.go | 1 - graphic_element.go | 12 -- link.go | 7 - link/link.go | 7 - logger.go | 8 +- models/models.go | 29 +++ models/resources/data/data.go | 29 +++ models/resources/data/data_mongo_accessor.go | 39 ++++ models/resources/data/data_test.go | 45 ++++ models/resources/datacenter/datacenter.go | 52 +++++ .../datacenter/datacenter_mongo_accessor.go | 43 ++++ .../resources/datacenter/datacenter_test.go | 46 ++++ models/resources/processing/processing.go | 46 ++++ .../processing/processing_mongo_accessor.go | 44 ++++ .../resources/processing/processing_test.go | 45 ++++ models/resources/resource.go | 54 +++++ models/resources/storage/storage.go | 39 ++++ .../storage/storage_mongo_accessor.go | 44 ++++ models/resources/storage/storage_test.go | 46 ++++ models/utils/abstracts.go | 32 +++ models/utils/enums.go | 8 + models/utils/interfaces.go | 14 ++ models/workflow/graph/graph.go | 41 ++++ models/workflow/workflow.go | 45 ++++ models/workflow/workflow_mongo_accessor.go | 43 ++++ .../workflow}/workflow_schedule.go | 0 models/workflow/workflow_test.go | 43 ++++ mongo.go | 199 ------------------ processing.go | 30 --- processing/processing.go | 32 --- processing/processing_mongo_accessor.go | 38 ---- processing/processing_test.go | 48 ----- processing_mongo_accessor.go | 33 --- processing_test.go | 47 ----- resource.go | 96 --------- resource_set.go | 6 - storage.go | 22 -- storage/storage.go | 24 --- storage/storage_mongo_accessor.go | 38 ---- storage/storage_test.go | 48 ----- storage_mongo_accessor.go | 33 --- storage_test.go | 47 ----- user_workflows.go | 1 - workflow.go | 25 --- workflow/workflow.go | 34 --- workflow/workflow_mongo_accessor.go | 34 --- workflow/workflow_test.go | 45 ---- workflow_mongo_accessor.go | 29 --- workflow_schedule.go | 15 -- workflow_test.go | 44 ---- 69 files changed, 952 insertions(+), 1531 deletions(-) delete mode 100644 calendar.go delete mode 100644 data.go delete mode 100644 data/data.go delete mode 100644 data/data_mongo_accessor.go delete mode 100644 data/data_test.go delete mode 100644 data/datacenter_workflows.go delete mode 100644 data_mongo_accessor.go delete mode 100644 data_test.go delete mode 100644 datacenter.go delete mode 100644 datacenter/datacenter.go delete mode 100644 datacenter/datacenter_mongo_accessor.go delete mode 100644 datacenter/datacenter_test.go delete mode 100644 datacenter_mongo_accessor.go delete mode 100644 datacenter_test.go delete mode 100644 datacenter_workflows.go create mode 100644 dbs/dbs.go rename {mongo => dbs/mongo}/mongo.go (52%) rename mongo_test.go => dbs/mongo/mongo_test.go (81%) rename {mongo => dbs/mongo}/mongo_utils.go (55%) delete mode 100644 graph.go delete mode 100644 graphic_element.go delete mode 100644 link.go delete mode 100644 link/link.go create mode 100644 models/models.go create mode 100644 models/resources/data/data.go create mode 100644 models/resources/data/data_mongo_accessor.go create mode 100644 models/resources/data/data_test.go create mode 100644 models/resources/datacenter/datacenter.go create mode 100644 models/resources/datacenter/datacenter_mongo_accessor.go create mode 100644 models/resources/datacenter/datacenter_test.go create mode 100644 models/resources/processing/processing.go create mode 100644 models/resources/processing/processing_mongo_accessor.go create mode 100644 models/resources/processing/processing_test.go create mode 100644 models/resources/resource.go create mode 100644 models/resources/storage/storage.go create mode 100644 models/resources/storage/storage_mongo_accessor.go create mode 100644 models/resources/storage/storage_test.go create mode 100644 models/utils/abstracts.go create mode 100644 models/utils/enums.go create mode 100644 models/utils/interfaces.go create mode 100644 models/workflow/graph/graph.go create mode 100644 models/workflow/workflow.go create mode 100644 models/workflow/workflow_mongo_accessor.go rename {workflow => models/workflow}/workflow_schedule.go (100%) create mode 100644 models/workflow/workflow_test.go delete mode 100644 mongo.go delete mode 100644 processing.go delete mode 100644 processing/processing.go delete mode 100644 processing/processing_mongo_accessor.go delete mode 100644 processing/processing_test.go delete mode 100644 processing_mongo_accessor.go delete mode 100644 processing_test.go delete mode 100644 resource.go delete mode 100644 resource_set.go delete mode 100644 storage.go delete mode 100644 storage/storage.go delete mode 100644 storage/storage_mongo_accessor.go delete mode 100644 storage/storage_test.go delete mode 100644 storage_mongo_accessor.go delete mode 100644 storage_test.go delete mode 100644 user_workflows.go delete mode 100644 workflow.go delete mode 100644 workflow/workflow.go delete mode 100644 workflow/workflow_mongo_accessor.go delete mode 100644 workflow/workflow_test.go delete mode 100644 workflow_mongo_accessor.go delete mode 100644 workflow_schedule.go delete mode 100644 workflow_test.go diff --git a/calendar.go b/calendar.go deleted file mode 100644 index 692632c..0000000 --- a/calendar.go +++ /dev/null @@ -1 +0,0 @@ -package oclib diff --git a/data.go b/data.go deleted file mode 100644 index c4a4079..0000000 --- a/data.go +++ /dev/null @@ -1,20 +0,0 @@ -package oclib - - -type Data struct { - AbstractResource - - Protocols []string `json:"protocol,omitempty" bson:"protocol,omitempty"` //TODO Enum type - DataType string `json:"datatype" required:"true" bson:"datatype"` - Example string `json:"example" bson:"example" required:"true" validate:"required" description:"base64 encoded data"` - -} - - -func (d *Data) GetType() ResourceType{ - return DATA -} - - - - diff --git a/data/data.go b/data/data.go deleted file mode 100644 index 458c108..0000000 --- a/data/data.go +++ /dev/null @@ -1,23 +0,0 @@ -package data - -import ( - oclib "oc-lib" -) - -type Data struct { - oclib.AbstractResource - - Protocols []string `json:"protocol,omitempty" bson:"protocol,omitempty"` //TODO Enum type - DataType string `json:"datatype" required:"true" bson:"datatype"` - Example string `json:"example" bson:"example" required:"true" validate:"required" description:"base64 encoded data"` - -} - - -func (d *Data) GetType() oclib.ResourceType{ - return oclib.DATA -} - - - - diff --git a/data/data_mongo_accessor.go b/data/data_mongo_accessor.go deleted file mode 100644 index 6e66144..0000000 --- a/data/data_mongo_accessor.go +++ /dev/null @@ -1,38 +0,0 @@ -package data - -import ( - logger "oc-lib/logs" - mongo "oc-lib/mongo" -) - - type DataMongoAccessor struct{ - - } - - -func (dma *DataMongoAccessor) StoreOne(data Data) string { - - id, err := mongo.StoreOne(data,"data") - if err != nil{ - l := logger.CreateLogger("oclib","") - l.Error().Msg("Could not store " + data.Name + " to db. Error: " + err.Error()) - return "" - } - return id -} - -func (dma *DataMongoAccessor) LoadOne(id string) Data { - - var data Data - - res_mongo, err := mongo.LoadOne(id,"data") - if err != nil{ - l := logger.CreateLogger("oclib","") - l.Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error()) - return Data{} - } - - res_mongo.Decode(&data) - - return data -} \ No newline at end of file diff --git a/data/data_test.go b/data/data_test.go deleted file mode 100644 index 6efdc2a..0000000 --- a/data/data_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package data - -import ( - oclib "oc-lib" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestStoreOneData(t *testing.T){ - d := Data{DataType: "jpeg", Example: "123456", - AbstractResource: oclib.AbstractResource{ - Uuid: "123", - Name: "testData", - Description: "Lorem Ipsum", - Logo : "azerty.com", - Owner: "toto", - OwnerLogo: "totoLogo", - SourceUrl: "azerty.fr", - }, - } - - dma := DataMongoAccessor{} - id := dma.StoreOne(d) - - assert.NotEmpty(t, id) -} - -func TestLoadOneDate(t *testing.T){ - d := Data{DataType: "jpeg", Example: "123456", - AbstractResource: oclib.AbstractResource{ - Uuid: "123", - Name: "testData", - Description: "Lorem Ipsum", - Logo : "azerty.com", - Owner: "toto", - OwnerLogo: "totoLogo", - SourceUrl: "azerty.fr", - }, - } - - dma := DataMongoAccessor{} - id := dma.StoreOne(d) - new_d := dma.LoadOne(id) - - assert.Equal(t,d, new_d) -} \ No newline at end of file diff --git a/data/datacenter_workflows.go b/data/datacenter_workflows.go deleted file mode 100644 index 0ad59c2..0000000 --- a/data/datacenter_workflows.go +++ /dev/null @@ -1 +0,0 @@ -package data diff --git a/data_mongo_accessor.go b/data_mongo_accessor.go deleted file mode 100644 index 4970147..0000000 --- a/data_mongo_accessor.go +++ /dev/null @@ -1,33 +0,0 @@ -package oclib - - type DataMongoAccessor struct{ - - } - - -func (dma *DataMongoAccessor) StoreOne(data Data) string { - - id, err := StoreOne(data,"data") - if err != nil{ - l := CreateLogger("oclib","") - l.Error().Msg("Could not store " + data.Name + " to db. Error: " + err.Error()) - return "" - } - return id -} - -func (dma *DataMongoAccessor) LoadOne(id string) Data { - - var data Data - - res_mongo, err := LoadOne(id,"data") - if err != nil{ - l := CreateLogger("oclib","") - l.Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error()) - return Data{} - } - - res_mongo.Decode(&data) - - return data -} \ No newline at end of file diff --git a/data_test.go b/data_test.go deleted file mode 100644 index 46d83fc..0000000 --- a/data_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package oclib - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestStoreOneData(t *testing.T){ - d := Data{DataType: "jpeg", Example: "123456", - AbstractResource: AbstractResource{ - Uuid: "123", - Name: "testData", - Description: "Lorem Ipsum", - Logo : "azerty.com", - Owner: "toto", - OwnerLogo: "totoLogo", - SourceUrl: "azerty.fr", - }, - } - - dma := DataMongoAccessor{} - id := dma.StoreOne(d) - - assert.NotEmpty(t, id) -} - -func TestLoadOneDate(t *testing.T){ - d := Data{DataType: "jpeg", Example: "123456", - AbstractResource: AbstractResource{ - Uuid: "123", - Name: "testData", - Description: "Lorem Ipsum", - Logo : "azerty.com", - Owner: "toto", - OwnerLogo: "totoLogo", - SourceUrl: "azerty.fr", - }, - } - - dma := DataMongoAccessor{} - id := dma.StoreOne(d) - new_d := dma.LoadOne(id) - - assert.Equal(t,d, new_d) -} \ No newline at end of file diff --git a/datacenter.go b/datacenter.go deleted file mode 100644 index 3a6ce88..0000000 --- a/datacenter.go +++ /dev/null @@ -1,37 +0,0 @@ -package oclib - -type Datacenter struct { - AbstractResource `json:"resource" required:"true"` - - Owner string `json:"owner" required:"true"` - BookingPrice int `json:"booking_price" required:"true"` - - CPU DatacenterCpuModel `json:"cpu,omitempty"` - RAM DatacenterMemoryModel `json:"ram,omitempty"` - GPU []DatacenterGpuModel `json:"gpu,omitempty"` -} - -type DatacenterCpuModel struct { - Cores uint `json:"cores,omitempty"` //TODO: validate - Architecture string `json:"architecture,omitempty"` //TOOD: enum - Shared bool `json:"shared,omitempty"` - MinimumMemory uint `json:"minimum_memory,omitempty"` - Platform string `json:"platform,omitempty"` -} - -type DatacenterMemoryModel struct { - Size uint `json:"size,omitempty" description:"Units in MB"` - Ecc bool `json:"ecc,omitempty"` -} - -type DatacenterGpuModel struct { - CudaCores uint `json:"cuda_cores,omitempty"` - Model string `json:"model,omitempty"` - Memory uint `json:"memory,omitempty" description:"Units in MB"` - TensorCores uint `json:"tensor_cores,omitempty"` -} - - -func (d *Datacenter) GetType() ResourceType{ - return DATACENTER -} \ No newline at end of file diff --git a/datacenter/datacenter.go b/datacenter/datacenter.go deleted file mode 100644 index 73ca4ad..0000000 --- a/datacenter/datacenter.go +++ /dev/null @@ -1,39 +0,0 @@ -package datacenter - -import oclib "oc-lib" - -type Datacenter struct { - oclib.AbstractResource `json:"resource" required:"true"` - - Owner string `json:"owner" required:"true"` - BookingPrice int `json:"booking_price" required:"true"` - - CPU DatacenterCpuModel `json:"cpu,omitempty"` - RAM DatacenterMemoryModel `json:"ram,omitempty"` - GPU []DatacenterGpuModel `json:"gpu,omitempty"` -} - -type DatacenterCpuModel struct { - Cores uint `json:"cores,omitempty"` //TODO: validate - Architecture string `json:"architecture,omitempty"` //TOOD: enum - Shared bool `json:"shared,omitempty"` - MinimumMemory uint `json:"minimum_memory,omitempty"` - Platform string `json:"platform,omitempty"` -} - -type DatacenterMemoryModel struct { - Size uint `json:"size,omitempty" description:"Units in MB"` - Ecc bool `json:"ecc,omitempty"` -} - -type DatacenterGpuModel struct { - CudaCores uint `json:"cuda_cores,omitempty"` - Model string `json:"model,omitempty"` - Memory uint `json:"memory,omitempty" description:"Units in MB"` - TensorCores uint `json:"tensor_cores,omitempty"` -} - - -func (d *Datacenter) GetType() oclib.ResourceType{ - return oclib.DATACENTER -} \ No newline at end of file diff --git a/datacenter/datacenter_mongo_accessor.go b/datacenter/datacenter_mongo_accessor.go deleted file mode 100644 index be99fc6..0000000 --- a/datacenter/datacenter_mongo_accessor.go +++ /dev/null @@ -1,33 +0,0 @@ -package datacenter - -import ( - logs "oc-lib/logs" - "oc-lib/mongo" -) - -type DatacenterMongoAccessor struct{} - -func (dca *DatacenterMongoAccessor) StoreOne(datacenter Datacenter) string { - id, err := mongo.StoreOne(datacenter, "datacenter") - if err != nil { - l := logs.CreateLogger("oclib", "") - l.Error().Msg("Could not store " + datacenter.Name + " to db. Error: " + err.Error()) - return "" - } - return id -} - -func (dca *DatacenterMongoAccessor) LoadOne(id string) Datacenter { - var datacenter Datacenter - - res_mongo, err := mongo.LoadOne(id, "datacenter") - if err != nil { - l := logs.CreateLogger("oclib", "") - l.Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error()) - return Datacenter{} - } - - res_mongo.Decode(&datacenter) - - return datacenter -} diff --git a/datacenter/datacenter_test.go b/datacenter/datacenter_test.go deleted file mode 100644 index 4397e1f..0000000 --- a/datacenter/datacenter_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package datacenter - -import ( - oclib "oc-lib" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestStoreOneDatacenter(t *testing.T){ - dc := Datacenter{Owner: "toto", BookingPrice: 123, - AbstractResource: oclib.AbstractResource{ - Uuid: "123", - Name: "testDatacenter", - Description: "Lorem Ipsum", - Logo : "azerty.com", - Owner: "toto", - OwnerLogo: "totoLogo", - SourceUrl: "azerty.fr", - }, - } - - dcma := DatacenterMongoAccessor{} - id := dcma.StoreOne(dc) - - assert.NotEmpty(t, id) -} - -func TestLoadOneDatacenter(t *testing.T){ - dc := Datacenter{Owner: "toto", BookingPrice: 123, - AbstractResource: oclib.AbstractResource{ - Uuid: "123", - Name: "testDatacenter", - Description: "Lorem Ipsum", - Logo : "azerty.com", - Owner: "toto", - OwnerLogo: "totoLogo", - SourceUrl: "azerty.fr", - }, - } - - dcma := DatacenterMongoAccessor{} - id := dcma.StoreOne(dc) - new_dc := dcma.LoadOne(id) - - assert.Equal(t,dc, new_dc) -} \ No newline at end of file diff --git a/datacenter_mongo_accessor.go b/datacenter_mongo_accessor.go deleted file mode 100644 index daae29b..0000000 --- a/datacenter_mongo_accessor.go +++ /dev/null @@ -1,28 +0,0 @@ -package oclib - -type DatacenterMongoAccessor struct{} - -func (dca *DatacenterMongoAccessor) StoreOne(datacenter Datacenter) string { - id, err := StoreOne(datacenter, "datacenter") - if err != nil { - l := CreateLogger("oclib", "") - l.Error().Msg("Could not store " + datacenter.Name + " to db. Error: " + err.Error()) - return "" - } - return id -} - -func (dca *DatacenterMongoAccessor) LoadOne(id string) Datacenter { - var datacenter Datacenter - - res_mongo, err := LoadOne(id, "datacenter") - if err != nil { - l := CreateLogger("oclib", "") - l.Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error()) - return Datacenter{} - } - - res_mongo.Decode(&datacenter) - - return datacenter -} diff --git a/datacenter_test.go b/datacenter_test.go deleted file mode 100644 index 0a64a86..0000000 --- a/datacenter_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package oclib - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestStoreOneDatacenter(t *testing.T){ - dc := Datacenter{Owner: "toto", BookingPrice: 123, - AbstractResource: AbstractResource{ - Uuid: "123", - Name: "testDatacenter", - Description: "Lorem Ipsum", - Logo : "azerty.com", - Owner: "toto", - OwnerLogo: "totoLogo", - SourceUrl: "azerty.fr", - }, - } - - dcma := DatacenterMongoAccessor{} - id := dcma.StoreOne(dc) - - assert.NotEmpty(t, id) -} - -func TestLoadOneDatacenter(t *testing.T){ - dc := Datacenter{Owner: "toto", BookingPrice: 123, - AbstractResource: AbstractResource{ - Uuid: "123", - Name: "testDatacenter", - Description: "Lorem Ipsum", - Logo : "azerty.com", - Owner: "toto", - OwnerLogo: "totoLogo", - SourceUrl: "azerty.fr", - }, - } - - dcma := DatacenterMongoAccessor{} - id := dcma.StoreOne(dc) - new_dc := dcma.LoadOne(id) - - assert.Equal(t,dc, new_dc) -} \ No newline at end of file diff --git a/datacenter_workflows.go b/datacenter_workflows.go deleted file mode 100644 index 692632c..0000000 --- a/datacenter_workflows.go +++ /dev/null @@ -1 +0,0 @@ -package oclib diff --git a/dbs/dbs.go b/dbs/dbs.go new file mode 100644 index 0000000..11d8769 --- /dev/null +++ b/dbs/dbs.go @@ -0,0 +1,22 @@ +package dbs + +import ( + "go.mongodb.org/mongo-driver/bson" +) + +type Input = map[string]interface{} + +func InputToBson(i Input, isUpdate bool) bson.D { + input := bson.D{} + for k, v := range i { + if k == "id" { + input = append(input, bson.E{Key: "_id", Value: v}) + } else { + input = append(input, bson.E{Key: k, Value: v}) + } + } + if isUpdate { + return bson.D{{Key: "$set", Value: input}} + } + return input +} diff --git a/mongo/mongo.go b/dbs/mongo/mongo.go similarity index 52% rename from mongo/mongo.go rename to dbs/mongo/mongo.go index 4424e51..4730f28 100644 --- a/mongo/mongo.go +++ b/dbs/mongo/mongo.go @@ -4,34 +4,29 @@ import ( "context" "encoding/json" "errors" + lib "oc-lib" + "oc-lib/dbs" "os" "time" - "github.com/rs/zerolog" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" - - "oc-lib/logs" ) var ( - mngoClient *mongo.Client - mngoDB *mongo.Database - MngoCtx context.Context - cancel context.CancelFunc - logger zerolog.Logger - existingCollections []string + mngoClient *mongo.Client + mngoDB *mongo.Database + MngoCtx context.Context + cancel context.CancelFunc + + existingCollections []string ResourceMap map[string]interface{} - ) - - func init() { - // var baseConfig string var err error var conf map[string]string @@ -39,15 +34,15 @@ func init() { var DBname string ResourceMap = make(map[string]interface{}) - - logger := logs.CreateLogger("oclib","") + + lib.Logger = lib.CreateLogger("oclib", "") db_conf, err := os.ReadFile("tests/oclib_conf.json") if err != nil { - logger.Fatal().Msg("Could not find configuration file") + lib.Logger.Fatal().Msg("Could not find configuration file") } - json.Unmarshal(db_conf,&conf) - + json.Unmarshal(db_conf, &conf) + if len(os.Getenv("DOCKER_ENVIRONMENT")) == 0 { MongoURL = conf["DB_URL_LOCAL"] } else { @@ -56,101 +51,92 @@ func init() { DBname = conf["DCNAME"] + "-" + conf["DBPOINT"] + lib.Logger.Info().Msg("Connecting to" + MongoURL) - logger.Info().Msg("Connecting to" + MongoURL) - MngoCtx, cancel = context.WithTimeout(context.Background(), 10*time.Second) defer cancel() createClient(MongoURL) - logger.Info().Msg("Connecting mongo client to db " + DBname) - prepareDB(conf["DCNAME"],conf["DBPOINT"]) + lib.Logger.Info().Msg("Connecting mongo client to db " + DBname) + prepareDB(conf["DCNAME"], conf["DBPOINT"]) - logger.Info().Msg("Database is READY") + lib.Logger.Info().Msg("Database is READY") } -func createClient(MongoURL string){ +func createClient(MongoURL string) { var err error // Allows us to use marshal and unmarshall with results of FindOne() and others - bsonOpts := &options.BSONOptions { + bsonOpts := &options.BSONOptions{ UseJSONStructTags: true, - NilSliceAsEmpty: true, + NilSliceAsEmpty: true, } clientOptions := options.Client().ApplyURI(MongoURL).SetBSONOptions(bsonOpts) - mngoClient, err = mongo.Connect(MngoCtx,clientOptions) + mngoClient, err = mongo.Connect(MngoCtx, clientOptions) if err != nil { - logger.Fatal().Msg("Mongodb NewClient " + MongoURL + ":" + "err" ) + lib.Logger.Fatal().Msg("Mongodb NewClient " + MongoURL + ":" + "err") panic(err) } - // Ping the primary if mngoClient, err = mongo.Connect(MngoCtx, clientOptions); err != nil { - logger.Fatal().Msg("Mongodb connect " + MongoURL + ":" + "err" ) + lib.Logger.Fatal().Msg("Mongodb connect " + MongoURL + ":" + "err") panic(err) } if err = mngoClient.Ping(MngoCtx, nil); err != nil { - logger.Fatal().Msg("Mongodb ping " + MongoURL + ":" + "err" ) + lib.Logger.Fatal().Msg("Mongodb ping " + MongoURL + ":" + "err") panic(err) } } func prepareDB(dc_name string, db_point string) { - var err error - DBname := dc_name + "-" + db_point + DBname := dc_name + "-" + db_point mngoDB = mngoClient.Database(DBname) - - list_collection := [...]string{"data","processing","storage","datacenter","workspace","schedule","workflow"} - existingCollections, err = mngoDB.ListCollectionNames(MngoCtx, bson.D{}) + list_collection := [...]string{"data", "processing", "storage", "datacenter", "workspace", "schedule", "workflow"} + + existingCollections, err = mngoDB.ListCollectionNames(MngoCtx, bson.D{}) if err != nil { - logger.Fatal().Msg("Error contacting MongoDB\n" + err.Error()) + lib.Logger.Fatal().Msg("Error contacting MongoDB\n" + err.Error()) } collectionMap := make(map[string]bool) - for _, name := range existingCollections { - collectionMap[name] = true - } - + for _, name := range existingCollections { + collectionMap[name] = true + } // Only do the collection definition process if it doesn't already exists // we add the collection to the collection map from mongo/mongo_utils to provide faster access to the collection - - for _, collection_name := range(list_collection){ + for _, collection_name := range list_collection { new_collection := mngoDB.Collection(collection_name) if _, exists := collectionMap[collection_name]; !exists { createCollection(collection_name, new_collection) - } else{ + } else { CollectionMap[collection_name] = new_collection } - - } + } } // Creates the collection with index specified in mongo/mongo_collections // or use the basic collection creation function -func createCollection(collection_name string, new_collection *mongo.Collection) { - - var err error - +func createCollection(collection_name string, new_collection *mongo.Collection) { + var err error CollectionMap[collection_name] = new_collection - - _, exists := IndexesMap[collection_name]; - if exists{ + _, exists := IndexesMap[collection_name] + if exists { if _, err = new_collection.Indexes().CreateMany(MngoCtx, IndexesMap[collection_name]); err != nil { var cmdErr mongo.CommandError if errors.As(err, &cmdErr) && cmdErr.Code != 85 { - logger.Fatal().Msg("Error creating indexes for " + collection_name + " collection : \n" + err.Error()) + lib.Logger.Fatal().Msg("Error creating indexes for " + collection_name + " collection : \n" + err.Error()) panic(err) } else if !errors.As(err, &cmdErr) { - logger.Fatal().Msg("Unexpected error: " + err.Error()) + lib.Logger.Fatal().Msg("Unexpected error: " + err.Error()) panic(err) } } @@ -160,26 +146,51 @@ func createCollection(collection_name string, new_collection *mongo.Collection) } +func DeleteOne(id string, collection_name string) (int64, error) { + filter := bson.M{"_id": GetObjIDFromString(id)} + targetDBCollection := CollectionMap[collection_name] + opts := options.Delete().SetHint(bson.D{{Key: "_id", Value: 1}}) + MngoCtx, cancel = context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + result, err := targetDBCollection.DeleteOne(MngoCtx, filter, opts) + if err != nil { + lib.Logger.Error().Msg("Couldn't insert resource: " + err.Error()) + return 0, err + } + return result.DeletedCount, nil +} + +func UpdateOne(set map[string]interface{}, id string, collection_name string) (string, error) { + filter := bson.M{"_id": GetObjIDFromString(id)} + targetDBCollection := CollectionMap[collection_name] + MngoCtx, cancel = context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + result, err := targetDBCollection.UpdateOne(MngoCtx, filter, dbs.InputToBson(set, true)) + if err != nil { + lib.Logger.Error().Msg("Couldn't insert resource: " + err.Error()) + return "", err + } + return result.UpsertedID.(primitive.ObjectID).Hex(), nil +} + func StoreOne(obj interface{}, collection_name string) (string, error) { targetDBCollection := CollectionMap[collection_name] MngoCtx, cancel = context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - result, err := targetDBCollection.InsertOne(MngoCtx,obj) + result, err := targetDBCollection.InsertOne(MngoCtx, obj) if err != nil { - logger.Error().Msg("Couldn't insert resource: " + err.Error()) + lib.Logger.Error().Msg("Couldn't insert resource: " + err.Error()) return "", err } return result.InsertedID.(primitive.ObjectID).Hex(), nil } -func LoadOne(id string, collection_name string) ( res *mongo.SingleResult , err error){ - - // new_obj := ResourceMap[collection_name] - // var doc bson.D - +func LoadOne(id string, collection_name string) (res *mongo.SingleResult, err error) { filter := bson.M{"_id": GetObjIDFromString(id)} targetDBCollection := CollectionMap[collection_name] @@ -187,23 +198,10 @@ func LoadOne(id string, collection_name string) ( res *mongo.SingleResult , err defer cancel() res = targetDBCollection.FindOne(MngoCtx, filter) - if res.Err() != nil { - logger.Error().Msg("Couldn't find resource " + id + ". Error : " + res.Err().Error()) + lib.Logger.Error().Msg("Couldn't find resource " + id + ". Error : " + res.Err().Error()) err = res.Err() return nil, err } - return res, nil - } - -func GetObjIDFromString(id string) interface{} { - objectID, err := primitive.ObjectIDFromHex(id) - if err == nil { - return objectID - } - - return id -} - diff --git a/mongo_test.go b/dbs/mongo/mongo_test.go similarity index 81% rename from mongo_test.go rename to dbs/mongo/mongo_test.go index f04a2f4..4ac00e0 100644 --- a/mongo_test.go +++ b/dbs/mongo/mongo_test.go @@ -1,6 +1,6 @@ -package oclib +package mongo // func TestMongoInit(T *testing.T){ // MongoInit() // fmt.Printf("It worked !") -// } \ No newline at end of file +// } diff --git a/mongo/mongo_utils.go b/dbs/mongo/mongo_utils.go similarity index 55% rename from mongo/mongo_utils.go rename to dbs/mongo/mongo_utils.go index d2972a4..de41a75 100644 --- a/mongo/mongo_utils.go +++ b/dbs/mongo/mongo_utils.go @@ -2,6 +2,7 @@ package mongo import ( "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" ) @@ -14,33 +15,41 @@ func init() { IndexesMap = make(map[string][]mongo.IndexModel) IndexesMap["data"] = append(IndexesMap["data"], mongo.IndexModel{Keys: bson.D{ - {Key: "description", Value:"text"}, - {Key: "example", Value:"text"}}, + {Key: "description", Value: "text"}, + {Key: "example", Value: "text"}}, }) IndexesMap["datacenter"] = append(IndexesMap["datacenter"], mongo.IndexModel{Keys: bson.D{ - {Key: "description", Value:"text"}, - {Key: "example", Value:"text"}, - {Key: "owner", Value:"text"}}, + {Key: "description", Value: "text"}, + {Key: "example", Value: "text"}, + {Key: "owner", Value: "text"}}, }) IndexesMap["storage"] = append(IndexesMap["storage"], mongo.IndexModel{Keys: bson.D{ - {Key: "description", Value:"text"}, - {Key: "example", Value:"text"}}, + {Key: "description", Value: "text"}, + {Key: "example", Value: "text"}}, }) IndexesMap["processing"] = append(IndexesMap["processing"], mongo.IndexModel{Keys: bson.D{ - {Key: "description", Value:"text"}, - {Key: "example", Value:"text"}, - {Key: "owner", Value:"text"}, + {Key: "description", Value: "text"}, + {Key: "example", Value: "text"}, + {Key: "owner", Value: "text"}, }, }) IndexesMap["workflow"] = append(IndexesMap["workflow"], mongo.IndexModel{Keys: bson.D{ - {Key: "description", Value:"text"}, - {Key: "example", Value:"text"}, - {Key: "owner", Value:"text"}, + {Key: "description", Value: "text"}, + {Key: "example", Value: "text"}, + {Key: "owner", Value: "text"}, }, }) -} \ No newline at end of file +} + +func GetObjIDFromString(id string) interface{} { + objectID, err := primitive.ObjectIDFromHex(id) + if err == nil { + return objectID + } + return id +} diff --git a/graph.go b/graph.go deleted file mode 100644 index 692632c..0000000 --- a/graph.go +++ /dev/null @@ -1 +0,0 @@ -package oclib diff --git a/graphic_element.go b/graphic_element.go deleted file mode 100644 index b99325e..0000000 --- a/graphic_element.go +++ /dev/null @@ -1,12 +0,0 @@ -package oclib - -type Coordinate struct { - x int - y int -} - -type GraphicElement struct{ - ID string `json:"ID" required:"true"` - style string `json:"style" required:"true"` - xy Coordinate `json:"xy" required:"true"` -} \ No newline at end of file diff --git a/link.go b/link.go deleted file mode 100644 index 7cd12b9..0000000 --- a/link.go +++ /dev/null @@ -1,7 +0,0 @@ -package oclib - -type Link struct { - Source string - Destination string -} - diff --git a/link/link.go b/link/link.go deleted file mode 100644 index 832c2c9..0000000 --- a/link/link.go +++ /dev/null @@ -1,7 +0,0 @@ -package link - -type Link struct { - Source string - Destination string -} - diff --git a/logger.go b/logger.go index feacb5e..da03ca5 100644 --- a/logger.go +++ b/logger.go @@ -9,7 +9,7 @@ import ( "github.com/rs/zerolog" ) -var logger zerolog.Logger +var Logger zerolog.Logger // CreateLogger // Create a new logger @@ -33,9 +33,9 @@ func CreateLogger(appname string, url string) zerolog.Logger { multiWriter := zerolog.MultiLevelWriter(consoleWriter, lokiWriter) - logger = zerolog.New(multiWriter).With().Timestamp().Logger() + Logger = zerolog.New(multiWriter).With().Timestamp().Logger() } else { - logger = zerolog.New(os.Stdout).With().Timestamp().Logger() + Logger = zerolog.New(os.Stdout).With().Timestamp().Logger() } - return logger + return Logger } diff --git a/models/models.go b/models/models.go new file mode 100644 index 0000000..069e00d --- /dev/null +++ b/models/models.go @@ -0,0 +1,29 @@ +package models + +import ( + oclib "oc-lib" + r "oc-lib/models/resources" + d "oc-lib/models/resources/data" + dc "oc-lib/models/resources/datacenter" + p "oc-lib/models/resources/processing" + s "oc-lib/models/resources/storage" + "oc-lib/models/utils" + w "oc-lib/models/workflow" +) + +var models = map[string]utils.DBObject{ + w.WORKFLOW: &w.Workflow{}, + r.ToString(r.DATA): &d.Data{}, + r.ToString(r.DATACENTER): &dc.Datacenter{}, + r.ToString(r.STORAGE): &s.Storage{}, + r.ToString(r.PROCESSING): &p.Processing{}, +} + +func Model(model string) utils.DBObject { + log := oclib.CreateLogger("oclib", "") + if _, ok := models[model]; ok { + return models[model] + } + log.Error().Msg("Can't find model " + model + ".") + return nil +} diff --git a/models/resources/data/data.go b/models/resources/data/data.go new file mode 100644 index 0000000..53fe9ca --- /dev/null +++ b/models/resources/data/data.go @@ -0,0 +1,29 @@ +package data + +import ( + resources "oc-lib/models/resources" + "oc-lib/models/utils" +) + +type Data struct { + resources.AbstractResource + Protocols []string `json:"protocol,omitempty" bson:"protocol,omitempty"` //TODO Enum type + DataType string `json:"datatype" required:"true" bson:"datatype"` + Example string `json:"example" bson:"example" required:"true" validate:"required" description:"base64 encoded data"` +} + +func (d *Data) GetType() resources.ResourceType { + return resources.DATA +} + +func (d *Data) GetAccessor(driver utils.Driver) utils.Accessor { + var data utils.Accessor + switch driver { + case utils.MONGO: + data = &DataMongoAccessor{} + default: + data = &DataMongoAccessor{} + } + data.SetLogger() + return data +} diff --git a/models/resources/data/data_mongo_accessor.go b/models/resources/data/data_mongo_accessor.go new file mode 100644 index 0000000..b886e05 --- /dev/null +++ b/models/resources/data/data_mongo_accessor.go @@ -0,0 +1,39 @@ +package data + +import ( + mongo "oc-lib/dbs/mongo" + "oc-lib/models/utils" +) + +type DataMongoAccessor struct { + utils.AbstractAccessor +} + +func (dma *DataMongoAccessor) DeleteOne(id string) utils.DBObject { + return dma.GenericDeleteOne(id, dma) +} + +func (dma *DataMongoAccessor) UpdateOne(set map[string]interface{}, id string) utils.DBObject { + return dma.GenericUpdateOne(set, id, dma) +} + +func (dma *DataMongoAccessor) StoreOne(data utils.DBObject) utils.DBObject { + id, err := mongo.StoreOne(data.(*Data), "data") + if err != nil { + dma.Logger.Error().Msg("Could not store " + data.GetName() + " to db. Error: " + err.Error()) + return &Data{} + } + return dma.LoadOne(id) +} + +func (dma *DataMongoAccessor) LoadOne(id string) utils.DBObject { + var data Data + res_mongo, err := mongo.LoadOne(id, "data") + if err != nil { + dma.Logger.Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error()) + return &Data{} + } + res_mongo.Decode(&data) + + return &data +} diff --git a/models/resources/data/data_test.go b/models/resources/data/data_test.go new file mode 100644 index 0000000..49aff18 --- /dev/null +++ b/models/resources/data/data_test.go @@ -0,0 +1,45 @@ +package data + +import ( + resources "oc-lib/models/resources" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestStoreOneData(t *testing.T) { + d := Data{DataType: "jpeg", Example: "123456", + AbstractResource: resources.AbstractResource{ + Uuid: "123", + Name: "testData", + Description: "Lorem Ipsum", + Logo: "azerty.com", + Owner: "toto", + OwnerLogo: "totoLogo", + SourceUrl: "azerty.fr", + }, + } + + dma := DataMongoAccessor{} + id := dma.StoreOne(&d) + + assert.NotEmpty(t, id) +} + +func TestLoadOneDate(t *testing.T) { + d := Data{DataType: "jpeg", Example: "123456", + AbstractResource: resources.AbstractResource{ + Uuid: "123", + Name: "testData", + Description: "Lorem Ipsum", + Logo: "azerty.com", + Owner: "toto", + OwnerLogo: "totoLogo", + SourceUrl: "azerty.fr", + }, + } + + dma := DataMongoAccessor{} + new_d := dma.StoreOne(&d) + assert.Equal(t, d, new_d) +} diff --git a/models/resources/datacenter/datacenter.go b/models/resources/datacenter/datacenter.go new file mode 100644 index 0000000..177cac1 --- /dev/null +++ b/models/resources/datacenter/datacenter.go @@ -0,0 +1,52 @@ +package datacenter + +import ( + resources "oc-lib/models/resources" + "oc-lib/models/utils" +) + +type Datacenter struct { + resources.AbstractResource + Owner string `bson:"owner" json:"owner" required:"true"` + BookingPrice int `bson:"booking_price" json:"booking_price" required:"true"` + + CPU DatacenterCpuModel `bson:"cpu,omitempty" json:"cpu,omitempty"` + RAM DatacenterMemoryModel `bson:"ram,omitempty" json:"ram,omitempty"` + GPU []DatacenterGpuModel `bson:"gpu,omitempty" json:"gpu,omitempty"` +} + +type DatacenterCpuModel struct { + Cores uint `bson:"cores,omitempty" json:"cores,omitempty"` //TODO: validate + Architecture string `bson:"architecture,omitempty" json:"architecture,omitempty"` //TOOD: enum + Shared bool `bson:"shared,omitempty" json:"shared,omitempty"` + MinimumMemory uint `bson:"minimum_memory,omitempty" json:"minimum_memory,omitempty"` + Platform string `bson:"platform,omitempty" json:"platform,omitempty"` +} + +type DatacenterMemoryModel struct { + Size uint `bson:"size,omitempty" json:"size,omitempty" description:"Units in MB"` + Ecc bool `bson:"ecc,omitempty" json:"ecc,omitempty"` +} + +type DatacenterGpuModel struct { + CudaCores uint `bson:"cuda_cores,omitempty" json:"cuda_cores,omitempty"` + Model string `bson:"model,omitempty" json:"model,omitempty"` + Memory uint `bson:"memory,omitempty" json:"memory,omitempty" description:"Units in MB"` + TensorCores uint `bson:"tensor_cores,omitempty" json:"tensor_cores,omitempty"` +} + +func (d *Datacenter) GetType() resources.ResourceType { + return resources.DATACENTER +} + +func (d *Datacenter) GetAccessor(driver utils.Driver) utils.Accessor { + var data utils.Accessor + switch driver { + case utils.MONGO: + data = &DatacenterMongoAccessor{} + default: + data = &DatacenterMongoAccessor{} + } + data.SetLogger() + return data +} diff --git a/models/resources/datacenter/datacenter_mongo_accessor.go b/models/resources/datacenter/datacenter_mongo_accessor.go new file mode 100644 index 0000000..bba9091 --- /dev/null +++ b/models/resources/datacenter/datacenter_mongo_accessor.go @@ -0,0 +1,43 @@ +package datacenter + +import ( + "oc-lib/dbs/mongo" + logs "oc-lib/logs" + "oc-lib/models/utils" +) + +type DatacenterMongoAccessor struct { + utils.AbstractAccessor +} + +func (dma *DatacenterMongoAccessor) DeleteOne(id string) utils.DBObject { + return dma.GenericDeleteOne(id, dma) +} + +func (dma *DatacenterMongoAccessor) UpdateOne(set map[string]interface{}, id string) utils.DBObject { + return dma.GenericUpdateOne(set, id, dma) +} + +func (dma *DatacenterMongoAccessor) StoreOne(data utils.DBObject) utils.DBObject { + id, err := mongo.StoreOne(data.(*Datacenter), "data") + if err != nil { + dma.Logger.Error().Msg("Could not store " + data.GetName() + " to db. Error: " + err.Error()) + return &Datacenter{} + } + return dma.LoadOne(id) +} + +func (dca *DatacenterMongoAccessor) LoadOne(id string) utils.DBObject { + var datacenter Datacenter + + res_mongo, err := mongo.LoadOne(id, "datacenter") + if err != nil { + l := logs.CreateLogger("oclib", "") + l.Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error()) + return &Datacenter{} + } + + res_mongo.Decode(&datacenter) + + return &datacenter +} diff --git a/models/resources/datacenter/datacenter_test.go b/models/resources/datacenter/datacenter_test.go new file mode 100644 index 0000000..be08113 --- /dev/null +++ b/models/resources/datacenter/datacenter_test.go @@ -0,0 +1,46 @@ +package datacenter + +import ( + resources "oc-lib/models/resources" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestStoreOneDatacenter(t *testing.T) { + dc := Datacenter{Owner: "toto", BookingPrice: 123, + AbstractResource: resources.AbstractResource{ + Uuid: "123", + Name: "testDatacenter", + Description: "Lorem Ipsum", + Logo: "azerty.com", + Owner: "toto", + OwnerLogo: "totoLogo", + SourceUrl: "azerty.fr", + }, + } + + dcma := DatacenterMongoAccessor{} + id := dcma.StoreOne(&dc) + + assert.NotEmpty(t, id) +} + +func TestLoadOneDatacenter(t *testing.T) { + dc := Datacenter{Owner: "toto", BookingPrice: 123, + AbstractResource: resources.AbstractResource{ + Uuid: "123", + Name: "testDatacenter", + Description: "Lorem Ipsum", + Logo: "azerty.com", + Owner: "toto", + OwnerLogo: "totoLogo", + SourceUrl: "azerty.fr", + }, + } + + dcma := DatacenterMongoAccessor{} + new_dc := dcma.StoreOne(&dc) + + assert.Equal(t, dc, new_dc) +} diff --git a/models/resources/processing/processing.go b/models/resources/processing/processing.go new file mode 100644 index 0000000..c302189 --- /dev/null +++ b/models/resources/processing/processing.go @@ -0,0 +1,46 @@ +package processing + +import ( + resources "oc-lib/models/resources" + "oc-lib/models/utils" +) + +type Processing struct { + resources.AbstractResource + Container string `bson:"container,omitempty" json:"container,omitempty"` // We could create a specific class for container, that could check if the name exists/is available + Repository string `bson:"repository,omitempty" json:"repository,omitempty"` // Indicate where to find the container image => Could add a struct handling authentication to the repo + Command string `bson:"command,omitempty" json:"command,omitempty"` + Arguments []string `bson:"arguments,omitempty" json:"arguments,omitempty"` + Environment []map[string]string `bson:"environment,omitempty" json:"environment,omitempty"` // a key/value struct is what ressembles the most a NAME=VALUE struct + + ExecutionRequirements ExecutionRequirementsModel `json:"execution_requirements,omitempty"` + + Price uint `bson:"price,omitempty" json:"price,omitempty"` + License string `bson:"license,omitempty" json:"license,omitempty"` +} + +type ExecutionRequirementsModel struct { + CPUs uint `bson:"cp_us,omitempty" json:"cp_us,omitempty"` + GPUs uint `bson:"gp_us,omitempty" json:"gp_us,omitempty"` + RAM uint `bson:"ram,omitempty" json:"ram,omitempty"` + + Parallel bool `bson:"parallel,omitempty" json:"parallel,omitempty"` + ScalingModel uint `bson:"scaling_model,omitempty" json:"scaling_model,omitempty"` + DiskIO string `bson:"disk_io,omitempty" json:"disk_io,omitempty"` +} + +func (p *Processing) GetType() resources.ResourceType { + return resources.PROCESSING +} + +func (d *Processing) GetAccessor(driver utils.Driver) utils.Accessor { + var data utils.Accessor + switch driver { + case utils.MONGO: + data = &ProcessingMongoAccessor{} + default: + data = &ProcessingMongoAccessor{} + } + data.SetLogger() + return data +} diff --git a/models/resources/processing/processing_mongo_accessor.go b/models/resources/processing/processing_mongo_accessor.go new file mode 100644 index 0000000..8d2e2a6 --- /dev/null +++ b/models/resources/processing/processing_mongo_accessor.go @@ -0,0 +1,44 @@ +package processing + +import ( + "oc-lib/dbs/mongo" + "oc-lib/logs" + "oc-lib/models/utils" +) + +type ProcessingMongoAccessor struct { + utils.AbstractAccessor +} + +func (dma *ProcessingMongoAccessor) DeleteOne(id string) utils.DBObject { + return dma.GenericDeleteOne(id, dma) +} + +func (dma *ProcessingMongoAccessor) UpdateOne(set map[string]interface{}, id string) utils.DBObject { + return dma.GenericUpdateOne(set, id, dma) +} + +func (dma *ProcessingMongoAccessor) StoreOne(data utils.DBObject) utils.DBObject { + id, err := mongo.StoreOne(data.(*Processing), "data") + if err != nil { + dma.Logger.Error().Msg("Could not store " + data.GetName() + " to db. Error: " + err.Error()) + return &Processing{} + } + return dma.LoadOne(id) +} + +func (pma *ProcessingMongoAccessor) LoadOne(id string) utils.DBObject { + + var processing Processing + + res_mongo, err := mongo.LoadOne(id, "processing") + if err != nil { + l := logs.CreateLogger("oclib", "") + l.Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error()) + return &Processing{} + } + + res_mongo.Decode(&processing) + + return &processing +} diff --git a/models/resources/processing/processing_test.go b/models/resources/processing/processing_test.go new file mode 100644 index 0000000..3969ae1 --- /dev/null +++ b/models/resources/processing/processing_test.go @@ -0,0 +1,45 @@ +package processing + +import ( + resources "oc-lib/models/resources" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestStoreOneProcessing(t *testing.T) { + p := Processing{Container: "totoCont", + AbstractResource: resources.AbstractResource{ + Uuid: "123", + Name: "testData", + Description: "Lorem Ipsum", + Logo: "azerty.com", + Owner: "toto", + OwnerLogo: "totoLogo", + SourceUrl: "azerty.fr", + }, + } + + sma := ProcessingMongoAccessor{} + id := sma.StoreOne(&p) + + assert.NotEmpty(t, id) +} + +func TestLoadOneProcessing(t *testing.T) { + p := Processing{Container: "totoCont", + AbstractResource: resources.AbstractResource{ + Uuid: "123", + Name: "testData", + Description: "Lorem Ipsum", + Logo: "azerty.com", + Owner: "toto", + OwnerLogo: "totoLogo", + SourceUrl: "azerty.fr", + }, + } + + sma := ProcessingMongoAccessor{} + new_s := sma.StoreOne(&p) + assert.Equal(t, p, new_s) +} diff --git a/models/resources/resource.go b/models/resources/resource.go new file mode 100644 index 0000000..bd29560 --- /dev/null +++ b/models/resources/resource.go @@ -0,0 +1,54 @@ +package resources + +// AbstractResource is the struct containing all of the attributes commons to all ressources + +// Resource is the interface to be implemented by all classes inheriting from Resource to have the same behavior + +//http://www.inanzzz.com/index.php/post/wqbs/a-basic-usage-of-int-and-string-enum-types-in-golang + +type ResourceType int + +const ( + INVALID ResourceType = iota + DATA + PROCESSING + STORAGE + DATACENTER + WORKFLOW +) + +var str = [...]string{ + "invalid", + "data", + "processing", + "storage", + "datacenter", + "workflow", +} + +func ToString(r ResourceType) string { + return str[r] +} + +type Resource interface { + GetType() ResourceType +} + +type AbstractResource struct { + Uuid string `json:"uuid" required:"true" bson:"uuid"` + Name string `json:"name" required:"true" bson:"name"` + ShortDescription string `json:"short_description" required:"true" bson:"short_description"` + Description string `json:"description,omitempty" bson:"description"` + Logo string `json:"logo" required:"true" bson:"logo"` + Owner string `json:"owner" required:"true" bson:"owner"` + OwnerLogo string `json:"owner_logo" required:"true" bson:"owner_logo"` + SourceUrl string `json:"source_url" required:"true" bson:"source_url"` +} + +func (r *AbstractResource) GetID() string { + return r.Uuid +} + +func (r *AbstractResource) GetName() string { + return r.Name +} diff --git a/models/resources/storage/storage.go b/models/resources/storage/storage.go new file mode 100644 index 0000000..efd559c --- /dev/null +++ b/models/resources/storage/storage.go @@ -0,0 +1,39 @@ +package storage + +import ( + resources "oc-lib/models/resources" + "oc-lib/models/utils" +) + +type URL struct { + Protocol string `bson:"protocol" json:"protocol"` + Path string `bson:"path" json:"path"` +} + +type Storage struct { + resources.AbstractResource + + Capacity uint `bson:"capacity,omitempty" json:"capacity,omitempty"` + Url URL `bson:"url,omitempty" json:"url,omitempty"` // Will allow to select between several protocols + + Encryption bool `bson:"encryption,omitempty" json:"encryption,omitempty"` + Redundancy string `bson:"redundancy,omitempty" json:"redundancy,omitempty"` + Throughput string `bson:"throughput,omitempty" json:"throughput,omitempty"` + BookingPrice uint `bson:"booking_price,omitempty" json:"booking_price,omitempty"` +} + +func (s *Storage) GetType() resources.ResourceType { + return resources.STORAGE +} + +func (d *Storage) GetAccessor(driver utils.Driver) utils.Accessor { + var data utils.Accessor + switch driver { + case utils.MONGO: + data = &StorageMongoAccessor{} + default: + data = &StorageMongoAccessor{} + } + data.SetLogger() + return data +} diff --git a/models/resources/storage/storage_mongo_accessor.go b/models/resources/storage/storage_mongo_accessor.go new file mode 100644 index 0000000..fc428a7 --- /dev/null +++ b/models/resources/storage/storage_mongo_accessor.go @@ -0,0 +1,44 @@ +package storage + +import ( + "oc-lib/dbs/mongo" + "oc-lib/logs" + "oc-lib/models/utils" +) + +type StorageMongoAccessor struct { + utils.AbstractAccessor +} + +func (dma *StorageMongoAccessor) DeleteOne(id string) utils.DBObject { + return dma.GenericDeleteOne(id, dma) +} + +func (dma *StorageMongoAccessor) UpdateOne(set map[string]interface{}, id string) utils.DBObject { + return dma.GenericUpdateOne(set, id, dma) +} + +func (dma *StorageMongoAccessor) StoreOne(data utils.DBObject) utils.DBObject { + id, err := mongo.StoreOne(data.(*Storage), "data") + if err != nil { + dma.Logger.Error().Msg("Could not store " + data.GetName() + " to db. Error: " + err.Error()) + return &Storage{} + } + return dma.LoadOne(id) +} + +func (schedulema *StorageMongoAccessor) LoadOne(id string) utils.DBObject { + + var storage Storage + + res_mongo, err := mongo.LoadOne(id, "storage") + if err != nil { + l := logs.CreateLogger("oclib", "") + l.Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error()) + return &Storage{} + } + + res_mongo.Decode(&storage) + + return &storage +} diff --git a/models/resources/storage/storage_test.go b/models/resources/storage/storage_test.go new file mode 100644 index 0000000..0de739a --- /dev/null +++ b/models/resources/storage/storage_test.go @@ -0,0 +1,46 @@ +package storage + +import ( + resources "oc-lib/models/resources" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestStoreOneStorage(t *testing.T) { + s := Storage{Capacity: 123, Url: URL{Protocol: "http", Path: "azerty.fr"}, + AbstractResource: resources.AbstractResource{ + Uuid: "123", + Name: "testData", + Description: "Lorem Ipsum", + Logo: "azerty.com", + Owner: "toto", + OwnerLogo: "totoLogo", + SourceUrl: "azerty.fr", + }, + } + + sma := StorageMongoAccessor{} + id := sma.StoreOne(&s) + + assert.NotEmpty(t, id) +} + +func TestLoadOneStorage(t *testing.T) { + s := Storage{Capacity: 123, Url: URL{Protocol: "http", Path: "azerty.fr"}, + AbstractResource: resources.AbstractResource{ + Uuid: "123", + Name: "testData", + Description: "Lorem Ipsum", + Logo: "azerty.com", + Owner: "toto", + OwnerLogo: "totoLogo", + SourceUrl: "azerty.fr", + }, + } + + sma := StorageMongoAccessor{} + new_s := sma.StoreOne(&s) + + assert.Equal(t, s, new_s) +} diff --git a/models/utils/abstracts.go b/models/utils/abstracts.go new file mode 100644 index 0000000..05058ce --- /dev/null +++ b/models/utils/abstracts.go @@ -0,0 +1,32 @@ +package utils + +import ( + oclib "oc-lib" + "oc-lib/dbs/mongo" + + "github.com/rs/zerolog" +) + +type AbstractAccessor struct { + Logger zerolog.Logger +} + +func (dma *AbstractAccessor) SetLogger() { + dma.Logger = oclib.CreateLogger("oclib", "") +} +func (dma *AbstractAccessor) GenericDeleteOne(id string, accessor Accessor) DBObject { + res := accessor.LoadOne(id) + _, err := mongo.DeleteOne(id, "data") + if err != nil { + dma.Logger.Error().Msg("Could not delete " + id + " to db. Error: " + err.Error()) + } + return res +} + +func (dma *AbstractAccessor) GenericUpdateOne(set map[string]interface{}, id string, accessor Accessor) DBObject { + id, err := mongo.UpdateOne(set, id, "data") + if err != nil { + dma.Logger.Error().Msg("Could not update " + id + " to db. Error: " + err.Error()) + } + return accessor.LoadOne(id) +} diff --git a/models/utils/enums.go b/models/utils/enums.go new file mode 100644 index 0000000..be56b32 --- /dev/null +++ b/models/utils/enums.go @@ -0,0 +1,8 @@ +package utils + +type Driver int + +const ( + INVALID Driver = iota + MONGO +) diff --git a/models/utils/interfaces.go b/models/utils/interfaces.go new file mode 100644 index 0000000..de92b26 --- /dev/null +++ b/models/utils/interfaces.go @@ -0,0 +1,14 @@ +package utils + +type DBObject interface { + GetName() string + GetAccessor(driver Driver) Accessor +} + +type Accessor interface { + SetLogger() + LoadOne(id string) DBObject + DeleteOne(id string) DBObject + StoreOne(data DBObject) DBObject + UpdateOne(set map[string]interface{}, id string) DBObject +} diff --git a/models/workflow/graph/graph.go b/models/workflow/graph/graph.go new file mode 100644 index 0000000..8435cbf --- /dev/null +++ b/models/workflow/graph/graph.go @@ -0,0 +1,41 @@ +package graph + +type Graph struct { + Items map[string]GraphItem `bson:"items" json:"items" default:"{}" required:"true"` + Links []GraphLink `bson:"links" json:"links" default:"{}" required:"true"` +} + +type GraphItem struct { + ID string `bson:"ID" json:"ID" required:"true"` + Width float64 `bson:"width" json:"width" required:"true"` + Height float64 `bson:"height" json:"height" required:"true"` + Position Position `bson:"position" json:"position" required:"true"` + ResourceID string `bson:"resource_id" json:"resource_id" required:"true"` +} + +type GraphLink struct { + Source Position `bson:"source" json:"source" required:"true"` + Destination Position `bson:"destination" json:"destination" required:"true"` + Style GraphLinkStyle `bson:"style" json:"style" required:"true"` +} + +type GraphLinkStyle struct { + Color int64 `bson:"color" json:"color" required:"true"` + Stroke float64 `bson:"stroke" json:"stroke" required:"true"` + Tension float64 `bson:"tension" json:"tension"` + HeadRadius float64 `bson:"head_radius" json:"head_radius"` + DashWidth float64 `bson:"dash_width" json:"dash_width"` + DashSpace float64 `bson:"dash_space" json:"dash_space"` + EndArrow Position `bson:"end_arrow" json:"end_arrow"` + StartArrow Position `bson:"start_arrow" json:"start_arrow"` + ArrowStyle int64 `bson:"arrow_style" json:"arrow_style" required:"true"` + ArrowDirection int64 `bson:"arrow_direction" json:"arrow_direction" required:"true"` + StartArrowWidth float64 `bson:"start_arrow_style" json:"start_arrow_style"` + EndArrowWidth float64 `bson:"end_arrow_style" json:"end_arrow_style"` +} + +type Position struct { + ID string `json:"ID" required:"true"` + X float64 `json:"x" required:"true"` + Y float64 `json:"y" required:"true"` +} diff --git a/models/workflow/workflow.go b/models/workflow/workflow.go new file mode 100644 index 0000000..93a24d1 --- /dev/null +++ b/models/workflow/workflow.go @@ -0,0 +1,45 @@ +package oclib + +import ( + "oc-lib/models/resources" + "oc-lib/models/resources/data" + "oc-lib/models/resources/datacenter" + "oc-lib/models/resources/processing" + "oc-lib/models/resources/storage" + "oc-lib/models/utils" + "oc-lib/models/workflow/graph" +) + +const WORKFLOW = "workflow" + +type Workflow struct { + resources.AbstractResource + Graph graph.Graph `bson:"graph,omitempty" json:"graph,omitempty"` + Datas map[string]data.Data `bson:"datas,omitempty" json:"datas,omitempty"` + Storages map[string]storage.Storage `bson:"storages,omitempty" json:"storages,omitempty"` + Processing map[string]processing.Processing `bson:"processing,omitempty" json:"processing,omitempty"` + Datacenters map[string]datacenter.Datacenter `bson:"datacenters,omitempty" json:"datacenters,omitempty"` + Schedule WorkflowSchedule `bson:"schedule,omitempty" json:"schedule,omitempty"` +} + +func (d *Workflow) GetAccessor(driver utils.Driver) utils.Accessor { + var data utils.Accessor + switch driver { + case utils.MONGO: + data = &WorkflowMongoAccessor{} + default: + data = &WorkflowMongoAccessor{} + } + data.SetLogger() + return data +} + +func (w *Workflow) isDCLink(link graph.GraphLink) bool { + if _, exists := w.Datacenters[link.Destination.ID]; exists { + return true + } else if _, exists := w.Datacenters[link.Source.ID]; exists { + return true + } + + return false +} diff --git a/models/workflow/workflow_mongo_accessor.go b/models/workflow/workflow_mongo_accessor.go new file mode 100644 index 0000000..2b00563 --- /dev/null +++ b/models/workflow/workflow_mongo_accessor.go @@ -0,0 +1,43 @@ +package oclib + +import ( + "oc-lib/dbs/mongo" + "oc-lib/logs" + "oc-lib/models/utils" +) + +type WorkflowMongoAccessor struct { + utils.AbstractAccessor +} + +func (dma *WorkflowMongoAccessor) DeleteOne(id string) utils.DBObject { + return dma.GenericDeleteOne(id, dma) +} + +func (dma *WorkflowMongoAccessor) UpdateOne(set map[string]interface{}, id string) utils.DBObject { + return dma.GenericUpdateOne(set, id, dma) +} + +func (dma *WorkflowMongoAccessor) StoreOne(data utils.DBObject) utils.DBObject { + id, err := mongo.StoreOne(data.(*Workflow), "data") + if err != nil { + dma.Logger.Error().Msg("Could not store " + data.GetName() + " to db. Error: " + err.Error()) + return &Workflow{} + } + return dma.LoadOne(id) +} + +func (wfa *WorkflowMongoAccessor) LoadOne(id string) utils.DBObject { + var workflow Workflow + + res_mongo, err := mongo.LoadOne(id, "workflow") + if err != nil { + l := logs.CreateLogger("oclib", "") + l.Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error()) + return &Workflow{} + } + + res_mongo.Decode(&workflow) + + return &workflow +} diff --git a/workflow/workflow_schedule.go b/models/workflow/workflow_schedule.go similarity index 100% rename from workflow/workflow_schedule.go rename to models/workflow/workflow_schedule.go diff --git a/models/workflow/workflow_test.go b/models/workflow/workflow_test.go new file mode 100644 index 0000000..e23f696 --- /dev/null +++ b/models/workflow/workflow_test.go @@ -0,0 +1,43 @@ +package oclib + +import ( + "oc-lib/models/resources" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestStoreOneWorkflow(t *testing.T) { + w := Workflow{AbstractResource: resources.AbstractResource{ + Uuid: "123", + Name: "testWorkflow", + Description: "Lorem Ipsum", + Logo: "azerty.com", + Owner: "toto", + OwnerLogo: "totoLogo", + SourceUrl: "azerty.fr", + }, + } + + wma := WorkflowMongoAccessor{} + id := wma.StoreOne(&w) + + assert.NotEmpty(t, id) +} + +func TestLoadOneWorkflow(t *testing.T) { + w := Workflow{AbstractResource: resources.AbstractResource{ + Uuid: "123", + Name: "testWorkflow", + Description: "Lorem Ipsum", + Logo: "azerty.com", + Owner: "toto", + OwnerLogo: "totoLogo", + SourceUrl: "azerty.fr", + }, + } + + wma := WorkflowMongoAccessor{} + new_w := wma.StoreOne(&w) + assert.Equal(t, w, new_w) +} diff --git a/mongo.go b/mongo.go deleted file mode 100644 index 6fac258..0000000 --- a/mongo.go +++ /dev/null @@ -1,199 +0,0 @@ -package oclib - -import ( - "context" - "encoding/json" - "errors" - "os" - "time" - - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/bson/primitive" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" - - mongo_utils "oc-lib/mongo" -) - -var ( - mngoClient *mongo.Client - mngoDB *mongo.Database - MngoCtx context.Context - cancel context.CancelFunc - - existingCollections []string - - ResourceMap map[string]interface{} - -) - - - -func init() { - - // var baseConfig string - var err error - var conf map[string]string - var MongoURL string - var DBname string - - ResourceMap = make(map[string]interface{}) - ResourceMap["data"] = Data{} - - logger = CreateLogger("oclib","") - db_conf, err := os.ReadFile("tests/oclib_conf.json") - if err != nil { - logger.Fatal().Msg("Could not find configuration file") - } - json.Unmarshal(db_conf,&conf) - - if len(os.Getenv("DOCKER_ENVIRONMENT")) == 0 { - MongoURL = conf["DB_URL_LOCAL"] - } else { - MongoURL = conf["DB_URL_DOCKER"] - } - - DBname = conf["DCNAME"] + "-" + conf["DBPOINT"] - - - logger.Info().Msg("Connecting to" + MongoURL) - - MngoCtx, cancel = context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - createClient(MongoURL) - - logger.Info().Msg("Connecting mongo client to db " + DBname) - prepareDB(conf["DCNAME"],conf["DBPOINT"]) - - logger.Info().Msg("Database is READY") - -} - -func createClient(MongoURL string){ - - var err error - - // Allows us to use marshal and unmarshall with results of FindOne() and others - bsonOpts := &options.BSONOptions { - UseJSONStructTags: true, - NilSliceAsEmpty: true, - } - - clientOptions := options.Client().ApplyURI(MongoURL).SetBSONOptions(bsonOpts) - mngoClient, err = mongo.Connect(MngoCtx,clientOptions) - if err != nil { - logger.Fatal().Msg("Mongodb NewClient " + MongoURL + ":" + "err" ) - panic(err) - } - - - // Ping the primary - if mngoClient, err = mongo.Connect(MngoCtx, clientOptions); err != nil { - logger.Fatal().Msg("Mongodb connect " + MongoURL + ":" + "err" ) - panic(err) - } - - if err = mngoClient.Ping(MngoCtx, nil); err != nil { - logger.Fatal().Msg("Mongodb ping " + MongoURL + ":" + "err" ) - panic(err) - } - -} - -func prepareDB(dc_name string, db_point string) { - - var err error - DBname := dc_name + "-" + db_point - mngoDB = mngoClient.Database(DBname) - - list_collection := [...]string{"data","processing","storage","datacenter","workspace","schedule","workflow"} - - existingCollections, err = mngoDB.ListCollectionNames(MngoCtx, bson.D{}) - if err != nil { - logger.Fatal().Msg("Error contacting MongoDB\n" + err.Error()) - } - collectionMap := make(map[string]bool) - for _, name := range existingCollections { - collectionMap[name] = true - } - - // Only do the collection definition process if it doesn't already exists - // we add the collection to the collection map from mongo/mongo_utils to provide faster access to the collection - - for _, collection_name := range(list_collection){ - new_collection := mngoDB.Collection(collection_name) - if _, exists := collectionMap[collection_name]; !exists { - createCollection(collection_name, new_collection) - } else{ - mongo_utils.CollectionMap[collection_name] = new_collection - } - - } - -} - -// Creates the collection with index specified in mongo/mongo_collections -// or use the basic collection creation function -func createCollection(collection_name string, new_collection *mongo.Collection) { - - var err error - - mongo_utils.CollectionMap[collection_name] = new_collection - - _, exists := mongo_utils.IndexesMap[collection_name]; - if exists{ - if _, err = new_collection.Indexes().CreateMany(MngoCtx, mongo_utils.IndexesMap[collection_name]); err != nil { - var cmdErr mongo.CommandError - if errors.As(err, &cmdErr) && cmdErr.Code != 85 { - logger.Fatal().Msg("Error creating indexes for " + collection_name + " collection : \n" + err.Error()) - panic(err) - } else if !errors.As(err, &cmdErr) { - logger.Fatal().Msg("Unexpected error: " + err.Error()) - panic(err) - } - } - } else { - mngoDB.CreateCollection(MngoCtx, collection_name) - } - -} - -func StoreOne(obj interface{}, collection_name string) (string, error) { - targetDBCollection := mongo_utils.CollectionMap[collection_name] - - MngoCtx, cancel = context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - result, err := targetDBCollection.InsertOne(MngoCtx,obj) - if err != nil { - logger.Error().Msg("Couldn't insert resource: " + err.Error()) - return "", err - } - - return result.InsertedID.(primitive.ObjectID).Hex(), nil -} - -func LoadOne(id string, collection_name string) ( res *mongo.SingleResult , err error){ - - // new_obj := ResourceMap[collection_name] - // var doc bson.D - - filter := bson.M{"_id": getObjIDFromString(id)} - targetDBCollection := mongo_utils.CollectionMap[collection_name] - - MngoCtx, cancel = context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - res = targetDBCollection.FindOne(MngoCtx, filter) - - if res.Err() != nil { - logger.Error().Msg("Couldn't find resource " + id + ". Error : " + res.Err().Error()) - err = res.Err() - return nil, err - } - - return res, nil - -} - diff --git a/processing.go b/processing.go deleted file mode 100644 index 204d708..0000000 --- a/processing.go +++ /dev/null @@ -1,30 +0,0 @@ -package oclib - -type Processing struct { - AbstractResource `json:"resource" required:"true"` - Container string `json:"container,omitempty"` // We could create a specific class for container, that could check if the name exists/is available - Repository string `json:"repository,omitempty"` // Indicate where to find the container image => Could add a struct handling authentication to the repo - Command string `json:"command,omitempty"` - Arguments []string `json:"arguments,omitempty"` - Environment []map[string]string `json:"environment,omitempty"` // a key/value struct is what ressembles the most a NAME=VALUE struct - - ExecutionRequirements ExecutionRequirementsModel `json:"execution_requirements,omitempty"` - - Price uint `json:"price,omitempty"` - License string `json:"license,omitempty"` - -} - -type ExecutionRequirementsModel struct { - CPUs uint `json:"cp_us,omitempty"` - GPUs uint `json:"gp_us,omitempty"` - RAM uint `json:"ram,omitempty"` - - Parallel bool `json:"parallel,omitempty"` - ScalingModel uint `json:"scaling_model,omitempty"` - DiskIO string `json:"disk_io,omitempty"` -} - -func (p *Processing) GetType() ResourceType{ - return PROCESSING -} diff --git a/processing/processing.go b/processing/processing.go deleted file mode 100644 index f935aa2..0000000 --- a/processing/processing.go +++ /dev/null @@ -1,32 +0,0 @@ -package processing - -import oclib "oc-lib" - -type Processing struct { - oclib.AbstractResource `json:"resource" required:"true"` - Container string `json:"container,omitempty"` // We could create a specific class for container, that could check if the name exists/is available - Repository string `json:"repository,omitempty"` // Indicate where to find the container image => Could add a struct handling authentication to the repo - Command string `json:"command,omitempty"` - Arguments []string `json:"arguments,omitempty"` - Environment []map[string]string `json:"environment,omitempty"` // a key/value struct is what ressembles the most a NAME=VALUE struct - - ExecutionRequirements ExecutionRequirementsModel `json:"execution_requirements,omitempty"` - - Price uint `json:"price,omitempty"` - License string `json:"license,omitempty"` - -} - -type ExecutionRequirementsModel struct { - CPUs uint `json:"cp_us,omitempty"` - GPUs uint `json:"gp_us,omitempty"` - RAM uint `json:"ram,omitempty"` - - Parallel bool `json:"parallel,omitempty"` - ScalingModel uint `json:"scaling_model,omitempty"` - DiskIO string `json:"disk_io,omitempty"` -} - -func (p *Processing) GetType() oclib.ResourceType{ - return oclib.PROCESSING -} diff --git a/processing/processing_mongo_accessor.go b/processing/processing_mongo_accessor.go deleted file mode 100644 index e41d4de..0000000 --- a/processing/processing_mongo_accessor.go +++ /dev/null @@ -1,38 +0,0 @@ -package processing - -import ( - "oc-lib/logs" - "oc-lib/mongo" -) - - type ProcessingMongoAccessor struct{ - - } - - -func (pma *ProcessingMongoAccessor) StoreOne(processing Processing) string { - - id, err := mongo.StoreOne(processing,"processing") - if err != nil{ - l := logs.CreateLogger("oclib","") - l.Error().Msg("Could not store " + processing.Name + " to db. Error: " + err.Error()) - return "" - } - return id -} - -func (pma *ProcessingMongoAccessor) LoadOne(id string) Processing { - - var processing Processing - - res_mongo, err := mongo.LoadOne(id,"processing") - if err != nil{ - l := logs.CreateLogger("oclib","") - l.Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error()) - return Processing{} - } - - res_mongo.Decode(&processing) - - return processing -} \ No newline at end of file diff --git a/processing/processing_test.go b/processing/processing_test.go deleted file mode 100644 index 483fc05..0000000 --- a/processing/processing_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package processing - -import ( - oclib "oc-lib" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestStoreOneProcessing(t *testing.T){ - p := Processing{ Container: "totoCont", - AbstractResource: oclib.AbstractResource{ - Uuid: "123", - Name: "testData", - Description: "Lorem Ipsum", - Logo : "azerty.com", - Owner: "toto", - OwnerLogo: "totoLogo", - SourceUrl: "azerty.fr", - }, - } - - sma := ProcessingMongoAccessor{} - id := sma.StoreOne(p) - - assert.NotEmpty(t, id) -} - -func TestLoadOneProcessing(t *testing.T){ - p := Processing{ Container: "totoCont", - AbstractResource: oclib.AbstractResource{ - Uuid: "123", - Name: "testData", - Description: "Lorem Ipsum", - Logo : "azerty.com", - Owner: "toto", - OwnerLogo: "totoLogo", - SourceUrl: "azerty.fr", - }, - } - - - sma := ProcessingMongoAccessor{} - id := sma.StoreOne(p) - new_s := sma.LoadOne(id) - - assert.Equal(t,p, new_s) -} \ No newline at end of file diff --git a/processing_mongo_accessor.go b/processing_mongo_accessor.go deleted file mode 100644 index 12224b8..0000000 --- a/processing_mongo_accessor.go +++ /dev/null @@ -1,33 +0,0 @@ -package oclib - - type ProcessingMongoAccessor struct{ - - } - - -func (pma *ProcessingMongoAccessor) StoreOne(processing Processing) string { - - id, err := StoreOne(processing,"processing") - if err != nil{ - l := CreateLogger("oclib","") - l.Error().Msg("Could not store " + processing.Name + " to db. Error: " + err.Error()) - return "" - } - return id -} - -func (pma *ProcessingMongoAccessor) LoadOne(id string) Processing { - - var processing Processing - - res_mongo, err := LoadOne(id,"processing") - if err != nil{ - l := CreateLogger("oclib","") - l.Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error()) - return Processing{} - } - - res_mongo.Decode(&processing) - - return processing -} \ No newline at end of file diff --git a/processing_test.go b/processing_test.go deleted file mode 100644 index 8fa15d9..0000000 --- a/processing_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package oclib - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestStoreOneProcessing(t *testing.T){ - p := Processing{ Container: "totoCont", - AbstractResource: AbstractResource{ - Uuid: "123", - Name: "testData", - Description: "Lorem Ipsum", - Logo : "azerty.com", - Owner: "toto", - OwnerLogo: "totoLogo", - SourceUrl: "azerty.fr", - }, - } - - sma := ProcessingMongoAccessor{} - id := sma.StoreOne(p) - - assert.NotEmpty(t, id) -} - -func TestLoadOneProcessing(t *testing.T){ - p := Processing{ Container: "totoCont", - AbstractResource: AbstractResource{ - Uuid: "123", - Name: "testData", - Description: "Lorem Ipsum", - Logo : "azerty.com", - Owner: "toto", - OwnerLogo: "totoLogo", - SourceUrl: "azerty.fr", - }, - } - - - sma := ProcessingMongoAccessor{} - id := sma.StoreOne(p) - new_s := sma.LoadOne(id) - - assert.Equal(t,p, new_s) -} \ No newline at end of file diff --git a/resource.go b/resource.go deleted file mode 100644 index 8afc799..0000000 --- a/resource.go +++ /dev/null @@ -1,96 +0,0 @@ -package oclib - -import ( - "go.mongodb.org/mongo-driver/bson/primitive" -) - -// AbstractResource is the struct containing all of the attributes commons to all ressources - -// Resource is the interface to be implemented by all classes inheriting from Resource to have the same behavior - -//http://www.inanzzz.com/index.php/post/wqbs/a-basic-usage-of-int-and-string-enum-types-in-golang - -type ResourceType int - -const ( - INVALID ResourceType = iota - DATA - PROCESSING - STORAGE - DATACENTER - WORKFLOW -) - -var extensions = [...]string{ - "INVALID", - "DATA", - "PROCESSING", - "STORAGE", - "DATACENTER", - "WORKFLOW", -} - - -type Resource interface{ - GetType() ResourceType - getOneResourceByID() Resource - StoreOne() Resource -} - -type AbstractResource struct { - Uuid string `json:"uuid" required:"true" bson:"uuid"` - Name string `json:"name" required:"true" bson:"name"` - ShortDescription string `json:"short_description" required:"true" bson:"short_description"` - Description string `json:"description,omitempty" bson:"description"` - Logo string `json:"logo" required:"true" bson:"logo"` - Owner string `json:"owner" required:"true" bson:"owner"` - OwnerLogo string `json:"owner_logo" required:"true" bson:"owner_logo"` - SourceUrl string `json:"source_url" required:"true" bson:"source_url"` - - Graphic GraphicElement `json:"graphic,omitempty" bson:"protocol"` -} - - -// func (r *AbstractResource) getOneResourceByID(id string, resType ResourceType){ - - -// targetDBCollection := r.GetType().MongoCollection() // Change the rType by the result of reflect -// var retObj interface{} - - - -// filter := bson.M{"_id": getObjIDFromString(id)} - -// res := targetDBCollection.FindOne(services.MngoCtx, filter) -// res.Decode(retObj) - -// if res.Err() != nil { -// logs.Warn("Couldn't find resource: " + res.Err().Error()) -// } - -// return retObj, res.Err() -// } - -func getObjIDFromString(id string) interface{} { - objectID, err := primitive.ObjectIDFromHex(id) - if err == nil { - return objectID - } - - return id -} - -func postToMongo(id string) { - -} - -func (r *AbstractResource) isLinked(){ - // Get the link collection in this workflow - // test if the current resource is a dest OR a source at least one - // (len(slice[r.ID == dest]) > 0 || len(slice[r.ID == 1]) > 1 ) -} - -// func (r *Resource) GetType() ResourceType { -// return INVALID -// } - diff --git a/resource_set.go b/resource_set.go deleted file mode 100644 index 12c28c0..0000000 --- a/resource_set.go +++ /dev/null @@ -1,6 +0,0 @@ -package oclib - -// Resources' key must be the Resource' Uuid, to garanty the set-like structure -type WorkflowSet struct{ - Resources map[string]Resource -} \ No newline at end of file diff --git a/storage.go b/storage.go deleted file mode 100644 index 5eb4d04..0000000 --- a/storage.go +++ /dev/null @@ -1,22 +0,0 @@ -package oclib - -type URL struct { - Protocol string `json:"protocol"` - Path string `json:"path"` -} - -type Storage struct { - AbstractResource `json:"resource" required:"true" bson:"resource"` - - Capacity uint `json:"capacity,omitempty"` - Url URL `json:"url,omitempty"` // Will allow to select between several protocols - - Encryption bool `json:"encryption,omitempty"` - Redundancy string `json:"redundancy,omitempty"` - Throughput string `json:"throughput,omitempty"` - BookingPrice uint `json:"booking_price,omitempty"` -} - -func (s *Storage) GetType() ResourceType { - return STORAGE -} diff --git a/storage/storage.go b/storage/storage.go deleted file mode 100644 index c06a8c7..0000000 --- a/storage/storage.go +++ /dev/null @@ -1,24 +0,0 @@ -package storage - -import oclib "oc-lib" - -type URL struct { - Protocol string `json:"protocol"` - Path string `json:"path"` -} - -type Storage struct { - oclib.AbstractResource `json:"resource" required:"true" bson:"resource"` - - Capacity uint `json:"capacity,omitempty"` - Url URL `json:"url,omitempty"` // Will allow to select between several protocols - - Encryption bool `json:"encryption,omitempty"` - Redundancy string `json:"redundancy,omitempty"` - Throughput string `json:"throughput,omitempty"` - BookingPrice uint `json:"booking_price,omitempty"` -} - -func (s *Storage) GetType() oclib.ResourceType { - return oclib.STORAGE -} diff --git a/storage/storage_mongo_accessor.go b/storage/storage_mongo_accessor.go deleted file mode 100644 index adf954f..0000000 --- a/storage/storage_mongo_accessor.go +++ /dev/null @@ -1,38 +0,0 @@ -package storage - -import ( - "oc-lib/logs" - "oc-lib/mongo" -) - - type StorageMongoAccessor struct{ - - } - - -func (schedulema *StorageMongoAccessor) StoreOne(storage Storage) string { - - id, err := mongo.StoreOne(storage,"storage") - if err != nil{ - l := logs.CreateLogger("oclib","") - l.Error().Msg("Could not store " + storage.Name + " to db. Error: " + err.Error()) - return "" - } - return id -} - -func (schedulema *StorageMongoAccessor) LoadOne(id string) Storage { - - var storage Storage - - res_mongo, err := mongo.LoadOne(id,"storage") - if err != nil{ - l := logs.CreateLogger("oclib","") - l.Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error()) - return Storage{} - } - - res_mongo.Decode(&storage) - - return storage -} \ No newline at end of file diff --git a/storage/storage_test.go b/storage/storage_test.go deleted file mode 100644 index 1429dce..0000000 --- a/storage/storage_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package storage - -import ( - oclib "oc-lib" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestStoreOneStorage(t *testing.T){ - s := Storage{ Capacity: 123, Url: URL{Protocol: "http",Path: "azerty.fr"} , - AbstractResource: oclib.AbstractResource{ - Uuid: "123", - Name: "testData", - Description: "Lorem Ipsum", - Logo : "azerty.com", - Owner: "toto", - OwnerLogo: "totoLogo", - SourceUrl: "azerty.fr", - }, - } - - sma := StorageMongoAccessor{} - id := sma.StoreOne(s) - - assert.NotEmpty(t, id) -} - -func TestLoadOneStorage(t *testing.T){ - s := Storage{ Capacity: 123, Url: URL{Protocol: "http",Path: "azerty.fr"} , - AbstractResource: oclib.AbstractResource{ - Uuid: "123", - Name: "testData", - Description: "Lorem Ipsum", - Logo : "azerty.com", - Owner: "toto", - OwnerLogo: "totoLogo", - SourceUrl: "azerty.fr", - }, - } - - - sma := StorageMongoAccessor{} - id := sma.StoreOne(s) - new_s := sma.LoadOne(id) - - assert.Equal(t,s, new_s) -} \ No newline at end of file diff --git a/storage_mongo_accessor.go b/storage_mongo_accessor.go deleted file mode 100644 index 5207897..0000000 --- a/storage_mongo_accessor.go +++ /dev/null @@ -1,33 +0,0 @@ -package oclib - - type StorageMongoAccessor struct{ - - } - - -func (schedulema *StorageMongoAccessor) StoreOne(storage Storage) string { - - id, err := StoreOne(storage,"storage") - if err != nil{ - l := CreateLogger("oclib","") - l.Error().Msg("Could not store " + storage.Name + " to db. Error: " + err.Error()) - return "" - } - return id -} - -func (schedulema *StorageMongoAccessor) LoadOne(id string) Storage { - - var storage Storage - - res_mongo, err := LoadOne(id,"storage") - if err != nil{ - l := CreateLogger("oclib","") - l.Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error()) - return Storage{} - } - - res_mongo.Decode(&storage) - - return storage -} \ No newline at end of file diff --git a/storage_test.go b/storage_test.go deleted file mode 100644 index a784ed9..0000000 --- a/storage_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package oclib - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestStoreOneStorage(t *testing.T){ - s := Storage{ Capacity: 123, Url: URL{Protocol: "http",Path: "azerty.fr"} , - AbstractResource: AbstractResource{ - Uuid: "123", - Name: "testData", - Description: "Lorem Ipsum", - Logo : "azerty.com", - Owner: "toto", - OwnerLogo: "totoLogo", - SourceUrl: "azerty.fr", - }, - } - - sma := StorageMongoAccessor{} - id := sma.StoreOne(s) - - assert.NotEmpty(t, id) -} - -func TestLoadOneStorage(t *testing.T){ - s := Storage{ Capacity: 123, Url: URL{Protocol: "http",Path: "azerty.fr"} , - AbstractResource: AbstractResource{ - Uuid: "123", - Name: "testData", - Description: "Lorem Ipsum", - Logo : "azerty.com", - Owner: "toto", - OwnerLogo: "totoLogo", - SourceUrl: "azerty.fr", - }, - } - - - sma := StorageMongoAccessor{} - id := sma.StoreOne(s) - new_s := sma.LoadOne(id) - - assert.Equal(t,s, new_s) -} \ No newline at end of file diff --git a/user_workflows.go b/user_workflows.go deleted file mode 100644 index 692632c..0000000 --- a/user_workflows.go +++ /dev/null @@ -1 +0,0 @@ -package oclib diff --git a/workflow.go b/workflow.go deleted file mode 100644 index cb6c640..0000000 --- a/workflow.go +++ /dev/null @@ -1,25 +0,0 @@ -package oclib - -type Workflow struct { - AbstractResource `json:"abstract_resource" required:"true"` - Datas map[string]Data `json:"datas,omitempty"` - Storages map[string]Storage `json:"storages,omitempty"` - Processing map[string]Processing `json:"processing,omitempty"` - Datacenters map[string]Datacenter `json:"datacenters,omitempty"` - Links map[string]Link `json:"links,omitempty"` - - Schedule WorkflowSchedule `json:"schedule,omitempty"` -} - -func (w *Workflow) isDCLink(link Link) bool { - if _, exists := w.Datacenters[link.Destination]; exists { - return true - } else if _, exists := w.Datacenters[link.Source]; exists { - return true - } - - return false -} - - - diff --git a/workflow/workflow.go b/workflow/workflow.go deleted file mode 100644 index 3002156..0000000 --- a/workflow/workflow.go +++ /dev/null @@ -1,34 +0,0 @@ -package oclib - -import ( - oclib "oc-lib" - "oc-lib/data" - "oc-lib/datacenter" - "oc-lib/link" - "oc-lib/processing" - "oc-lib/storage" -) - -type Workflow struct { - oclib.AbstractResource `json:"abstract_resource" required:"true"` - Datas map[string]data.Data `json:"datas,omitempty"` - Storages map[string]storage.Storage `json:"storages,omitempty"` - Processing map[string]processing.Processing `json:"processing,omitempty"` - Datacenters map[string]datacenter.Datacenter `json:"datacenters,omitempty"` - Links map[string]link.Link `json:"links,omitempty"` - - Schedule WorkflowSchedule `json:"schedule,omitempty"` -} - -func (w *Workflow) isDCLink(link link.Link) bool { - if _, exists := w.Datacenters[link.Destination]; exists { - return true - } else if _, exists := w.Datacenters[link.Source]; exists { - return true - } - - return false -} - - - diff --git a/workflow/workflow_mongo_accessor.go b/workflow/workflow_mongo_accessor.go deleted file mode 100644 index 13a284b..0000000 --- a/workflow/workflow_mongo_accessor.go +++ /dev/null @@ -1,34 +0,0 @@ -package oclib - -import ( - "oc-lib/logs" - "oc-lib/mongo" -) - - -type WorkflowMongoAccessor struct{} - -func (wfa *WorkflowMongoAccessor) StoreOne(workflow Workflow) string { - id, err := mongo.StoreOne(workflow, "workflow") - if err != nil { - l := logs.CreateLogger("oclib", "") - l.Error().Msg("Could not store " + workflow.Name + " to db. Error: " + err.Error()) - return "" - } - return id -} - -func (wfa *WorkflowMongoAccessor) LoadOne(id string) Workflow { - var workflow Workflow - - res_mongo, err := mongo.LoadOne(id, "workflow") - if err != nil { - l := logs.CreateLogger("oclib", "") - l.Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error()) - return Workflow{} - } - - res_mongo.Decode(&workflow) - - return workflow -} \ No newline at end of file diff --git a/workflow/workflow_test.go b/workflow/workflow_test.go deleted file mode 100644 index 90d16cd..0000000 --- a/workflow/workflow_test.go +++ /dev/null @@ -1,45 +0,0 @@ -package oclib - -import ( - oclib "oc-lib" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestStoreOneWorkflow(t *testing.T){ - w := Workflow{AbstractResource: oclib.AbstractResource{ - Uuid: "123", - Name: "testWorkflow", - Description: "Lorem Ipsum", - Logo : "azerty.com", - Owner: "toto", - OwnerLogo: "totoLogo", - SourceUrl: "azerty.fr", - }, - } - - wma := WorkflowMongoAccessor{} - id := wma.StoreOne(w) - - assert.NotEmpty(t, id) -} - -func TestLoadOneWorkflow(t *testing.T){ - w := Workflow{AbstractResource: oclib.AbstractResource{ - Uuid: "123", - Name: "testWorkflow", - Description: "Lorem Ipsum", - Logo : "azerty.com", - Owner: "toto", - OwnerLogo: "totoLogo", - SourceUrl: "azerty.fr", - }, - } - - wma := WorkflowMongoAccessor{} - id := wma.StoreOne(w) - new_w := wma.LoadOne(id) - - assert.Equal(t,w, new_w) -} \ No newline at end of file diff --git a/workflow_mongo_accessor.go b/workflow_mongo_accessor.go deleted file mode 100644 index dae64b1..0000000 --- a/workflow_mongo_accessor.go +++ /dev/null @@ -1,29 +0,0 @@ -package oclib - - -type WorkflowMongoAccessor struct{} - -func (wfa *WorkflowMongoAccessor) StoreOne(workflow Workflow) string { - id, err := StoreOne(workflow, "workflow") - if err != nil { - l := CreateLogger("oclib", "") - l.Error().Msg("Could not store " + workflow.Name + " to db. Error: " + err.Error()) - return "" - } - return id -} - -func (wfa *WorkflowMongoAccessor) LoadOne(id string) Workflow { - var workflow Workflow - - res_mongo, err := LoadOne(id, "workflow") - if err != nil { - l := CreateLogger("oclib", "") - l.Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error()) - return Workflow{} - } - - res_mongo.Decode(&workflow) - - return workflow -} \ No newline at end of file diff --git a/workflow_schedule.go b/workflow_schedule.go deleted file mode 100644 index 7d5d5a1..0000000 --- a/workflow_schedule.go +++ /dev/null @@ -1,15 +0,0 @@ -package oclib - -import "time" - -type WorkflowSchedule struct { - Id string `json:"id"` - Start time.Time - End time.Time - Cron string -} - -func (ws *WorkflowSchedule) GetAllDates() (timetable []time.Time){ - // Return all the execution time generated by the Cron - return -} \ No newline at end of file diff --git a/workflow_test.go b/workflow_test.go deleted file mode 100644 index 8c5e93a..0000000 --- a/workflow_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package oclib - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestStoreOneWorkflow(t *testing.T){ - w := Workflow{AbstractResource: AbstractResource{ - Uuid: "123", - Name: "testWorkflow", - Description: "Lorem Ipsum", - Logo : "azerty.com", - Owner: "toto", - OwnerLogo: "totoLogo", - SourceUrl: "azerty.fr", - }, - } - - wma := WorkflowMongoAccessor{} - id := wma.StoreOne(w) - - assert.NotEmpty(t, id) -} - -func TestLoadOneWorkflow(t *testing.T){ - w := Workflow{AbstractResource: AbstractResource{ - Uuid: "123", - Name: "testWorkflow", - Description: "Lorem Ipsum", - Logo : "azerty.com", - Owner: "toto", - OwnerLogo: "totoLogo", - SourceUrl: "azerty.fr", - }, - } - - wma := WorkflowMongoAccessor{} - id := wma.StoreOne(w) - new_w := wma.LoadOne(id) - - assert.Equal(t,w, new_w) -} \ No newline at end of file