lightest + clearest code

This commit is contained in:
mr
2024-11-28 16:49:41 +01:00
parent 8a11805fe8
commit 8d701e67d8
34 changed files with 444 additions and 1448 deletions

View File

@@ -1,4 +1,4 @@
package compute
package resources
import (
"cloud.o-forge.io/core/oc-lib/models/resources/resource_model"
@@ -6,6 +6,48 @@ import (
"cloud.o-forge.io/core/oc-lib/tools"
)
/*
* ComputeResource is a struct that represents a compute resource
* it defines the resource compute
*/
type ComputeResource struct {
resource_model.AbstractResource
Technology TechnologyEnum `json:"technology" bson:"technology" default:"0"` // Technology is the technology
Architecture string `json:"architecture,omitempty" bson:"architecture,omitempty"` // Architecture is the architecture
Access AccessEnum `json:"access" bson:"access" default:"0"` // Access is the access
Localisation string `json:"localisation,omitempty" bson:"localisation,omitempty"` // Localisation is the localisation
CPUs []*CPU `bson:"cpus,omitempty" json:"cpus,omitempty"` // CPUs is the list of CPUs
RAM *RAM `bson:"ram,omitempty" json:"ram,omitempty"` // RAM is the RAM
GPUs []*GPU `bson:"gpus,omitempty" json:"gpus,omitempty"` // GPUs is the list of GPUs
}
func (d *ComputeResource) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
return New[*ComputeResource](tools.COMPUTE_RESOURCE, peerID, groups, caller, func() utils.DBObject { return &ComputeResource{} })
}
// CPU is a struct that represents a CPU
type CPU 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 RAM struct {
Size uint `bson:"size,omitempty" json:"size,omitempty" description:"Units in MB"`
Ecc bool `bson:"ecc,omitempty" json:"ecc,omitempty"`
}
type GPU 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"`
}
type TechnologyEnum int
const (
@@ -34,45 +76,3 @@ const (
func (a AccessEnum) String() string {
return [...]string{"SSH", "SSH_KUBE_API", "SSH_SLURM", "SSH_DOCKER", "OPENCLOUD", "VPN"}[a]
}
/*
* ComputeResource is a struct that represents a compute resource
* it defines the resource compute
*/
type ComputeResource struct {
resource_model.AbstractResource
Technology TechnologyEnum `json:"technology" bson:"technology" default:"0"` // Technology is the technology
Architecture string `json:"architecture,omitempty" bson:"architecture,omitempty"` // Architecture is the architecture
Access AccessEnum `json:"access" bson:"access default:"0"` // Access is the access
Localisation string `json:"localisation,omitempty" bson:"localisation,omitempty"` // Localisation is the localisation
CPUs []*CPU `bson:"cpus,omitempty" json:"cpus,omitempty"` // CPUs is the list of CPUs
RAM *RAM `bson:"ram,omitempty" json:"ram,omitempty"` // RAM is the RAM
GPUs []*GPU `bson:"gpus,omitempty" json:"gpus,omitempty"` // GPUs is the list of GPUs
}
func (d *ComputeResource) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
return New(tools.COMPUTE_RESOURCE, peerID, groups, caller)
}
// CPU is a struct that represents a CPU
type CPU 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 RAM struct {
Size uint `bson:"size,omitempty" json:"size,omitempty" description:"Units in MB"`
Ecc bool `bson:"ecc,omitempty" json:"ecc,omitempty"`
}
type GPU 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"`
}

View File

@@ -1,81 +0,0 @@
package compute
import (
"cloud.o-forge.io/core/oc-lib/dbs"
"cloud.o-forge.io/core/oc-lib/logs"
"cloud.o-forge.io/core/oc-lib/models/resources/resource_model"
"cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
)
type computeMongoAccessor struct {
utils.AbstractAccessor // AbstractAccessor contains the basic fields of an accessor (model, caller)
}
// New creates a new instance of the computeMongoAccessor
func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCaller) *computeMongoAccessor {
return &computeMongoAccessor{
utils.AbstractAccessor{
ResourceModelAccessor: resource_model.New(),
Logger: logs.CreateLogger(t.String()), // Create a logger with the data type
Caller: caller,
PeerID: peerID,
Groups: groups, // Set the caller
Type: t.String(),
},
}
}
/*
* Nothing special here, just the basic CRUD operations
*/
func (dca *computeMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) {
return dca.GenericDeleteOne(id, dca)
}
func (dca *computeMongoAccessor) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) {
set.(*ComputeResource).ResourceModel = nil
return dca.GenericUpdateOne(set.(*ComputeResource).Trim(), id, dca, &ComputeResource{})
}
func (dca *computeMongoAccessor) StoreOne(data utils.DBObject) (utils.DBObject, int, error) {
data.(*ComputeResource).ResourceModel = nil
return dca.GenericStoreOne(data.(*ComputeResource).Trim(), dca)
}
func (dca *computeMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObject, int, error) {
return dca.StoreOne(data)
}
func (dca *computeMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) {
return utils.GenericLoadOne[*ComputeResource](id, func(d utils.DBObject) (utils.DBObject, int, error) {
resources, _, err := dca.ResourceModelAccessor.Search(nil, dca.GetType())
if err == nil && len(resources) > 0 {
d.(*ComputeResource).ResourceModel = resources[0].(*resource_model.ResourceModel)
}
return d, 200, nil
}, dca)
}
func (wfa *computeMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, error) {
resources, _, err := wfa.ResourceModelAccessor.Search(nil, wfa.GetType())
return utils.GenericLoadAll[*ComputeResource](func(d utils.DBObject) utils.ShallowDBObject {
if err == nil && len(resources) > 0 {
d.(*ComputeResource).ResourceModel = resources[0].(*resource_model.ResourceModel)
}
return d
}, wfa)
}
func (wfa *computeMongoAccessor) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) {
root := &ComputeResource{}
resources, _, err := wfa.ResourceModelAccessor.Search(nil, wfa.GetType())
return utils.GenericSearch[*ComputeResource](filters, search, root.GetResourceFilter(search),
func(d utils.DBObject) utils.ShallowDBObject {
if err == nil && len(resources) > 0 {
d.(*ComputeResource).ResourceModel = resources[0].(*resource_model.ResourceModel)
}
return d
}, wfa)
}

View File

@@ -1,47 +0,0 @@
package compute
import (
"testing"
"cloud.o-forge.io/core/oc-lib/models/resources/resource_model"
"cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
"github.com/stretchr/testify/assert"
)
func TestStoreOneCompute(t *testing.T) {
dc := ComputeResource{
AbstractResource: resource_model.AbstractResource{
AbstractObject: utils.AbstractObject{Name: "testCompute"},
Description: "Lorem Ipsum",
Logo: "azerty.com",
Owner: "toto",
OwnerLogo: "totoLogo",
SourceUrl: "azerty.fr",
},
}
dcma := New(tools.COMPUTE_RESOURCE, "", nil, nil)
id, _, _ := dcma.StoreOne(&dc)
assert.NotEmpty(t, id)
}
func TestLoadOneCompute(t *testing.T) {
dc := ComputeResource{
AbstractResource: resource_model.AbstractResource{
AbstractObject: utils.AbstractObject{Name: "testCompute"},
Description: "Lorem Ipsum",
Logo: "azerty.com",
Owner: "toto",
OwnerLogo: "totoLogo",
SourceUrl: "azerty.fr",
},
}
dcma := New(tools.COMPUTE_RESOURCE, "", nil, nil)
new_dc, _, _ := dcma.StoreOne(&dc)
assert.Equal(t, dc, new_dc)
}

View File

@@ -1,4 +1,4 @@
package data
package resources
import (
"cloud.o-forge.io/core/oc-lib/models/resources/resource_model"
@@ -38,5 +38,5 @@ type DataResource struct {
}
func (d *DataResource) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
return New(tools.DATA_RESOURCE, peerID, groups, caller) // Create a new instance of the accessor
return New[*DataResource](tools.DATA_RESOURCE, peerID, groups, caller, func() utils.DBObject { return &DataResource{} }) // Create a new instance of the accessor
}

View File

@@ -1,129 +0,0 @@
package data
import (
"errors"
"cloud.o-forge.io/core/oc-lib/dbs"
mongo "cloud.o-forge.io/core/oc-lib/dbs/mongo"
"cloud.o-forge.io/core/oc-lib/logs"
"cloud.o-forge.io/core/oc-lib/models/resources/resource_model"
"cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
)
type dataMongoAccessor struct {
utils.AbstractAccessor // AbstractAccessor contains the basic fields of an accessor (model, caller)
}
// New creates a new instance of the dataMongoAccessor
func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCaller) *dataMongoAccessor {
return &dataMongoAccessor{
utils.AbstractAccessor{
ResourceModelAccessor: resource_model.New(),
Logger: logs.CreateLogger(t.String()), // Create a logger with the data type
Caller: caller,
PeerID: peerID,
Groups: groups, // Set the caller
Type: t.String(),
},
}
}
/*
* Nothing special here, just the basic CRUD operations
*/
func (dma *dataMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) {
return dma.GenericDeleteOne(id, dma)
}
func (dma *dataMongoAccessor) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) {
set.(*DataResource).ResourceModel = nil
return dma.GenericUpdateOne(set.(*DataResource).Trim(), id, dma, &DataResource{})
}
func (dma *dataMongoAccessor) StoreOne(data utils.DBObject) (utils.DBObject, int, error) {
data.(*DataResource).ResourceModel = nil
return dma.GenericStoreOne(data.(*DataResource).Trim(), dma)
}
func (dma *dataMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObject, int, error) {
return dma.StoreOne(data)
}
func (dma *dataMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) {
var data DataResource
res_mongo, code, err := mongo.MONGOService.LoadOne(id, dma.GetType())
if err != nil {
dma.Logger.Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error())
return nil, code, err
}
res_mongo.Decode(&data)
if !data.VerifyAuth(dma.PeerID, dma.Groups) {
return nil, 403, errors.New("You are not allowed to access this collaborative area")
}
resources, _, err := dma.ResourceModelAccessor.Search(nil, dma.GetType())
if err == nil && len(resources) > 0 {
data.ResourceModel = resources[0].(*resource_model.ResourceModel)
}
return &data, 200, nil
}
func (wfa dataMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, error) {
objs := []utils.ShallowDBObject{}
res_mongo, code, err := mongo.MONGOService.LoadAll(wfa.GetType())
if err != nil {
wfa.Logger.Error().Msg("Could not retrieve any from db. Error: " + err.Error())
return nil, code, err
}
var results []DataResource
if err = res_mongo.All(mongo.MngoCtx, &results); err != nil {
return nil, 404, err
}
resources, _, err := wfa.ResourceModelAccessor.Search(nil, wfa.GetType())
for _, r := range results {
if !r.VerifyAuth(wfa.PeerID, wfa.Groups) {
continue
}
if err == nil && len(resources) > 0 {
r.ResourceModel = resources[0].(*resource_model.ResourceModel)
}
objs = append(objs, &r) // only get the abstract resource !
}
return objs, 200, nil
}
func (wfa *dataMongoAccessor) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) {
objs := []utils.ShallowDBObject{}
if (filters == nil || len(filters.And) == 0 || len(filters.Or) == 0) && search != "" {
filters = &dbs.Filters{
Or: map[string][]dbs.Filter{ // filter by like name, short_description, description, owner, url if no filters are provided
"abstractresource.abstractobject.name": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.short_description": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.description": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.owner": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.source_url": {{Operator: dbs.LIKE.String(), Value: search}},
},
}
}
res_mongo, code, err := mongo.MONGOService.Search(filters, wfa.GetType())
if err != nil {
wfa.Logger.Error().Msg("Could not store to db. Error: " + err.Error())
return nil, code, err
}
var results []DataResource
if err = res_mongo.All(mongo.MngoCtx, &results); err != nil {
return nil, 404, err
}
resources, _, err := wfa.ResourceModelAccessor.Search(nil, wfa.GetType())
for _, r := range results {
if !r.VerifyAuth(wfa.PeerID, wfa.Groups) {
continue
}
if err == nil && len(resources) > 0 {
r.ResourceModel = resources[0].(*resource_model.ResourceModel)
}
objs = append(objs, &r) // only get the abstract resource !
}
return objs, 200, nil
}

View File

@@ -1,54 +0,0 @@
package data
import (
"testing"
"cloud.o-forge.io/core/oc-lib/models/resources/resource_model"
"cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
"github.com/stretchr/testify/assert"
)
func TestStoreOneData(t *testing.T) {
d := DataResource{
WebResource: resource_model.WebResource{
Protocol: "http", Path: "azerty.fr",
},
Example: "123456",
AbstractResource: resource_model.AbstractResource{
AbstractObject: utils.AbstractObject{Name: "testData"},
Description: "Lorem Ipsum",
Logo: "azerty.com",
Owner: "toto",
OwnerLogo: "totoLogo",
SourceUrl: "azerty.fr",
},
}
dma := New(tools.DATA_RESOURCE, "", nil, nil)
id, _, _ := dma.StoreOne(&d)
assert.NotEmpty(t, id)
}
func TestLoadOneDate(t *testing.T) {
d := DataResource{
WebResource: resource_model.WebResource{
Protocol: "http", Path: "azerty.fr",
},
Example: "123456",
AbstractResource: resource_model.AbstractResource{
AbstractObject: utils.AbstractObject{Name: "testData"},
Description: "Lorem Ipsum",
Logo: "azerty.com",
Owner: "toto",
OwnerLogo: "totoLogo",
SourceUrl: "azerty.fr",
},
}
dma := New(tools.DATA_RESOURCE, "", nil, nil)
new_d, _, _ := dma.StoreOne(&d)
assert.Equal(t, d, new_d)
}

View File

@@ -0,0 +1,43 @@
package resources
import (
"cloud.o-forge.io/core/oc-lib/models/resources/resource_model"
"cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
)
type Container struct {
Image string `json:"image,omitempty" bson:"image,omitempty"` // Image is the container image
Command string `json:"command,omitempty" bson:"command,omitempty"` // Command is the container command
Args string `json:"args,omitempty" bson:"args,omitempty"` // Args is the container arguments
Env map[string]string `json:"env,omitempty" bson:"env,omitempty"` // Env is the container environment variables
Volumes map[string]string `json:"volumes,omitempty" bson:"volumes,omitempty"` // Volumes is the container volumes
}
type Expose struct {
Port int `json:"port,omitempty" bson:"port,omitempty"` // Port is the port
Reverse string `json:"reverse,omitempty" bson:"reverse,omitempty"` // Reverse is the reverse
PAT int `json:"pat,omitempty" bson:"pat,omitempty"` // PAT is the PAT
}
/*
* ProcessingResource is a struct that represents a processing resource
* it defines the resource processing
*/
type ProcessingResource struct {
resource_model.AbstractResource
IsService bool `json:"is_service,omitempty" bson:"is_service,omitempty"` // IsService is a flag that indicates if the processing is a service
CPUs []*CPU `bson:"cpus,omitempty" json:"cp_us,omitempty"` // CPUs is the list of CPUs
GPUs []*GPU `bson:"gpus,omitempty" json:"gp_us,omitempty"` // GPUs is the list of GPUs
RAM *RAM `bson:"ram,omitempty" json:"ram,omitempty"` // RAM is the RAM
Storage uint `bson:"storage,omitempty" json:"storage,omitempty"` // Storage is the storage
Parallel bool `bson:"parallel,omitempty" json:"parallel,omitempty"` // Parallel is a flag that indicates if the processing is parallel
ScalingModel uint `bson:"scaling_model,omitempty" json:"scaling_model,omitempty"` // ScalingModel is the scaling model
DiskIO string `bson:"disk_io,omitempty" json:"disk_io,omitempty"` // DiskIO is the disk IO
Container *Container `bson:"container,omitempty" json:"container,omitempty"` // Container is the container
Expose []Expose `bson:"expose,omitempty" json:"expose,omitempty"` // Expose is the execution
}
func (d *ProcessingResource) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
return New[*ProcessingResource](tools.PROCESSING_RESOURCE, peerID, groups, caller, func() utils.DBObject { return &ProcessingResource{} }) // Create a new instance of the accessor
}

View File

@@ -1,44 +0,0 @@
package processing
import (
"cloud.o-forge.io/core/oc-lib/models/resources/compute"
"cloud.o-forge.io/core/oc-lib/models/resources/resource_model"
"cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
)
type Container struct {
Image string `json:"image,omitempty" bson:"image,omitempty"` // Image is the container image
Command string `json:"command,omitempty" bson:"command,omitempty"` // Command is the container command
Args string `json:"args,omitempty" bson:"args,omitempty"` // Args is the container arguments
Env map[string]string `json:"env,omitempty" bson:"env,omitempty"` // Env is the container environment variables
Volumes map[string]string `json:"volumes,omitempty" bson:"volumes,omitempty"` // Volumes is the container volumes
}
type Expose struct {
Port int `json:"port,omitempty" bson:"port,omitempty"` // Port is the port
Reverse string `json:"reverse,omitempty" bson:"reverse,omitempty"` // Reverse is the reverse
PAT int `json:"pat,omitempty" bson:"pat,omitempty"` // PAT is the PAT
}
/*
* ProcessingResource is a struct that represents a processing resource
* it defines the resource processing
*/
type ProcessingResource struct {
resource_model.AbstractResource
IsService bool `json:"is_service,omitempty" bson:"is_service,omitempty"` // IsService is a flag that indicates if the processing is a service
CPUs []*compute.CPU `bson:"cpus,omitempty" json:"cp_us,omitempty"` // CPUs is the list of CPUs
GPUs []*compute.GPU `bson:"gpus,omitempty" json:"gp_us,omitempty"` // GPUs is the list of GPUs
RAM *compute.RAM `bson:"ram,omitempty" json:"ram,omitempty"` // RAM is the RAM
Storage uint `bson:"storage,omitempty" json:"storage,omitempty"` // Storage is the storage
Parallel bool `bson:"parallel,omitempty" json:"parallel,omitempty"` // Parallel is a flag that indicates if the processing is parallel
ScalingModel uint `bson:"scaling_model,omitempty" json:"scaling_model,omitempty"` // ScalingModel is the scaling model
DiskIO string `bson:"disk_io,omitempty" json:"disk_io,omitempty"` // DiskIO is the disk IO
Container *Container `bson:"container,omitempty" json:"container,omitempty"` // Container is the container
Expose []Expose `bson:"expose,omitempty" json:"expose,omitempty"` // Expose is the execution
}
func (d *ProcessingResource) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
return New(tools.PROCESSING_RESOURCE, peerID, groups, caller) // Create a new instance of the accessor
}

View File

@@ -1,133 +0,0 @@
package processing
import (
"errors"
"cloud.o-forge.io/core/oc-lib/dbs"
"cloud.o-forge.io/core/oc-lib/dbs/mongo"
"cloud.o-forge.io/core/oc-lib/logs"
"cloud.o-forge.io/core/oc-lib/models/resources/resource_model"
"cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
)
type processingMongoAccessor struct {
utils.AbstractAccessor // AbstractAccessor contains the basic fields of an accessor (model, caller)
}
// New creates a new instance of the storageMongoAccessor
func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCaller) *processingMongoAccessor {
return &processingMongoAccessor{
utils.AbstractAccessor{
ResourceModelAccessor: resource_model.New(),
Logger: logs.CreateLogger(t.String()), // Create a logger with the data type
Caller: caller,
PeerID: peerID,
Groups: groups, // Set the caller
Type: t.String(),
},
}
}
/*
* Nothing special here, just the basic CRUD operations
*/
func (pma *processingMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) {
return pma.GenericDeleteOne(id, pma)
}
func (pma *processingMongoAccessor) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) {
set.(*ProcessingResource).ResourceModel = nil
return pma.GenericUpdateOne(set.(*ProcessingResource).Trim(), id, pma, &ProcessingResource{})
}
func (pma *processingMongoAccessor) StoreOne(data utils.DBObject) (utils.DBObject, int, error) {
data.(*ProcessingResource).ResourceModel = nil
return pma.GenericStoreOne(data.(*ProcessingResource).Trim(), pma)
}
func (pma *processingMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObject, int, error) {
return pma.StoreOne(data)
}
func (pma *processingMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) {
var processing ProcessingResource
res_mongo, code, err := mongo.MONGOService.LoadOne(id, pma.GetType())
if err != nil {
pma.Logger.Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error())
return nil, code, err
}
res_mongo.Decode(&processing)
if !processing.VerifyAuth(pma.PeerID, pma.Groups) {
return nil, 403, errors.New("You are not allowed to access this collaborative area")
}
resources, _, err := pma.ResourceModelAccessor.Search(nil, pma.GetType())
if err == nil && len(resources) > 0 {
processing.ResourceModel = resources[0].(*resource_model.ResourceModel)
}
return &processing, 200, nil
}
func (wfa processingMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, error) {
objs := []utils.ShallowDBObject{}
res_mongo, code, err := mongo.MONGOService.LoadAll(wfa.GetType())
if err != nil {
wfa.Logger.Error().Msg("Could not retrieve any from db. Error: " + err.Error())
return nil, code, err
}
var results []ProcessingResource
if err = res_mongo.All(mongo.MngoCtx, &results); err != nil {
return nil, 404, err
}
resources, _, err := wfa.ResourceModelAccessor.Search(nil, wfa.GetType())
for _, r := range results {
if !r.VerifyAuth(wfa.PeerID, wfa.Groups) {
continue
}
if err == nil && len(resources) > 0 {
r.ResourceModel = resources[0].(*resource_model.ResourceModel)
}
objs = append(objs, &r) // only get the abstract resource !
}
return objs, 200, nil
}
// Search searches for processing resources in the database, given some filters OR a search string
func (wfa *processingMongoAccessor) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) {
objs := []utils.ShallowDBObject{}
if (filters == nil || len(filters.And) == 0 || len(filters.Or) == 0) && search != "" {
filters = &dbs.Filters{
Or: map[string][]dbs.Filter{ // filter by like name, short_description, description, owner, url if no filters are provided
"abstractresource.abstractobject.name": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.short_description": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.description": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.owner": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.source_url": {{Operator: dbs.LIKE.String(), Value: search}},
},
}
}
res_mongo, code, err := mongo.MONGOService.Search(filters, wfa.GetType())
if err != nil {
wfa.Logger.Error().Msg("Could not store to db. Error: " + err.Error())
return nil, code, err
}
var results []ProcessingResource
if err = res_mongo.All(mongo.MngoCtx, &results); err != nil {
return nil, 404, err
}
resources, _, err := wfa.ResourceModelAccessor.Search(nil, wfa.GetType())
for _, r := range results {
if !r.VerifyAuth(wfa.PeerID, wfa.Groups) {
continue
}
if err == nil && len(resources) > 0 {
r.ResourceModel = resources[0].(*resource_model.ResourceModel)
}
objs = append(objs, &r) // only get the abstract resource !
}
return objs, 200, nil
}

View File

@@ -1,38 +0,0 @@
package processing
/*
func TestStoreOneProcessing(t *testing.T) {
p := ProcessingResource{Container: "totoCont",
AbstractResource: resources.AbstractResource{
AbstractObject: utils.AbstractObject{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 := ProcessingResource{Container: "totoCont",
AbstractResource: resources.AbstractResource{
AbstractObject: utils.AbstractObject{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)
}
*/

View File

@@ -1,12 +1,7 @@
package resources
import (
"cloud.o-forge.io/core/oc-lib/models/resources/compute"
"cloud.o-forge.io/core/oc-lib/models/resources/data"
"cloud.o-forge.io/core/oc-lib/models/resources/processing"
"cloud.o-forge.io/core/oc-lib/models/resources/resource_model"
"cloud.o-forge.io/core/oc-lib/models/resources/storage"
w "cloud.o-forge.io/core/oc-lib/models/resources/workflow"
"cloud.o-forge.io/core/oc-lib/models/utils"
)
@@ -15,6 +10,12 @@ import (
// 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 ResourceInterface interface {
utils.DBObject
Trim() *resource_model.AbstractResource
SetResourceModel(model *resource_model.ResourceModel)
}
type ResourceSet struct {
Datas []string `bson:"datas,omitempty" json:"datas,omitempty"`
Storages []string `bson:"storages,omitempty" json:"storages,omitempty"`
@@ -22,35 +23,43 @@ type ResourceSet struct {
Computes []string `bson:"computes,omitempty" json:"computes,omitempty"`
Workflows []string `bson:"workflows,omitempty" json:"workflows,omitempty"`
DataResources []*data.DataResource `bson:"-" json:"data_resources,omitempty"`
StorageResources []*storage.StorageResource `bson:"-" json:"storage_resources,omitempty"`
ProcessingResources []*processing.ProcessingResource `bson:"-" json:"processing_resources,omitempty"`
ComputeResources []*compute.ComputeResource `bson:"-" json:"compute_resources,omitempty"`
WorkflowResources []*w.WorkflowResource `bson:"-" json:"workflow_resources,omitempty"`
DataResources []*DataResource `bson:"-" json:"data_resources,omitempty"`
StorageResources []*StorageResource `bson:"-" json:"storage_resources,omitempty"`
ProcessingResources []*ProcessingResource `bson:"-" json:"processing_resources,omitempty"`
ComputeResources []*ComputeResource `bson:"-" json:"compute_resources,omitempty"`
WorkflowResources []*WorkflowResource `bson:"-" json:"workflow_resources,omitempty"`
}
func (r *ResourceSet) Clear() {
r.DataResources = nil
r.StorageResources = nil
r.ProcessingResources = nil
r.ComputeResources = nil
r.WorkflowResources = nil
}
func (r *ResourceSet) Fill(peerID string, groups []string) {
for k, v := range map[utils.DBObject][]string{
(&data.DataResource{}): r.Datas,
(&compute.ComputeResource{}): r.Computes,
(&storage.StorageResource{}): r.Storages,
(&processing.ProcessingResource{}): r.Processings,
(&w.WorkflowResource{}): r.Workflows,
(&DataResource{}): r.Datas,
(&ComputeResource{}): r.Computes,
(&StorageResource{}): r.Storages,
(&ProcessingResource{}): r.Processings,
(&WorkflowResource{}): r.Workflows,
} {
for _, id := range v {
d, _, e := k.GetAccessor(peerID, groups, nil).LoadOne(id)
if e == nil {
switch k.(type) {
case *data.DataResource:
r.DataResources = append(r.DataResources, d.(*data.DataResource))
case *compute.ComputeResource:
r.ComputeResources = append(r.ComputeResources, d.(*compute.ComputeResource))
case *storage.StorageResource:
r.StorageResources = append(r.StorageResources, d.(*storage.StorageResource))
case *processing.ProcessingResource:
r.ProcessingResources = append(r.ProcessingResources, d.(*processing.ProcessingResource))
case *w.WorkflowResource:
r.WorkflowResources = append(r.WorkflowResources, d.(*w.WorkflowResource))
case *DataResource:
r.DataResources = append(r.DataResources, d.(*DataResource))
case *ComputeResource:
r.ComputeResources = append(r.ComputeResources, d.(*ComputeResource))
case *StorageResource:
r.StorageResources = append(r.StorageResources, d.(*StorageResource))
case *ProcessingResource:
r.ProcessingResources = append(r.ProcessingResources, d.(*ProcessingResource))
case *WorkflowResource:
r.WorkflowResources = append(r.WorkflowResources, d.(*WorkflowResource))
}
}
}
@@ -58,11 +67,11 @@ func (r *ResourceSet) Fill(peerID string, groups []string) {
}
type ItemResource struct {
Data *data.DataResource `bson:"data,omitempty" json:"data,omitempty"`
Processing *processing.ProcessingResource `bson:"processing,omitempty" json:"processing,omitempty"`
Storage *storage.StorageResource `bson:"storage,omitempty" json:"storage,omitempty"`
Compute *compute.ComputeResource `bson:"compute,omitempty" json:"compute,omitempty"`
Workflow *w.WorkflowResource `bson:"workflow,omitempty" json:"workflow,omitempty"`
Data *DataResource `bson:"data,omitempty" json:"data,omitempty"`
Processing *ProcessingResource `bson:"processing,omitempty" json:"processing,omitempty"`
Storage *StorageResource `bson:"storage,omitempty" json:"storage,omitempty"`
Compute *ComputeResource `bson:"compute,omitempty" json:"compute,omitempty"`
Workflow *WorkflowResource `bson:"workflow,omitempty" json:"workflow,omitempty"`
}
func (i *ItemResource) GetAbstractRessource() *resource_model.AbstractResource {

View File

@@ -0,0 +1,94 @@
package resources
import (
"cloud.o-forge.io/core/oc-lib/dbs"
"cloud.o-forge.io/core/oc-lib/logs"
"cloud.o-forge.io/core/oc-lib/models/resources/resource_model"
"cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
)
type resourceMongoAccessor[T ResourceInterface] struct {
utils.AbstractAccessor // AbstractAccessor contains the basic fields of an accessor (model, caller)
generateData func() utils.DBObject
}
// New creates a new instance of the computeMongoAccessor
func New[T ResourceInterface](t tools.DataType, peerID string, groups []string, caller *tools.HTTPCaller, g func() utils.DBObject) *resourceMongoAccessor[T] {
return &resourceMongoAccessor[T]{
AbstractAccessor: utils.AbstractAccessor{
ResourceModelAccessor: resource_model.New(),
Logger: logs.CreateLogger(t.String()), // Create a logger with the data type
Caller: caller,
PeerID: peerID,
Groups: groups, // Set the caller
Type: t,
},
generateData: g,
}
}
/*
* Nothing special here, just the basic CRUD operations
*/
func (dca *resourceMongoAccessor[T]) DeleteOne(id string) (utils.DBObject, int, error) {
return dca.GenericDeleteOne(id, dca)
}
func (dca *resourceMongoAccessor[T]) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) {
set.(T).SetResourceModel(nil)
return dca.GenericUpdateOne(set.(T).Trim(), id, dca, dca.generateData()) // TODO CHANGE
}
func (dca *resourceMongoAccessor[T]) StoreOne(data utils.DBObject) (utils.DBObject, int, error) {
data.(T).SetResourceModel(nil)
return dca.GenericStoreOne(data.(T).Trim(), dca)
}
func (dca *resourceMongoAccessor[T]) CopyOne(data utils.DBObject) (utils.DBObject, int, error) {
return dca.StoreOne(data)
}
func (dca *resourceMongoAccessor[T]) LoadOne(id string) (utils.DBObject, int, error) {
return utils.GenericLoadOne[T](id, func(d utils.DBObject) (utils.DBObject, int, error) {
resources, _, err := dca.ResourceModelAccessor.Search(nil, dca.GetType().String())
if err == nil && len(resources) > 0 {
d.(T).SetResourceModel(resources[0].(*resource_model.ResourceModel))
}
return d, 200, nil
}, dca)
}
func (wfa *resourceMongoAccessor[T]) LoadAll() ([]utils.ShallowDBObject, int, error) {
resources, _, err := wfa.ResourceModelAccessor.Search(nil, wfa.GetType().String())
return utils.GenericLoadAll[T](func(d utils.DBObject) utils.ShallowDBObject {
if err == nil && len(resources) > 0 {
d.(T).SetResourceModel(resources[0].(*resource_model.ResourceModel))
}
return d
}, wfa)
}
func (wfa *resourceMongoAccessor[T]) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) {
resources, _, err := wfa.ResourceModelAccessor.Search(nil, wfa.GetType().String())
return utils.GenericSearch[T](filters, search, wfa.getResourceFilter(search),
func(d utils.DBObject) utils.ShallowDBObject {
if err == nil && len(resources) > 0 {
d.(T).SetResourceModel(resources[0].(*resource_model.ResourceModel))
}
return d
}, wfa)
}
func (abs *resourceMongoAccessor[T]) getResourceFilter(search string) *dbs.Filters {
return &dbs.Filters{
Or: map[string][]dbs.Filter{ // filter by like name, short_description, description, owner, url if no filters are provided
"abstractresource.abstractobject.name": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.short_description": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.description": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.owner": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.source_url": {{Operator: dbs.LIKE.String(), Value: search}},
},
}
}

View File

@@ -5,7 +5,6 @@ import (
"slices"
"cloud.o-forge.io/core/oc-lib/config"
"cloud.o-forge.io/core/oc-lib/dbs"
"cloud.o-forge.io/core/oc-lib/models/peer"
"cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
@@ -39,6 +38,10 @@ type AbstractResource struct {
Currency string `json:"currency,omitempty" bson:"currency,omitempty"` // Currency is the currency of the price
}
func (abs *AbstractResource) SetResourceModel(model *ResourceModel) {
abs.ResourceModel = model
}
func (abs *AbstractResource) VerifyAuth(peerID string, groups []string) bool {
if grps, ok := abs.AllowedPeersGroup[peerID]; ok || config.GetConfig().Whitelist {
if (ok && slices.Contains(grps, "*")) || (!ok && config.GetConfig().Whitelist) {
@@ -53,18 +56,6 @@ func (abs *AbstractResource) VerifyAuth(peerID string, groups []string) bool {
return false
}
func (abs *AbstractResource) GetResourceFilter(search string) *dbs.Filters {
return &dbs.Filters{
Or: map[string][]dbs.Filter{ // filter by like name, short_description, description, owner, url if no filters are provided
"abstractresource.abstractobject.name": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.short_description": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.description": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.owner": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.source_url": {{Operator: dbs.LIKE.String(), Value: search}},
},
}
}
/*
* GetModelType returns the type of the model key
*/
@@ -147,7 +138,7 @@ func (abs *ResourceModel) VerifyAuth(peerID string, groups []string) bool {
func (d *ResourceModel) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
return &ResourceModelMongoAccessor{
utils.AbstractAccessor{
Type: tools.RESOURCE_MODEL.String(),
Type: tools.RESOURCE_MODEL,
PeerID: peerID,
Groups: groups,
Caller: caller,

View File

@@ -2,7 +2,6 @@ package resource_model
import (
"cloud.o-forge.io/core/oc-lib/dbs"
"cloud.o-forge.io/core/oc-lib/dbs/mongo"
"cloud.o-forge.io/core/oc-lib/logs"
"cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
@@ -19,7 +18,7 @@ type ResourceModelMongoAccessor struct {
func New() *ResourceModelMongoAccessor {
return &ResourceModelMongoAccessor{
utils.AbstractAccessor{
Type: tools.RESOURCE_MODEL.String(),
Type: tools.RESOURCE_MODEL,
Logger: logs.CreateLogger(tools.RESOURCE_MODEL.String()),
},
}
@@ -41,54 +40,23 @@ func (wfa *ResourceModelMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObj
return wfa.GenericStoreOne(data, wfa)
}
func (wfa *ResourceModelMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) {
var workflow ResourceModel
res_mongo, code, err := mongo.MONGOService.LoadOne(id, wfa.GetType())
if err != nil {
wfa.Logger.Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error())
return nil, code, err
}
res_mongo.Decode(&workflow)
return &workflow, 200, nil
func (a *ResourceModelMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) {
return utils.GenericLoadOne[*ResourceModel](id, func(d utils.DBObject) (utils.DBObject, int, error) {
return d, 200, nil
}, a)
}
func (wfa ResourceModelMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, error) {
objs := []utils.ShallowDBObject{}
res_mongo, code, err := mongo.MONGOService.LoadAll(wfa.GetType())
if err != nil {
wfa.Logger.Error().Msg("Could not retrieve any from db. Error: " + err.Error())
return nil, code, err
}
var results []ResourceModel
if err = res_mongo.All(mongo.MngoCtx, &results); err != nil {
return nil, 404, err
}
for _, r := range results {
objs = append(objs, &r)
}
return objs, 200, nil
func (a *ResourceModelMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, error) {
return utils.GenericLoadAll[*ResourceModel](func(d utils.DBObject) utils.ShallowDBObject {
return d
}, a)
}
func (wfa *ResourceModelMongoAccessor) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) {
objs := []utils.ShallowDBObject{}
if (filters == nil || len(filters.And) == 0 || len(filters.Or) == 0) && search != "" {
filters = &dbs.Filters{
func (a *ResourceModelMongoAccessor) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) {
return utils.GenericSearch[*ResourceModel](filters, search,
&dbs.Filters{
Or: map[string][]dbs.Filter{
"resource_type": {{Operator: dbs.LIKE.String(), Value: search}},
},
}
}
res_mongo, code, err := mongo.MONGOService.Search(filters, wfa.GetType())
if err != nil {
wfa.Logger.Error().Msg("Could not store to db. Error: " + err.Error())
return nil, code, err
}
var results []ResourceModel
if err = res_mongo.All(mongo.MngoCtx, &results); err != nil {
return nil, 404, err
}
for _, r := range results {
objs = append(objs, &r)
}
return objs, 200, nil
}, func(d utils.DBObject) utils.ShallowDBObject { return d }, a)
}

View File

@@ -1,4 +1,4 @@
package storage
package resources
import (
"cloud.o-forge.io/core/oc-lib/models/resources/resource_model"
@@ -57,5 +57,5 @@ type StorageResource struct {
}
func (d *StorageResource) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
return New(tools.STORAGE_RESOURCE, peerID, groups, caller) // Create a new instance of the accessor
return New[*StorageResource](tools.STORAGE_RESOURCE, peerID, groups, caller, func() utils.DBObject { return &StorageResource{} }) // Create a new instance of the accessor
}

View File

@@ -1,133 +0,0 @@
package storage
import (
"errors"
"cloud.o-forge.io/core/oc-lib/dbs"
"cloud.o-forge.io/core/oc-lib/dbs/mongo"
"cloud.o-forge.io/core/oc-lib/logs"
"cloud.o-forge.io/core/oc-lib/models/resources/resource_model"
"cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
)
type storageMongoAccessor struct {
utils.AbstractAccessor // AbstractAccessor contains the basic fields of an accessor (model, caller)
}
// New creates a new instance of the storageMongoAccessor
func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCaller) *storageMongoAccessor {
return &storageMongoAccessor{
utils.AbstractAccessor{
ResourceModelAccessor: resource_model.New(),
Logger: logs.CreateLogger(t.String()), // Create a logger with the data type
Caller: caller,
PeerID: peerID,
Groups: groups, // Set the caller
Type: t.String(),
},
}
}
/*
* Nothing special here, just the basic CRUD operations
*/
func (sma *storageMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) {
return sma.GenericDeleteOne(id, sma)
}
func (sma *storageMongoAccessor) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) {
set.(*StorageResource).ResourceModel = nil
return sma.GenericUpdateOne(set.(*StorageResource).Trim(), id, sma, &StorageResource{})
}
func (sma *storageMongoAccessor) StoreOne(data utils.DBObject) (utils.DBObject, int, error) {
data.(*StorageResource).ResourceModel = nil
return sma.GenericStoreOne(data.(*StorageResource).Trim(), sma)
}
func (sma *storageMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObject, int, error) {
return sma.StoreOne(data)
}
func (sma *storageMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) {
var storage StorageResource
res_mongo, code, err := mongo.MONGOService.LoadOne(id, sma.GetType())
if err != nil {
sma.Logger.Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error())
return nil, code, err
}
res_mongo.Decode(&storage)
if !storage.VerifyAuth(sma.PeerID, sma.Groups) {
return nil, 403, errors.New("You are not allowed to access this collaborative area")
}
resources, _, err := sma.ResourceModelAccessor.Search(nil, sma.GetType())
if err == nil && len(resources) > 0 {
storage.ResourceModel = resources[0].(*resource_model.ResourceModel)
}
return &storage, 200, nil
}
func (wfa storageMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, error) {
objs := []utils.ShallowDBObject{}
res_mongo, code, err := mongo.MONGOService.LoadAll(wfa.GetType())
if err != nil {
wfa.Logger.Error().Msg("Could not retrieve any from db. Error: " + err.Error())
return nil, code, err
}
var results []StorageResource
if err = res_mongo.All(mongo.MngoCtx, &results); err != nil {
return nil, 404, err
}
resources, _, err := wfa.ResourceModelAccessor.Search(nil, wfa.GetType())
for _, r := range results {
if !r.VerifyAuth(wfa.PeerID, wfa.Groups) {
continue
}
if err == nil && len(resources) > 0 {
r.ResourceModel = resources[0].(*resource_model.ResourceModel)
}
objs = append(objs, &r) // only get the abstract resource !
}
return objs, 200, nil
}
// Search searches for storage resources in the database, given some filters OR a search string
func (wfa *storageMongoAccessor) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) {
objs := []utils.ShallowDBObject{}
if (filters == nil || len(filters.And) == 0 || len(filters.Or) == 0) && search != "" {
filters = &dbs.Filters{
Or: map[string][]dbs.Filter{ // filter by like name, short_description, description, owner, url if no filters are provided
"abstractresource.abstractobject.name": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.short_description": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.description": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.owner": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.source_url": {{Operator: dbs.LIKE.String(), Value: search}},
},
}
}
res_mongo, code, err := mongo.MONGOService.Search(filters, wfa.GetType())
if err != nil {
wfa.Logger.Error().Msg("Could not store to db. Error: " + err.Error())
return nil, code, err
}
var results []StorageResource
if err = res_mongo.All(mongo.MngoCtx, &results); err != nil {
return nil, 404, err
}
resources, _, err := wfa.ResourceModelAccessor.Search(nil, wfa.GetType())
for _, r := range results {
if !r.VerifyAuth(wfa.PeerID, wfa.Groups) {
continue
}
if err == nil && len(resources) > 0 {
r.ResourceModel = resources[0].(*resource_model.ResourceModel)
}
objs = append(objs, &r) // only get the abstract resource !
}
return objs, 200, nil
}

View File

@@ -1,47 +0,0 @@
package storage
import (
"testing"
"cloud.o-forge.io/core/oc-lib/models/resources/resource_model"
"cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
"github.com/stretchr/testify/assert"
)
func TestStoreOneStorage(t *testing.T) {
s := StorageResource{Size: 123, WebResource: resource_model.WebResource{Protocol: "http", Path: "azerty.fr"},
AbstractResource: resource_model.AbstractResource{
AbstractObject: utils.AbstractObject{Name: "testData"},
Description: "Lorem Ipsum",
Logo: "azerty.com",
Owner: "toto",
OwnerLogo: "totoLogo",
SourceUrl: "azerty.fr",
},
}
sma := New(tools.STORAGE_RESOURCE, "peerID", []string{}, nil)
id, _, _ := sma.StoreOne(&s)
assert.NotEmpty(t, id)
}
func TestLoadOneStorage(t *testing.T) {
s := StorageResource{Size: 123, WebResource: resource_model.WebResource{Protocol: "http", Path: "azerty.fr"},
AbstractResource: resource_model.AbstractResource{
AbstractObject: utils.AbstractObject{Name: "testData"},
Description: "Lorem Ipsum",
Logo: "azerty.com",
Owner: "toto",
OwnerLogo: "totoLogo",
SourceUrl: "azerty.fr",
},
}
sma := New(tools.STORAGE_RESOURCE, "peerID", []string{}, nil)
new_s, _, _ := sma.StoreOne(&s)
assert.Equal(t, s, new_s)
}

View File

@@ -1,4 +1,4 @@
package oclib
package resources
import (
"cloud.o-forge.io/core/oc-lib/models/resources/resource_model"
@@ -14,5 +14,5 @@ type WorkflowResource struct {
}
func (d *WorkflowResource) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
return New(tools.WORKFLOW_RESOURCE, peerID, groups, caller) // Create a new instance of the accessor
return New[*WorkflowResource](tools.WORKFLOW_RESOURCE, peerID, groups, caller, func() utils.DBObject { return &WorkflowResource{} }) // Create a new instance of the accessor
}

View File

@@ -1,70 +0,0 @@
package graph
import (
"cloud.o-forge.io/core/oc-lib/models/resources"
"cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
)
// Graph is a struct that represents a graph
type Graph struct {
Zoom float64 `bson:"zoom" json:"zoom" default:"1"` // Zoom is the graphical zoom of the graph
Items map[string]GraphItem `bson:"items" json:"items" default:"{}" validate:"required"` // Items is the list of elements in the graph
Links []GraphLink `bson:"links" json:"links" default:"{}" validate:"required"` // Links is the list of links between elements in the graph
}
func (g *Graph) GetResource(id string) (string, utils.DBObject) {
if item, ok := g.Items[id]; ok {
if item.Data != nil {
return tools.DATA_RESOURCE.String(), item.Data
} else if item.Compute != nil {
return tools.COMPUTE_RESOURCE.String(), item.Compute
} else if item.Workflow != nil {
return tools.WORKFLOW_RESOURCE.String(), item.Workflow
} else if item.Processing != nil {
return tools.PROCESSING_RESOURCE.String(), item.Processing
} else if item.Storage != nil {
return tools.STORAGE_RESOURCE.String(), item.Storage
}
}
return "", nil
}
// GraphItem is a struct that represents an item in a graph
type GraphItem struct {
ID string `bson:"id" json:"id" validate:"required"` // ID is the unique identifier of the item
Width float64 `bson:"width" json:"width" validate:"required"` // Width is the graphical width of the item
Height float64 `bson:"height" json:"height" validate:"required"` // Height is the graphical height of the item
Position Position `bson:"position" json:"position" validate:"required"` // Position is the graphical position of the item
*resources.ItemResource // ItemResource is the resource of the item affected to the item
}
// GraphLink is a struct that represents a link between two items in a graph
type GraphLink struct {
Source Position `bson:"source" json:"source" validate:"required"` // Source is the source graphical position of the link
Destination Position `bson:"destination" json:"destination" validate:"required"` // Destination is the destination graphical position of the link
Style *GraphLinkStyle `bson:"style,omitempty" json:"style,omitempty"` // Style is the graphical style of the link
}
// GraphLinkStyle is a struct that represents the style of a link in a graph
type GraphLinkStyle struct {
Color int64 `bson:"color" json:"color"` // Color is the graphical color of the link (int description of a color, can be transpose as hex)
Stroke float64 `bson:"stroke" json:"stroke"` // Stroke is the graphical stroke of the link
Tension float64 `bson:"tension" json:"tension"` // Tension is the graphical tension of the link
HeadRadius float64 `bson:"head_radius" json:"head_radius"` // graphical pin radius
DashWidth float64 `bson:"dash_width" json:"dash_width"` // DashWidth is the graphical dash width of the link
DashSpace float64 `bson:"dash_space" json:"dash_space"` // DashSpace is the graphical dash space of the link
EndArrow Position `bson:"end_arrow" json:"end_arrow"` // EndArrow is the graphical end arrow of the link
StartArrow Position `bson:"start_arrow" json:"start_arrow"` // StartArrow is the graphical start arrow of the link
ArrowStyle int64 `bson:"arrow_style" json:"arrow_style"` // ArrowStyle is the graphical arrow style of the link (enum foundable in UI)
ArrowDirection int64 `bson:"arrow_direction" json:"arrow_direction"` // ArrowDirection is the graphical arrow direction of the link (enum foundable in UI)
StartArrowWidth float64 `bson:"start_arrow_width" json:"start_arrow_width"` // StartArrowWidth is the graphical start arrow width of the link
EndArrowWidth float64 `bson:"end_arrow_width" json:"end_arrow_width"` // EndArrowWidth is the graphical end arrow width of the link
}
// Position is a struct that represents a graphical position
type Position struct {
ID string `json:"id" bson:"id"` // ID reprents ItemID (optionnal), TODO: rename to ItemID
X float64 `json:"x" bson:"x" validate:"required"` // X is the graphical x position
Y float64 `json:"y" bson:"y" validate:"required"` // Y is the graphical y position
}

View File

@@ -1,132 +0,0 @@
package oclib
import (
"errors"
"cloud.o-forge.io/core/oc-lib/dbs"
"cloud.o-forge.io/core/oc-lib/dbs/mongo"
"cloud.o-forge.io/core/oc-lib/logs"
"cloud.o-forge.io/core/oc-lib/models/resources/resource_model"
"cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
)
type workflowResourceMongoAccessor struct {
utils.AbstractAccessor // AbstractAccessor contains the basic fields of an accessor (model, caller)
}
func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCaller) *workflowResourceMongoAccessor {
return &workflowResourceMongoAccessor{
utils.AbstractAccessor{
ResourceModelAccessor: resource_model.New(),
Logger: logs.CreateLogger(t.String()), // Create a logger with the data type
Caller: caller,
PeerID: peerID,
Groups: groups, // Set the caller
Type: t.String(),
},
}
}
func (wfa *workflowResourceMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) {
return wfa.GenericDeleteOne(id, wfa)
}
func (wfa *workflowResourceMongoAccessor) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) {
set.(*WorkflowResource).ResourceModel = nil
return wfa.GenericUpdateOne(set.(*WorkflowResource).Trim(), id, wfa, &WorkflowResource{})
}
func (wfa *workflowResourceMongoAccessor) StoreOne(data utils.DBObject) (utils.DBObject, int, error) {
data.(*WorkflowResource).ResourceModel = nil
return wfa.GenericStoreOne(data.(*WorkflowResource).Trim(), wfa)
}
func (wfa *workflowResourceMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObject, int, error) {
res, _, _ := wfa.LoadOne(data.GetID())
data.(*WorkflowResource).WorkflowID = data.GetID()
if res == nil {
return wfa.GenericStoreOne(data.(*WorkflowResource).Trim(), wfa)
} else {
data.(*WorkflowResource).UUID = res.GetID()
return wfa.GenericUpdateOne(data.(*WorkflowResource).Trim(), res.GetID(), wfa, &WorkflowResource{})
}
}
func (wfa *workflowResourceMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) {
var workflow WorkflowResource
res_mongo, code, err := mongo.MONGOService.LoadOne(id, wfa.GetType())
if err != nil {
wfa.Logger.Error().Msg("Could not retrieve " + id + " from db. Error: " + err.Error())
return nil, code, err
}
res_mongo.Decode(&workflow)
if !workflow.VerifyAuth(wfa.PeerID, wfa.Groups) {
return nil, 403, errors.New("You are not allowed to access this collaborative area")
}
resources, _, err := wfa.ResourceModelAccessor.Search(nil, wfa.GetType())
if err == nil && len(resources) > 0 {
workflow.ResourceModel = resources[0].(*resource_model.ResourceModel)
}
return &workflow, 200, nil
}
func (wfa workflowResourceMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, error) {
objs := []utils.ShallowDBObject{}
res_mongo, code, err := mongo.MONGOService.LoadAll(wfa.GetType())
if err != nil {
wfa.Logger.Error().Msg("Could not retrieve any from db. Error: " + err.Error())
return nil, code, err
}
var results []WorkflowResource
if err = res_mongo.All(mongo.MngoCtx, &results); err != nil {
return nil, 404, err
}
resources, _, err := wfa.ResourceModelAccessor.Search(nil, wfa.GetType())
for _, r := range results {
if !r.VerifyAuth(wfa.PeerID, wfa.Groups) {
continue
}
if err == nil && len(resources) > 0 {
r.ResourceModel = resources[0].(*resource_model.ResourceModel)
}
objs = append(objs, &r)
}
return objs, 200, nil
}
// Search searches for workflow resources in the database, given some filters OR a search string
func (wfa *workflowResourceMongoAccessor) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) {
objs := []utils.ShallowDBObject{}
if (filters == nil || len(filters.And) == 0 || len(filters.Or) == 0) && search != "" {
filters = &dbs.Filters{
Or: map[string][]dbs.Filter{ // filter by like name, short_description, description, owner, url if no filters are provided
"abstractresource.abstractobject.name": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.short_description": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.description": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.owner": {{Operator: dbs.LIKE.String(), Value: search}},
"abstractresource.source_url": {{Operator: dbs.LIKE.String(), Value: search}},
},
}
}
res_mongo, code, err := mongo.MONGOService.Search(filters, wfa.GetType())
if err != nil {
wfa.Logger.Error().Msg("Could not store to db. Error: " + err.Error())
return nil, code, err
}
var results []WorkflowResource
if err = res_mongo.All(mongo.MngoCtx, &results); err != nil {
return nil, 404, err
}
resources, _, err := wfa.ResourceModelAccessor.Search(nil, wfa.GetType())
for _, r := range results {
if !r.VerifyAuth(wfa.PeerID, wfa.Groups) {
continue
}
if err == nil && len(resources) > 0 {
r.ResourceModel = resources[0].(*resource_model.ResourceModel)
}
objs = append(objs, &r)
}
return objs, 200, nil
}

View File

@@ -1,44 +0,0 @@
package oclib
import (
"testing"
"cloud.o-forge.io/core/oc-lib/models/resources/resource_model"
"cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
"github.com/stretchr/testify/assert"
)
func TestStoreOneWorkflow(t *testing.T) {
w := WorkflowResource{AbstractResource: resource_model.AbstractResource{
AbstractObject: utils.AbstractObject{Name: "testWorkflow"},
Description: "Lorem Ipsum",
Logo: "azerty.com",
Owner: "toto",
OwnerLogo: "totoLogo",
SourceUrl: "azerty.fr",
},
}
wma := New(tools.WORKFLOW_RESOURCE, "peerID", []string{}, nil)
id, _, _ := wma.StoreOne(&w)
assert.NotEmpty(t, id)
}
func TestLoadOneWorkflow(t *testing.T) {
w := WorkflowResource{AbstractResource: resource_model.AbstractResource{
AbstractObject: utils.AbstractObject{Name: "testWorkflow"},
Description: "Lorem Ipsum",
Logo: "azerty.com",
Owner: "toto",
OwnerLogo: "totoLogo",
SourceUrl: "azerty.fr",
},
}
wma := New(tools.WORKFLOW_RESOURCE, "peerID", []string{}, nil)
new_w, _, _ := wma.StoreOne(&w)
assert.Equal(t, w, new_w)
}