Workspace is the new space
This commit is contained in:
@@ -6,7 +6,9 @@ import (
|
||||
"strconv"
|
||||
|
||||
oclib "cloud.o-forge.io/core/oc-lib"
|
||||
"cloud.o-forge.io/core/oc-lib/models/workspace"
|
||||
"cloud.o-forge.io/core/oc-lib/tools"
|
||||
"oc-workspace/infrastructure"
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
)
|
||||
|
||||
@@ -53,18 +55,101 @@ func (o *WorkspaceController) Search() {
|
||||
// @Success 200 {workspace} models.workspace
|
||||
// @router /:id [put]
|
||||
func (o *WorkspaceController) Put() {
|
||||
//user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
|
||||
// store and return Id or post with UUID
|
||||
caller := tools.NewHTTPCaller(paths) // generate a http caller to send to peer shared workspace
|
||||
caller := tools.NewHTTPCaller(paths)
|
||||
caller.Disabled = oclib.IsQueryParamsEquals(o.Ctx.Input, "is_remote", true)
|
||||
var res map[string]interface{}
|
||||
id := o.Ctx.Input.Param(":id")
|
||||
json.Unmarshal(o.Ctx.Input.CopyBody(10000), &res)
|
||||
// o.Data["json"] = oclib.NewRequest(oclib.LibDataEnum(oclib.WORKSPACE), user, peerID, groups, caller).UpdateOne(res, id)
|
||||
json.Unmarshal(o.Ctx.Input.CopyBody(2000000), &res)
|
||||
|
||||
// Snapshot resource IDs before the update to detect additions and removals.
|
||||
oldResources := loadWorkspaceResourceMap(id)
|
||||
|
||||
o.Data["json"] = oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.WORKSPACE), caller).UpdateOne(res, id)
|
||||
|
||||
// Emit watch/unwatch events for resources that changed in this workspace.
|
||||
go diffAndEmitWatchers(oldResources, extractResourceMap(res))
|
||||
|
||||
o.ServeJSON()
|
||||
}
|
||||
|
||||
// resourceEntry holds the resource ID and its creator's libp2p PeerID.
|
||||
type resourceEntry struct {
|
||||
creatorPeerID string
|
||||
dataType tools.DataType
|
||||
}
|
||||
|
||||
// loadWorkspaceResourceMap returns the current resourceID→entry map for a workspace.
|
||||
func loadWorkspaceResourceMap(id string) map[string]resourceEntry {
|
||||
result := map[string]resourceEntry{}
|
||||
data := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.WORKSPACE), nil).LoadOne(id)
|
||||
if data.Data == nil {
|
||||
return result
|
||||
}
|
||||
w, ok := data.Data.(*workspace.Workspace)
|
||||
if !ok {
|
||||
return result
|
||||
}
|
||||
for _, r := range w.DataResources { result[r.GetID()] = resourceEntry{creatorPeerID: r.GetCreatorID(), dataType: tools.DATA_RESOURCE} }
|
||||
for _, r := range w.ComputeResources { result[r.GetID()] = resourceEntry{creatorPeerID: r.GetCreatorID(), dataType: tools.COMPUTE_RESOURCE} }
|
||||
for _, r := range w.StorageResources { result[r.GetID()] = resourceEntry{creatorPeerID: r.GetCreatorID(), dataType: tools.STORAGE_RESOURCE} }
|
||||
for _, r := range w.ProcessingResources { result[r.GetID()] = resourceEntry{creatorPeerID: r.GetCreatorID(), dataType: tools.PROCESSING_RESOURCE} }
|
||||
for _, r := range w.WorkflowResources { result[r.GetID()] = resourceEntry{creatorPeerID: r.GetCreatorID(), dataType: tools.WORKFLOW_RESOURCE} }
|
||||
for _, r := range w.ServiceResources { result[r.GetID()] = resourceEntry{creatorPeerID: r.GetCreatorID(), dataType: tools.SERVICE_RESOURCE} }
|
||||
for _, r := range w.DynamicResources { result[r.GetID()] = resourceEntry{creatorPeerID: r.GetCreatorID(), dataType: tools.DYNAMIC_RESOURCE} }
|
||||
for _, r := range w.NativeTools { result[r.GetID()] = resourceEntry{creatorPeerID: r.GetCreatorID(), dataType: tools.NATIVE_TOOL} }
|
||||
return result
|
||||
}
|
||||
|
||||
// extractResourceMap parses the PUT body to build a resourceID→entry map.
|
||||
// creator_id is at the top level of each resource object (from Flutter toJSON()).
|
||||
var resourceArrayKeys = map[string]tools.DataType{
|
||||
"data_resources": tools.DATA_RESOURCE,
|
||||
"compute_resources": tools.COMPUTE_RESOURCE,
|
||||
"storage_resources": tools.STORAGE_RESOURCE,
|
||||
"processing_resources": tools.PROCESSING_RESOURCE,
|
||||
"workflow_resources": tools.WORKFLOW_RESOURCE,
|
||||
"service_resources": tools.SERVICE_RESOURCE,
|
||||
"dynamic_resources": tools.DYNAMIC_RESOURCE,
|
||||
"native_tools": tools.NATIVE_TOOL,
|
||||
}
|
||||
|
||||
func extractResourceMap(body map[string]interface{}) map[string]resourceEntry {
|
||||
result := map[string]resourceEntry{}
|
||||
for key, dt := range resourceArrayKeys {
|
||||
arr, ok := body[key].([]interface{})
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
for _, rawR := range arr {
|
||||
r, ok := rawR.(map[string]interface{})
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
id, _ := r["id"].(string)
|
||||
creatorID, _ := r["creator_id"].(string)
|
||||
if id != "" {
|
||||
result[id] = resourceEntry{creatorPeerID: creatorID, dataType: dt}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// diffAndEmitWatchers emits PB_WATCH_RESOURCE for added non-self resources
|
||||
// and PB_UNWATCH_RESOURCE for removed ones.
|
||||
func diffAndEmitWatchers(old, new map[string]resourceEntry) {
|
||||
for id, entry := range new {
|
||||
if _, existed := old[id]; !existed {
|
||||
infrastructure.EmitWatchResource(id, entry.creatorPeerID, entry.dataType)
|
||||
}
|
||||
}
|
||||
for id, entry := range old {
|
||||
if _, stillPresent := new[id]; !stillPresent {
|
||||
infrastructure.EmitUnwatchResource(id, entry.creatorPeerID, entry.dataType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @Title Create
|
||||
// @Description create workspace
|
||||
// @Param data body json true "body for data content (Json format)"
|
||||
@@ -125,3 +210,4 @@ func (o *WorkspaceController) Delete() {
|
||||
o.Data["json"] = oclib.NewRequest(oclib.LibDataEnum(oclib.WORKSPACE), user, peerID, groups, caller).DeleteOne(id)
|
||||
o.ServeJSON()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user