This commit is contained in:
mr 2024-11-28 13:19:01 +01:00
parent b388e43f30
commit 9ea342c4c4
37 changed files with 198 additions and 122 deletions

View File

@ -26,7 +26,7 @@ func (wfa *Booking) CheckBooking(id string, start time.Time, end *time.Time) (bo
return true, nil return true, nil
} }
e := *end e := *end
accessor := New() accessor := New(tools.BOOKING, "", nil, nil)
res, code, err := accessor.Search(&dbs.Filters{ res, code, err := accessor.Search(&dbs.Filters{
And: map[string][]dbs.Filter{ // check if there is a booking on the same compute resource by filtering on the compute_resource_id, the state and the execution date And: map[string][]dbs.Filter{ // check if there is a booking on the same compute resource by filtering on the compute_resource_id, the state and the execution date
"compute_resource_id": {{Operator: dbs.EQUAL.String(), Value: id}}, "compute_resource_id": {{Operator: dbs.EQUAL.String(), Value: id}},
@ -54,7 +54,5 @@ func (d *Booking) GetName() string {
} }
func (d *Booking) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor { func (d *Booking) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
data := New() // Create a new instance of the accessor return New(tools.BOOKING, peerID, groups, caller) // Create a new instance of the accessor
data.Init(tools.BOOKING, peerID, groups, caller) // Initialize the accessor with the BOOKING model type
return data
} }

View File

@ -5,8 +5,10 @@ import (
"cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/dbs"
"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/utils" "cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/models/workflow_execution" "cloud.o-forge.io/core/oc-lib/models/workflow_execution"
"cloud.o-forge.io/core/oc-lib/tools"
) )
type bookingMongoAccessor struct { type bookingMongoAccessor struct {
@ -14,8 +16,16 @@ type bookingMongoAccessor struct {
} }
// New creates a new instance of the bookingMongoAccessor // New creates a new instance of the bookingMongoAccessor
func New() *bookingMongoAccessor { func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCaller) *bookingMongoAccessor {
return &bookingMongoAccessor{} return &bookingMongoAccessor{
AbstractAccessor: utils.AbstractAccessor{
Logger: logs.CreateLogger(t.String()), // Create a logger with the data type
Caller: caller,
PeerID: peerID,
Groups: groups, // Set the caller
Type: t.String(),
},
}
} }
/* /*

View File

@ -59,9 +59,7 @@ func (ao *CollaborativeArea) VerifyAuth(peerID string, groups []string) bool {
} }
func (d *CollaborativeArea) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor { func (d *CollaborativeArea) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
data := New(peerID, groups) // Create a new instance of the accessor return New(tools.COLLABORATIVE_AREA, peerID, groups, caller) // Create a new instance of the accessor
data.Init(tools.COLLABORATIVE_AREA, peerID, groups, caller) // Initialize the accessor with the SHARED_WORKSPACE model type
return data
} }
func (d *CollaborativeArea) Trim() *CollaborativeArea { func (d *CollaborativeArea) Trim() *CollaborativeArea {

View File

@ -9,6 +9,7 @@ import (
"cloud.o-forge.io/core/oc-lib/config" "cloud.o-forge.io/core/oc-lib/config"
"cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/dbs"
"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/collaborative_area/rules/rule" "cloud.o-forge.io/core/oc-lib/models/collaborative_area/rules/rule"
"cloud.o-forge.io/core/oc-lib/models/peer" "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/models/utils"
@ -27,9 +28,15 @@ type collaborativeAreaMongoAccessor struct {
ruleAccessor utils.Accessor ruleAccessor utils.Accessor
} }
// New creates a new instance of the collaborativeAreaMongoAccessor func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCaller) *collaborativeAreaMongoAccessor {
func New(peerID string, groups []string) *collaborativeAreaMongoAccessor {
return &collaborativeAreaMongoAccessor{ return &collaborativeAreaMongoAccessor{
AbstractAccessor: utils.AbstractAccessor{
Logger: logs.CreateLogger(t.String()), // Create a logger with the data type
Caller: caller,
PeerID: peerID,
Groups: groups, // Set the caller
Type: t.String(),
},
workspaceAccessor: (&workspace.Workspace{}).GetAccessor(peerID, groups, nil), workspaceAccessor: (&workspace.Workspace{}).GetAccessor(peerID, groups, nil),
workflowAccessor: (&w.Workflow{}).GetAccessor(peerID, groups, nil), workflowAccessor: (&w.Workflow{}).GetAccessor(peerID, groups, nil),
peerAccessor: (&peer.Peer{}).GetAccessor(peerID, groups, nil), peerAccessor: (&peer.Peer{}).GetAccessor(peerID, groups, nil),

View File

@ -21,7 +21,5 @@ func (r *Rule) GenerateID() {
} }
func (d *Rule) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor { func (d *Rule) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
data := New() return New(tools.RULE, peerID, groups, caller)
data.Init(tools.RULE, peerID, groups, caller)
return data
} }

View File

@ -3,7 +3,9 @@ package rule
import ( import (
"cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/dbs"
"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/utils" "cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
) )
type ruleMongoAccessor struct { type ruleMongoAccessor struct {
@ -11,8 +13,16 @@ type ruleMongoAccessor struct {
} }
// New creates a new instance of the ruleMongoAccessor // New creates a new instance of the ruleMongoAccessor
func New() *ruleMongoAccessor { func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCaller) *ruleMongoAccessor {
return &ruleMongoAccessor{} return &ruleMongoAccessor{
AbstractAccessor: utils.AbstractAccessor{
Logger: logs.CreateLogger(t.String()), // Create a logger with the data type
Caller: caller,
PeerID: peerID,
Groups: groups, // Set the caller
Type: t.String(),
},
}
} }
// GetType returns the type of the rule // GetType returns the type of the rule

View File

@ -19,7 +19,5 @@ type ShallowCollaborativeArea struct {
} }
func (d *ShallowCollaborativeArea) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor { func (d *ShallowCollaborativeArea) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
data := New() return New(tools.COLLABORATIVE_AREA, peerID, groups, caller)
data.Init(tools.COLLABORATIVE_AREA, peerID, groups, caller)
return data
} }

View File

@ -3,15 +3,25 @@ package shallow_collaborative_area
import ( import (
"cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/dbs"
"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/utils" "cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
) )
type shallowSharedWorkspaceMongoAccessor struct { type shallowSharedWorkspaceMongoAccessor struct {
utils.AbstractAccessor utils.AbstractAccessor
} }
func New() *shallowSharedWorkspaceMongoAccessor { func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCaller) *shallowSharedWorkspaceMongoAccessor {
return &shallowSharedWorkspaceMongoAccessor{} return &shallowSharedWorkspaceMongoAccessor{
AbstractAccessor: utils.AbstractAccessor{
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 *shallowSharedWorkspaceMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) { func (wfa *shallowSharedWorkspaceMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) {

View File

@ -63,7 +63,7 @@ func (ao *Peer) RemoveExecution(exec PeerExecution) {
// IsMySelf checks if the peer is the local peer // IsMySelf checks if the peer is the local peer
func (ao *Peer) IsMySelf() (bool, string) { func (ao *Peer) IsMySelf() (bool, string) {
d, code, err := New().Search(nil, SELF.String()) d, code, err := New(tools.PEER, "", nil, nil).Search(nil, SELF.String())
if code != 200 || err != nil || len(d) == 0 { if code != 200 || err != nil || len(d) == 0 {
return false, "" return false, ""
} }
@ -77,7 +77,6 @@ func (p *Peer) LaunchPeerExecution(peerID string, dataID string, dt tools.DataTy
return cache.LaunchPeerExecution(peerID, dataID, dt, method, body, caller) // Launch the execution on the peer through the cache return cache.LaunchPeerExecution(peerID, dataID, dt, method, body, caller) // Launch the execution on the peer through the cache
} }
func (d *Peer) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor { func (d *Peer) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
data := New() // Create a new instance of the accessor data := New(tools.PEER, peerID, groups, caller) // Create a new instance of the accessor
data.Init(tools.PEER, peerID, groups, caller) // Initialize the accessor with the PEER model type
return data return data
} }

View File

@ -56,7 +56,7 @@ func (p *PeerCache) urlFormat(url string, dt tools.DataType) string {
// checkPeerStatus checks the status of a peer // checkPeerStatus checks the status of a peer
func (p *PeerCache) checkPeerStatus(peerID string, appName string, caller *tools.HTTPCaller) (*Peer, bool) { func (p *PeerCache) checkPeerStatus(peerID string, appName string, caller *tools.HTTPCaller) (*Peer, bool) {
api := tools.API{} api := tools.API{}
access := New() access := NewShallow()
res, code, _ := access.LoadOne(peerID) // Load the peer from db res, code, _ := access.LoadOne(peerID) // Load the peer from db
if code != 200 { // no peer no party if code != 200 { // no peer no party
return nil, false return nil, false
@ -101,7 +101,7 @@ func (p *PeerCache) LaunchPeerExecution(peerID string, dataID string,
DataID: dataID, DataID: dataID,
} }
mypeer.AddExecution(*pexec) mypeer.AddExecution(*pexec)
New().UpdateOne(mypeer, peerID) // Update the peer in the db NewShallow().UpdateOne(mypeer, peerID) // Update the peer in the db
return nil, errors.New("peer is not reachable") return nil, errors.New("peer is not reachable")
} else { } else {
if mypeer == nil { if mypeer == nil {
@ -111,7 +111,7 @@ func (p *PeerCache) LaunchPeerExecution(peerID string, dataID string,
url = p.urlFormat((mypeer.Url)+meth, dt) // Format the URL url = p.urlFormat((mypeer.Url)+meth, dt) // Format the URL
tmp := mypeer.FailedExecution // Get the failed executions list tmp := mypeer.FailedExecution // Get the failed executions list
mypeer.FailedExecution = []PeerExecution{} // Reset the failed executions list mypeer.FailedExecution = []PeerExecution{} // Reset the failed executions list
New().UpdateOne(mypeer, peerID) // Update the peer in the db NewShallow().UpdateOne(mypeer, peerID) // Update the peer in the db
for _, v := range tmp { // Retry the failed executions for _, v := range tmp { // Retry the failed executions
go p.exec(v.Url, tools.ToMethod(v.Method), v.Body, caller) go p.exec(v.Url, tools.ToMethod(v.Method), v.Body, caller)
} }

View File

@ -5,7 +5,9 @@ import (
"cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/dbs"
"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/utils" "cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
) )
type peerMongoAccessor struct { type peerMongoAccessor struct {
@ -13,8 +15,25 @@ type peerMongoAccessor struct {
} }
// New creates a new instance of the peerMongoAccessor // New creates a new instance of the peerMongoAccessor
func New() *peerMongoAccessor { func NewShallow() *peerMongoAccessor {
return &peerMongoAccessor{} return &peerMongoAccessor{
utils.AbstractAccessor{
Logger: logs.CreateLogger(tools.PEER.String()), // Create a logger with the data type
Type: tools.PEER.String(),
},
}
}
func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCaller) *peerMongoAccessor {
return &peerMongoAccessor{
utils.AbstractAccessor{
Logger: logs.CreateLogger(t.String()), // Create a logger with the data type
Caller: caller,
PeerID: peerID,
Groups: groups, // Set the caller
Type: t.String(),
},
}
} }
/* /*

View File

@ -53,9 +53,7 @@ type ComputeResource struct {
} }
func (d *ComputeResource) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor { func (d *ComputeResource) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
data := New(peerID, groups) return New(tools.COMPUTE_RESOURCE, peerID, groups, caller)
data.Init(tools.COMPUTE_RESOURCE, peerID, groups, caller)
return data
} }
// CPU is a struct that represents a CPU // CPU is a struct that represents a CPU

View File

@ -2,8 +2,10 @@ package compute
import ( import (
"cloud.o-forge.io/core/oc-lib/dbs" "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/resources/resource_model"
"cloud.o-forge.io/core/oc-lib/models/utils" "cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
) )
type computeMongoAccessor struct { type computeMongoAccessor struct {
@ -11,10 +13,15 @@ type computeMongoAccessor struct {
} }
// New creates a new instance of the computeMongoAccessor // New creates a new instance of the computeMongoAccessor
func New(peerID string, groups []string) *computeMongoAccessor { func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCaller) *computeMongoAccessor {
return &computeMongoAccessor{ return &computeMongoAccessor{
utils.AbstractAccessor{ utils.AbstractAccessor{
ResourceModelAccessor: resource_model.New(), 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(),
}, },
} }
} }
@ -53,12 +60,11 @@ func (dca *computeMongoAccessor) LoadOne(id string) (utils.DBObject, int, error)
func (wfa *computeMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, error) { func (wfa *computeMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, error) {
resources, _, err := wfa.ResourceModelAccessor.Search(nil, wfa.GetType()) resources, _, err := wfa.ResourceModelAccessor.Search(nil, wfa.GetType())
return utils.GenericLoadAll[*ComputeResource](func(d utils.DBObject, a []utils.ShallowDBObject) []utils.ShallowDBObject { return utils.GenericLoadAll[*ComputeResource](func(d utils.DBObject) utils.ShallowDBObject {
if err == nil && len(resources) > 0 { if err == nil && len(resources) > 0 {
d.(*ComputeResource).ResourceModel = resources[0].(*resource_model.ResourceModel) d.(*ComputeResource).ResourceModel = resources[0].(*resource_model.ResourceModel)
} }
a = append(a, d) // only get the abstract resource ! return d
return a
}, wfa) }, wfa)
} }
@ -66,11 +72,10 @@ func (wfa *computeMongoAccessor) Search(filters *dbs.Filters, search string) ([]
root := &ComputeResource{} root := &ComputeResource{}
resources, _, err := wfa.ResourceModelAccessor.Search(nil, wfa.GetType()) resources, _, err := wfa.ResourceModelAccessor.Search(nil, wfa.GetType())
return utils.GenericSearch[*ComputeResource](filters, search, root.GetResourceFilter(search), return utils.GenericSearch[*ComputeResource](filters, search, root.GetResourceFilter(search),
func(d utils.DBObject, a []utils.ShallowDBObject) []utils.ShallowDBObject { func(d utils.DBObject) utils.ShallowDBObject {
if err == nil && len(resources) > 0 { if err == nil && len(resources) > 0 {
d.(*ComputeResource).ResourceModel = resources[0].(*resource_model.ResourceModel) d.(*ComputeResource).ResourceModel = resources[0].(*resource_model.ResourceModel)
} }
a = append(a, d) // only get the abstract resource ! return d
return a
}, wfa) }, wfa)
} }

View File

@ -5,6 +5,7 @@ import (
"cloud.o-forge.io/core/oc-lib/models/resources/resource_model" "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/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -21,7 +22,7 @@ func TestStoreOneCompute(t *testing.T) {
}, },
} }
dcma := New("", nil) dcma := New(tools.COMPUTE_RESOURCE, "", nil, nil)
id, _, _ := dcma.StoreOne(&dc) id, _, _ := dcma.StoreOne(&dc)
assert.NotEmpty(t, id) assert.NotEmpty(t, id)
@ -39,7 +40,7 @@ func TestLoadOneCompute(t *testing.T) {
}, },
} }
dcma := New("", nil) dcma := New(tools.COMPUTE_RESOURCE, "", nil, nil)
new_dc, _, _ := dcma.StoreOne(&dc) new_dc, _, _ := dcma.StoreOne(&dc)
assert.Equal(t, dc, new_dc) assert.Equal(t, dc, new_dc)

View File

@ -38,7 +38,5 @@ type DataResource struct {
} }
func (d *DataResource) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor { func (d *DataResource) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
data := New() // Create a new instance of the accessor return New(tools.DATA_RESOURCE, peerID, groups, caller) // Create a new instance of the accessor
data.Init(tools.DATA_RESOURCE, peerID, groups, caller) // Initialize the accessor with the DATA_RESOURCE model type
return data
} }

View File

@ -5,8 +5,10 @@ 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/dbs/mongo" 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/resources/resource_model"
"cloud.o-forge.io/core/oc-lib/models/utils" "cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
) )
type dataMongoAccessor struct { type dataMongoAccessor struct {
@ -14,10 +16,15 @@ type dataMongoAccessor struct {
} }
// New creates a new instance of the dataMongoAccessor // New creates a new instance of the dataMongoAccessor
func New() *dataMongoAccessor { func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCaller) *dataMongoAccessor {
return &dataMongoAccessor{ return &dataMongoAccessor{
utils.AbstractAccessor{ utils.AbstractAccessor{
ResourceModelAccessor: resource_model.New(), 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(),
}, },
} }
} }

View File

@ -5,6 +5,7 @@ import (
"cloud.o-forge.io/core/oc-lib/models/resources/resource_model" "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/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -25,7 +26,7 @@ func TestStoreOneData(t *testing.T) {
}, },
} }
dma := New() dma := New(tools.DATA_RESOURCE, "", nil, nil)
id, _, _ := dma.StoreOne(&d) id, _, _ := dma.StoreOne(&d)
assert.NotEmpty(t, id) assert.NotEmpty(t, id)
@ -47,7 +48,7 @@ func TestLoadOneDate(t *testing.T) {
}, },
} }
dma := New() dma := New(tools.DATA_RESOURCE, "", nil, nil)
new_d, _, _ := dma.StoreOne(&d) new_d, _, _ := dma.StoreOne(&d)
assert.Equal(t, d, new_d) assert.Equal(t, d, new_d)
} }

View File

@ -40,7 +40,5 @@ type ProcessingResource struct {
} }
func (d *ProcessingResource) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor { func (d *ProcessingResource) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
data := New() // Create a new instance of the accessor return New(tools.PROCESSING_RESOURCE, peerID, groups, caller) // Create a new instance of the accessor
data.Init(tools.PROCESSING_RESOURCE, peerID, groups, caller) // Initialize the accessor with the PROCESSING_RESOURCE model type
return data
} }

View File

@ -5,19 +5,26 @@ import (
"cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/dbs"
"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/resources/resource_model"
"cloud.o-forge.io/core/oc-lib/models/utils" "cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
) )
type processingMongoAccessor struct { type processingMongoAccessor struct {
utils.AbstractAccessor // AbstractAccessor contains the basic fields of an accessor (model, caller) utils.AbstractAccessor // AbstractAccessor contains the basic fields of an accessor (model, caller)
} }
// New creates a new instance of the processingMongoAccessor // New creates a new instance of the storageMongoAccessor
func New() *processingMongoAccessor { func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCaller) *processingMongoAccessor {
return &processingMongoAccessor{ return &processingMongoAccessor{
utils.AbstractAccessor{ utils.AbstractAccessor{
ResourceModelAccessor: resource_model.New(), 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(),
}, },
} }
} }

View File

@ -144,9 +144,14 @@ func (abs *ResourceModel) VerifyAuth(peerID string, groups []string) bool {
} }
func (d *ResourceModel) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor { func (d *ResourceModel) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
data := &ResourceModelMongoAccessor{} return &ResourceModelMongoAccessor{
data.Init(tools.RESOURCE_MODEL, peerID, groups, caller) utils.AbstractAccessor{
return data Type: tools.RESOURCE_MODEL.String(),
PeerID: peerID,
Groups: groups,
Caller: caller,
},
}
} }
func (dma *ResourceModel) Deserialize(j map[string]interface{}, obj utils.DBObject) utils.DBObject { func (dma *ResourceModel) Deserialize(j map[string]interface{}, obj utils.DBObject) utils.DBObject {

View File

@ -57,7 +57,5 @@ type StorageResource struct {
} }
func (d *StorageResource) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor { func (d *StorageResource) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
data := New() // Create a new instance of the accessor return New(tools.STORAGE_RESOURCE, peerID, groups, caller) // Create a new instance of the accessor
data.Init(tools.STORAGE_RESOURCE, peerID, groups, caller) // Initialize the accessor with the STORAGE_RESOURCE model type
return data
} }

View File

@ -5,8 +5,10 @@ import (
"cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/dbs"
"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/resources/resource_model"
"cloud.o-forge.io/core/oc-lib/models/utils" "cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
) )
type storageMongoAccessor struct { type storageMongoAccessor struct {
@ -14,10 +16,15 @@ type storageMongoAccessor struct {
} }
// New creates a new instance of the storageMongoAccessor // New creates a new instance of the storageMongoAccessor
func New() *storageMongoAccessor { func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCaller) *storageMongoAccessor {
return &storageMongoAccessor{ return &storageMongoAccessor{
utils.AbstractAccessor{ utils.AbstractAccessor{
ResourceModelAccessor: resource_model.New(), 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(),
}, },
} }
} }

View File

@ -5,6 +5,7 @@ import (
"cloud.o-forge.io/core/oc-lib/models/resources/resource_model" "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/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -21,7 +22,7 @@ func TestStoreOneStorage(t *testing.T) {
}, },
} }
sma := New() sma := New(tools.STORAGE_RESOURCE, "peerID", []string{}, nil)
id, _, _ := sma.StoreOne(&s) id, _, _ := sma.StoreOne(&s)
assert.NotEmpty(t, id) assert.NotEmpty(t, id)
@ -39,7 +40,7 @@ func TestLoadOneStorage(t *testing.T) {
}, },
} }
sma := New() sma := New(tools.STORAGE_RESOURCE, "peerID", []string{}, nil)
new_s, _, _ := sma.StoreOne(&s) new_s, _, _ := sma.StoreOne(&s)
assert.Equal(t, s, new_s) assert.Equal(t, s, new_s)

View File

@ -14,7 +14,5 @@ type WorkflowResource struct {
} }
func (d *WorkflowResource) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor { func (d *WorkflowResource) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
data := New() // Create a new instance of the accessor return New(tools.WORKFLOW_RESOURCE, peerID, groups, caller) // Create a new instance of the accessor
data.Init(tools.WORKFLOW_RESOURCE, peerID, groups, caller) // Initialize the accessor with the WORKFLOW_RESOURCE model type
return data
} }

View File

@ -5,18 +5,25 @@ import (
"cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/dbs"
"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/resources/resource_model"
"cloud.o-forge.io/core/oc-lib/models/utils" "cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
) )
type workflowResourceMongoAccessor struct { type workflowResourceMongoAccessor struct {
utils.AbstractAccessor // AbstractAccessor contains the basic fields of an accessor (model, caller) utils.AbstractAccessor // AbstractAccessor contains the basic fields of an accessor (model, caller)
} }
func New() *workflowResourceMongoAccessor { func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCaller) *workflowResourceMongoAccessor {
return &workflowResourceMongoAccessor{ return &workflowResourceMongoAccessor{
utils.AbstractAccessor{ utils.AbstractAccessor{
ResourceModelAccessor: resource_model.New(), 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(),
}, },
} }
} }

View File

@ -5,6 +5,7 @@ import (
"cloud.o-forge.io/core/oc-lib/models/resources/resource_model" "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/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -20,7 +21,7 @@ func TestStoreOneWorkflow(t *testing.T) {
}, },
} }
wma := New() wma := New(tools.WORKFLOW_RESOURCE, "peerID", []string{}, nil)
id, _, _ := wma.StoreOne(&w) id, _, _ := wma.StoreOne(&w)
assert.NotEmpty(t, id) assert.NotEmpty(t, id)
@ -37,7 +38,7 @@ func TestLoadOneWorkflow(t *testing.T) {
}, },
} }
wma := New() wma := New(tools.WORKFLOW_RESOURCE, "peerID", []string{}, nil)
new_w, _, _ := wma.StoreOne(&w) new_w, _, _ := wma.StoreOne(&w)
assert.Equal(t, w, new_w) assert.Equal(t, w, new_w)
} }

View File

@ -7,11 +7,11 @@ import (
"cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/dbs"
"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/tools" "cloud.o-forge.io/core/oc-lib/tools"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/rs/zerolog" "github.com/rs/zerolog"
mgb "go.mongodb.org/mongo-driver/mongo"
) )
// single instance of the validator used in every model Struct to validate the fields // single instance of the validator used in every model Struct to validate the fields
@ -100,15 +100,6 @@ func (dma *AbstractAccessor) GetCaller() *tools.HTTPCaller {
return dma.Caller return dma.Caller
} }
// Init initializes the accessor with the data type and the http caller
func (dma *AbstractAccessor) Init(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCaller) {
dma.Logger = logs.CreateLogger(t.String()) // Create a logger with the data type
dma.Caller = caller
dma.PeerID = peerID
dma.Groups = groups // Set the caller
dma.Type = t.String() // Set the data type
}
// GenericLoadOne loads one object from the database (generic) // GenericLoadOne loads one object from the database (generic)
func (wfa *AbstractAccessor) GenericStoreOne(data DBObject, accessor Accessor) (DBObject, int, error) { func (wfa *AbstractAccessor) GenericStoreOne(data DBObject, accessor Accessor) (DBObject, int, error) {
data.GenerateID() data.GenerateID()
@ -189,48 +180,37 @@ func GenericLoadOne[T DBObject](id string, f func(DBObject) (DBObject, int, erro
return f(data) return f(data)
} }
func GenericLoadAll[T DBObject](f func(DBObject, []ShallowDBObject) []ShallowDBObject, wfa Accessor) ([]ShallowDBObject, int, error) { func genericLoadAll[T DBObject](res *mgb.Cursor, code int, err error, f func(DBObject) ShallowDBObject, wfa Accessor) ([]ShallowDBObject, int, error) {
results := []T{}
objs := []ShallowDBObject{} objs := []ShallowDBObject{}
res_mongo, code, err := mongo.MONGOService.LoadAll(wfa.GetType()) results := []T{}
if err != nil { if err != nil {
wfa.GetLogger().Error().Msg("Could not retrieve any from db. Error: " + err.Error()) wfa.GetLogger().Error().Msg("Could not retrieve any from db. Error: " + err.Error())
return nil, code, err return nil, code, err
} }
if err = res_mongo.All(mongo.MngoCtx, &results); err != nil { if err = res.All(mongo.MngoCtx, &results); err != nil {
return nil, 404, err return nil, 404, err
} }
for _, r := range results { for _, r := range results {
if !r.VerifyAuth(wfa.GetPeerID(), wfa.GetGroups()) { if !r.VerifyAuth(wfa.GetPeerID(), wfa.GetGroups()) {
continue continue
} }
objs = f(r, objs) objs = append(objs, f(r))
} }
return objs, 200, nil return objs, 200, nil
} }
func GenericLoadAll[T DBObject](f func(DBObject) ShallowDBObject, wfa Accessor) ([]ShallowDBObject, int, error) {
res_mongo, code, err := mongo.MONGOService.LoadAll(wfa.GetType())
return genericLoadAll[T](res_mongo, code, err, f, wfa)
}
func GenericSearch[T DBObject](filters *dbs.Filters, search string, defaultFilters *dbs.Filters, func GenericSearch[T DBObject](filters *dbs.Filters, search string, defaultFilters *dbs.Filters,
f func(DBObject, []ShallowDBObject) []ShallowDBObject, wfa Accessor) ([]ShallowDBObject, int, error) { f func(DBObject) ShallowDBObject, wfa Accessor) ([]ShallowDBObject, int, error) {
results := []T{}
objs := []ShallowDBObject{}
if (filters == nil || len(filters.And) == 0 || len(filters.Or) == 0) && search != "" { if (filters == nil || len(filters.And) == 0 || len(filters.Or) == 0) && search != "" {
filters = defaultFilters filters = defaultFilters
} }
res_mongo, code, err := mongo.MONGOService.Search(filters, wfa.GetType()) res_mongo, code, err := mongo.MONGOService.Search(filters, wfa.GetType())
if err != nil { return genericLoadAll[T](res_mongo, code, err, f, wfa)
wfa.GetLogger().Error().Msg("Could not store to db. Error: " + err.Error())
return nil, code, err
}
if err = res_mongo.All(mongo.MngoCtx, &results); err != nil {
return nil, 404, err
}
for _, r := range results {
if !r.VerifyAuth(wfa.GetPeerID(), wfa.GetGroups()) {
continue
}
objs = f(r, objs)
}
return objs, 200, nil
} }
// GenericLoadOne loads one object from the database (generic) // GenericLoadOne loads one object from the database (generic)

View File

@ -29,7 +29,6 @@ type DBObject interface {
// Accessor is an interface that defines the basic methods for an Accessor // Accessor is an interface that defines the basic methods for an Accessor
type Accessor interface { type Accessor interface {
Init(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCaller)
GetType() string GetType() string
GetPeerID() string GetPeerID() string
GetGroups() []string GetGroups() []string

View File

@ -129,7 +129,5 @@ func (wfa *Workflow) CheckBooking(caller *tools.HTTPCaller) (bool, error) {
} }
func (d *Workflow) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor { func (d *Workflow) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
data := New(peerID, groups) // Create a new instance of the accessor return New(tools.WORKFLOW, peerID, groups, caller) // Create a new instance of the accessor
data.Init(tools.WORKFLOW, peerID, groups, caller) // Initialize the accessor with the WORKFLOW model type
return data
} }

View File

@ -9,9 +9,7 @@ import (
type WorkflowHistory struct{ Workflow } type WorkflowHistory struct{ Workflow }
func (d *WorkflowHistory) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor { func (d *WorkflowHistory) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
data := New(peerID, groups) // Create a new instance of the accessor return New(tools.WORKSPACE_HISTORY, peerID, groups, caller) // Create a new instance of the accessor
data.Init(tools.WORKSPACE_HISTORY, peerID, groups, caller) // Initialize the accessor with the WORKSPACE model type
return data
} }
func (r *WorkflowHistory) GenerateID() { func (r *WorkflowHistory) GenerateID() {
r.UUID = uuid.New().String() r.UUID = uuid.New().String()

View File

@ -9,6 +9,7 @@ import (
"cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/dbs"
"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/collaborative_area/shallow_collaborative_area" "cloud.o-forge.io/core/oc-lib/models/collaborative_area/shallow_collaborative_area"
"cloud.o-forge.io/core/oc-lib/models/peer" "cloud.o-forge.io/core/oc-lib/models/peer"
"cloud.o-forge.io/core/oc-lib/models/resources" "cloud.o-forge.io/core/oc-lib/models/resources"
@ -30,12 +31,19 @@ type workflowMongoAccessor struct {
} }
// New creates a new instance of the workflowMongoAccessor // New creates a new instance of the workflowMongoAccessor
func New(peerID string, groups []string) *workflowMongoAccessor { func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCaller) *workflowMongoAccessor {
return &workflowMongoAccessor{ return &workflowMongoAccessor{
computeResourceAccessor: (&compute.ComputeResource{}).GetAccessor(peerID, groups, nil), computeResourceAccessor: (&compute.ComputeResource{}).GetAccessor(peerID, groups, nil),
collaborativeAreaAccessor: (&shallow_collaborative_area.ShallowCollaborativeArea{}).GetAccessor(peerID, groups, nil), collaborativeAreaAccessor: (&shallow_collaborative_area.ShallowCollaborativeArea{}).GetAccessor(peerID, groups, nil),
executionAccessor: (&workflow_execution.WorkflowExecution{}).GetAccessor(peerID, groups, nil), executionAccessor: (&workflow_execution.WorkflowExecution{}).GetAccessor(peerID, groups, nil),
workspaceAccessor: (&workspace.Workspace{}).GetAccessor(peerID, groups, nil), workspaceAccessor: (&workspace.Workspace{}).GetAccessor(peerID, groups, nil),
AbstractAccessor: utils.AbstractAccessor{
Logger: logs.CreateLogger(t.String()), // Create a logger with the data type
Caller: caller,
PeerID: peerID,
Groups: groups, // Set the caller
Type: t.String(),
},
} }
} }

View File

@ -4,6 +4,7 @@ import (
"testing" "testing"
"cloud.o-forge.io/core/oc-lib/models/utils" "cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -12,7 +13,7 @@ func TestStoreOneWorkflow(t *testing.T) {
AbstractObject: utils.AbstractObject{Name: "testWorkflow"}, AbstractObject: utils.AbstractObject{Name: "testWorkflow"},
} }
wma := New("", nil) wma := New(tools.WORKFLOW, "", nil, nil)
id, _, _ := wma.StoreOne(&w) id, _, _ := wma.StoreOne(&w)
assert.NotEmpty(t, id) assert.NotEmpty(t, id)
@ -23,7 +24,7 @@ func TestLoadOneWorkflow(t *testing.T) {
AbstractObject: utils.AbstractObject{Name: "testWorkflow"}, AbstractObject: utils.AbstractObject{Name: "testWorkflow"},
} }
wma := New("", nil) wma := New(tools.WORKFLOW, "", nil, nil)
new_w, _, _ := wma.StoreOne(&w) new_w, _, _ := wma.StoreOne(&w)
assert.Equal(t, w, new_w) assert.Equal(t, w, new_w)
} }

View File

@ -116,7 +116,5 @@ func (d *WorkflowExecution) GetName() string {
} }
func (d *WorkflowExecution) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor { func (d *WorkflowExecution) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
data := New() // Create a new instance of the accessor return New(tools.WORKFLOW_EXECUTION, peerID, groups, caller) // Create a new instance of the accessor
data.Init(tools.WORKFLOW_EXECUTION, peerID, groups, caller) // Initialize the accessor with the WORKFLOW_EXECUTION model type
return data
} }

View File

@ -5,15 +5,25 @@ import (
"cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/dbs"
"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/utils" "cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
) )
type workflowExecutionMongoAccessor struct { type workflowExecutionMongoAccessor struct {
utils.AbstractAccessor utils.AbstractAccessor
} }
func New() *workflowExecutionMongoAccessor { func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCaller) *workflowExecutionMongoAccessor {
return &workflowExecutionMongoAccessor{} return &workflowExecutionMongoAccessor{
utils.AbstractAccessor{
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 *workflowExecutionMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) { func (wfa *workflowExecutionMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) {

View File

@ -16,7 +16,5 @@ type Workspace struct {
} }
func (d *Workspace) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor { func (d *Workspace) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
data := New(peerID, groups) // Create a new instance of the accessor return New(tools.WORKSPACE, peerID, groups, caller) // Create a new instance of the accessor
data.Init(tools.WORKSPACE, peerID, groups, caller) // Initialize the accessor with the WORKSPACE model type
return data
} }

View File

@ -9,9 +9,7 @@ import (
type WorkspaceHistory struct{ Workspace } type WorkspaceHistory struct{ Workspace }
func (d *WorkspaceHistory) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor { func (d *WorkspaceHistory) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
data := New(peerID, groups) // Create a new instance of the accessor return New(tools.WORKFLOW_HISTORY, peerID, groups, caller) // Create a new instance of the accessor
data.Init(tools.WORKSPACE_HISTORY, peerID, groups, caller) // Initialize the accessor with the WORKSPACE model type
return data
} }
func (r *WorkspaceHistory) GenerateID() { func (r *WorkspaceHistory) GenerateID() {
r.UUID = uuid.New().String() r.UUID = uuid.New().String()

View File

@ -6,6 +6,7 @@ import (
"cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/dbs"
"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/collaborative_area/shallow_collaborative_area" "cloud.o-forge.io/core/oc-lib/models/collaborative_area/shallow_collaborative_area"
"cloud.o-forge.io/core/oc-lib/models/peer" "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/models/utils"
@ -18,8 +19,16 @@ type workspaceMongoAccessor struct {
} }
// New creates a new instance of the workspaceMongoAccessor // New creates a new instance of the workspaceMongoAccessor
func New(peerID string, groups []string) *workspaceMongoAccessor { func New(t tools.DataType, peerID string, groups []string, caller *tools.HTTPCaller) *workspaceMongoAccessor {
return &workspaceMongoAccessor{} return &workspaceMongoAccessor{
utils.AbstractAccessor{
Logger: logs.CreateLogger(t.String()), // Create a logger with the data type
Caller: caller,
PeerID: peerID,
Groups: groups, // Set the caller
Type: t.String(),
},
}
} }
// DeleteOne deletes a workspace from the database, given its ID, it automatically share to peers if the workspace is shared // DeleteOne deletes a workspace from the database, given its ID, it automatically share to peers if the workspace is shared