Files
oc-workspace/controllers/workspace.go
T

214 lines
8.6 KiB
Go
Raw Normal View History

2024-07-26 10:37:13 +02:00
package controllers
import (
"encoding/json"
2026-02-20 10:31:58 +01:00
"fmt"
2026-05-28 08:48:02 +02:00
"strconv"
2024-07-26 10:37:13 +02:00
oclib "cloud.o-forge.io/core/oc-lib"
2026-06-22 07:41:32 +02:00
"cloud.o-forge.io/core/oc-lib/models/workspace"
2024-08-30 10:19:40 +02:00
"cloud.o-forge.io/core/oc-lib/tools"
2026-06-22 07:41:32 +02:00
"oc-workspace/infrastructure"
2024-07-26 10:37:13 +02:00
beego "github.com/beego/beego/v2/server/web"
)
// Operations about workspace
type WorkspaceController struct {
beego.Controller
}
2024-10-02 14:15:58 +02:00
var paths = map[tools.DataType]map[tools.METHOD]string{
tools.PEER: { // paths to call to status of peers
2024-10-15 10:56:39 +02:00
tools.POST: "/status/",
2024-10-02 14:15:58 +02:00
},
tools.WORKSPACE: { // paths to call to delete/update workspace on peer destination
2024-10-15 10:56:39 +02:00
tools.PUT: "/:id?is_remote=true",
tools.DELETE: "/:id?is_remote=true",
2024-10-02 14:15:58 +02:00
},
}
2024-08-08 08:38:40 +02:00
// @Title Search
// @Description search workspace
// @Param search path string true "the word search you want to get"
2025-01-17 17:18:29 +01:00
// @Param is_draft query string false "draft wished"
2026-05-28 08:48:02 +02:00
// @Param offset query string false "offset wished"
// @Param limit query string false "limit wished"
2024-08-08 08:38:40 +02:00
// @Success 200 {workspace} models.workspace
// @router /search/:search [get]
func (o *WorkspaceController) Search() {
2026-02-20 10:31:58 +01:00
// user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
2024-08-08 08:38:40 +02:00
// store and return Id or post with UUID
search := o.Ctx.Input.Param(":search")
2025-01-17 17:18:29 +01:00
isDraft := o.Ctx.Input.Query("is_draft")
2026-05-28 08:48:02 +02:00
offset, _ := strconv.Atoi(o.Ctx.Input.Query("offset"))
limit, _ := strconv.Atoi(o.Ctx.Input.Query("limit"))
2026-02-20 10:31:58 +01:00
// o.Data["json"] = oclib.NewRequest(oclib.LibDataEnum(oclib.WORKSPACE), user, peerID, groups, nil).Search(nil, search, isDraft == "true")
2026-05-28 08:48:02 +02:00
o.Data["json"] = oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.WORKSPACE), nil).Search(nil, search, isDraft == "true", int64(offset), int64(limit))
2026-02-20 10:31:58 +01:00
2024-08-08 08:38:40 +02:00
o.ServeJSON()
}
2024-07-26 10:37:13 +02:00
// @Title Update
// @Description create workspaces
// @Param id path string true "the workspace id you want to get"
// @Param body body models.workspace true "The workspace content"
// @Success 200 {workspace} models.workspace
// @router /:id [put]
func (o *WorkspaceController) Put() {
2026-06-22 07:41:32 +02:00
caller := tools.NewHTTPCaller(paths)
2024-10-02 14:15:58 +02:00
caller.Disabled = oclib.IsQueryParamsEquals(o.Ctx.Input, "is_remote", true)
2024-07-26 10:37:13 +02:00
var res map[string]interface{}
id := o.Ctx.Input.Param(":id")
2026-06-22 07:41:32 +02:00
json.Unmarshal(o.Ctx.Input.CopyBody(2000000), &res)
// Snapshot resource IDs before the update to detect additions and removals.
oldResources := loadWorkspaceResourceMap(id)
2026-02-20 10:31:58 +01:00
o.Data["json"] = oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.WORKSPACE), caller).UpdateOne(res, id)
2026-06-22 07:41:32 +02:00
// Emit watch/unwatch events for resources that changed in this workspace.
go diffAndEmitWatchers(oldResources, extractResourceMap(res))
2024-07-26 10:37:13 +02:00
o.ServeJSON()
}
2026-06-22 07:41:32 +02:00
// 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)
}
}
}
2024-07-26 10:37:13 +02:00
// @Title Create
// @Description create workspace
// @Param data body json true "body for data content (Json format)"
// @Success 200 {workspace} models.workspace
// @router / [post]
func (o *WorkspaceController) Post() {
2026-02-20 10:31:58 +01:00
// user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
2024-08-30 16:00:49 +02:00
caller := tools.NewHTTPCaller(paths) // generate a http caller to send to peer shared workspace
2024-10-02 14:15:58 +02:00
caller.Disabled = oclib.IsQueryParamsEquals(o.Ctx.Input, "is_remote", true)
2024-07-26 10:37:13 +02:00
var res map[string]interface{}
json.Unmarshal(o.Ctx.Input.CopyBody(10000), &res)
2026-02-20 10:31:58 +01:00
// o.Data["json"] = oclib.NewRequest(oclib.LibDataEnum(oclib.WORKSPACE), user, peerID, groups, caller).StoreOne(res)
o.Data["json"] = oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.WORKSPACE), caller).StoreOne(res)
2024-07-26 10:37:13 +02:00
o.ServeJSON()
}
// @Title GetAll
// @Description find workspace by id
2025-01-17 17:18:29 +01:00
// @Param is_draft query string false "draft wished"
2026-05-28 08:48:02 +02:00
// @Param offset query string false "offset wished"
// @Param limit query string false "limit wished"
2024-07-26 10:37:13 +02:00
// @Success 200 {workspace} models.workspace
// @router / [get]
func (o *WorkspaceController) GetAll() {
2025-01-17 17:18:29 +01:00
user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
2026-02-20 10:31:58 +01:00
fmt.Println(user, peerID, groups)
2025-01-17 17:18:29 +01:00
isDraft := o.Ctx.Input.Query("is_draft")
2026-02-20 10:31:58 +01:00
// o.Data["json"] = oclib.NewRequest(oclib.LibDataEnum(oclib.WORKSPACE), user, peerID, groups, nil).LoadAll(isDraft == "true")
2026-05-28 08:48:02 +02:00
offset, _ := strconv.Atoi(o.Ctx.Input.Query("offset"))
limit, _ := strconv.Atoi(o.Ctx.Input.Query("limit"))
o.Data["json"] = oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.WORKSPACE), nil).LoadAll(isDraft == "true", int64(offset), int64(limit))
2024-07-26 10:37:13 +02:00
o.ServeJSON()
}
// @Title Get
2025-01-17 17:18:29 +01:00
// @Description find workflow by idisDraft := o.Ctx.Input.Query("is_draft")
2024-07-26 10:37:13 +02:00
// @Param id path string true "the id you want to get"
// @Success 200 {workspace} models.workspace
// @router /:id [get]
func (o *WorkspaceController) Get() {
2026-02-20 10:31:58 +01:00
//user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
2024-07-26 10:37:13 +02:00
id := o.Ctx.Input.Param(":id")
2026-02-20 10:31:58 +01:00
// o.Data["json"] = oclib.NewRequest(oclib.LibDataEnum(oclib.WORKSPACE), user, peerID, groups, nil).LoadOne(id)
o.Data["json"] = oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.WORKSPACE), nil).LoadOne(id)
2024-07-26 10:37:13 +02:00
o.ServeJSON()
}
// @Title Delete
// @Description delete the workspace
// @Param id path string true "The id you want to delete"
// @Success 200 {workspace} delete success!
// @router /:id [delete]
func (o *WorkspaceController) Delete() {
2025-01-17 17:18:29 +01:00
user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
2024-07-26 10:37:13 +02:00
id := o.Ctx.Input.Param(":id")
2024-08-30 10:19:40 +02:00
caller := tools.NewHTTPCaller(paths) // generate a http caller to send to peer shared workspace
2024-10-02 14:15:58 +02:00
caller.Disabled = oclib.IsQueryParamsEquals(o.Ctx.Input, "is_remote", true)
2025-01-17 17:18:29 +01:00
o.Data["json"] = oclib.NewRequest(oclib.LibDataEnum(oclib.WORKSPACE), user, peerID, groups, caller).DeleteOne(id)
2024-07-26 10:37:13 +02:00
o.ServeJSON()
}
2026-06-22 07:41:32 +02:00