added links models to workflow

This commit is contained in:
pb 2024-04-15 11:42:17 +02:00
parent ff9021b1ff
commit 64ae7eeb4c
2 changed files with 95 additions and 73 deletions

View File

@ -1,26 +1,34 @@
package models package models
import ( import (
"fmt" "cloud.o-forge.io/core/oc-catalog/models/rtype"
"reflect"
) )
type Link struct { type Link struct {
source string // ID primitive.ObjectID `json:"ID" bson:"_id" required:"true" example:"5099803df3f4948bd2f98391"`
destination string Source string `json:"source" description:"id in the workflow of the source object"`
dcLink bool Destination string `json:"destination" description:"id in the workflow of the destination object"`
DCLink bool `json:"dcLink" description:"is this a link with a datacenter"`
} }
func NewLink(src interface{}, dst interface{}) (link Link) { // Use ResourceObject parameter to process certain components type differently
// Check type with reflect and get ID // and Id's to identify each component as a node in an oriented graph
typeSrc := reflect.TypeOf(src)
typeDst := reflect.TypeOf(dst)
fmt.Println("src is %s\ndst is %s",typeSrc,typeDst) func NewLink(src ResourceObject, srcId string, dst ResourceObject, dstId string) (link Link) {
link.Source = srcId
link.Destination = dstId
if (src.getRtype() == rtype.DATACENTER || dst.getRtype() == rtype.DATACENTER){
link.DCLink = true
}
return return
} }
func (l *Link) AddLinkToDataCenter(component interface{}) { // So far only computing components expect the ID of the DC in their attributes
// if the component has a DataCenter id attribute then add it (switch on type) // func (l *Link) AddLinkToDataCenter(component models.ComputingModel) {
} // }

View File

@ -52,10 +52,11 @@ const SchedulesDB = "schedules"
type Workflow struct { type Workflow struct {
// The key of the map is the ID of the object itself // The key of the map is the ID of the object itself
Data map[string]DataObject `json:"data"` Data map[string]DataObject `json:"data"`
Computing map[string]ComputingObject `json:"computing"` Computing map[string]ComputingObject `json:"computing"`
Storage map[string]StorageObject `json:"storage"` Storage map[string]StorageObject `json:"storage"`
Datacenter map[string]DatacenterObject `json:"datacenter"` //TODO: Decide if there should be multiple objects of a datacenter Datacenter map[string]DatacenterObject `json:"datacenter"` //TODO: Decide if there should be multiple objects of a datacenter
Links map[string]Link `json:"link"`
Schedules WorkflowSchedule `json:"schedules"` Schedules WorkflowSchedule `json:"schedules"`
@ -181,6 +182,13 @@ func (w *Workflow) AddObj(robj ResourceObject) *primitive.ObjectID {
return &outputID return &outputID
} }
func (w *Workflow) AddLinkToWorkflow (link Link, id string){
if w.Links == nil {
w.Links = make(map[string]Link)
}
w.Links[id] = link
}
func (w *Workflow) UpdateDB(userID, workflowName string) error { func (w *Workflow) UpdateDB(userID, workflowName string) error {
_, err := services.MngoCollWorkspace.UpdateOne(services.MngoCtx, _, err := services.MngoCollWorkspace.UpdateOne(services.MngoCtx,
@ -543,9 +551,7 @@ func ParseMxGraph(username, workflowName, xmlData string) (err error, mxissues [
logs.Alert("Error creating links") logs.Alert("Error creating links")
return err, nil return err, nil
} }
// Move the attribute of the object's tags into the mxCell's for an easier processing
// currentWorkflow.extractMxCell(xmlModel)
targetWorkspaceWorkflow, err, mxissues := userWorkspace.ConsumeMxGraphModel(xmlModel) targetWorkspaceWorkflow, err, mxissues := userWorkspace.ConsumeMxGraphModel(xmlModel)
if err != nil { if err != nil {
@ -593,7 +599,6 @@ func FindSliceInSlice(slice1 []string, slice2 []string) (int, int, bool) {
return -1, -1, false return -1, -1, false
} }
// TODO : correct this method to suppport mxcells with settings
func (ws Workspace) ConsumeMxGraphModel(xmlmodel MxGraphModel) (returned_wf *Workflow, err error, issues []error) { func (ws Workspace) ConsumeMxGraphModel(xmlmodel MxGraphModel) (returned_wf *Workflow, err error, issues []error) {
returned_wf = &Workflow{} returned_wf = &Workflow{}
@ -648,62 +653,20 @@ func (ws Workspace) ConsumeMxGraphModel(xmlmodel MxGraphModel) (returned_wf *Wor
default: default:
// Not root nor resource. Should be only links // Not root nor resource. Should be only links
sourceObj := returned_wf.GetResource(cell.Source) // If is a invalid link, we can't save it in the DB
targetObj := returned_wf.GetResource(cell.Target) // We should always get a ID because we already registered resources and discarded which doesn't correspond to existent models
// save back
link := NewLink(sourceObj,targetObj) // If we have a relationship of:
_ = link // Source ----> Target
//
if sourceObj == nil || targetObj == nil { // The Source will be in the INPUTs of the Target.
if sourceObj == nil && targetObj == nil { // But we also must make sure that the Target will be in the OUTPUTs of the Source
issues = append(issues, errors.New("Arrow "+cell.ID+" is alone"))
} else if sourceObj == nil {
issues = append(issues, errors.New("Arrow ("+cell.ID+") to "+*targetObj.getName()+" without parent"))
} else {
issues = append(issues, errors.New("Arrow "+cell.ID+" from "+*sourceObj.getName()+" without target"))
}
// If is a invalid link, we can't save it in the DB
continue
}
if sourceObj.getRtype() == rtype.DATACENTER || targetObj.getRtype() == rtype.DATACENTER {
var datacenter, datacenterLinked *string
if sourceObj.getRtype() == rtype.DATACENTER {
datacenter = cell.Source
datacenterLinked = cell.Target
} else {
datacenter = cell.Target
datacenterLinked = cell.Source
}
switch returned_wf.GetResource(datacenterLinked).getRtype() {
case rtype.COMPUTING:
computingObj := returned_wf.GetResource(datacenterLinked).(*ComputingObject)
// We should always get a ID because we already registered resources and discarded which doesn't correspond to existent models
computingObj.DataCenterID = *datacenter
returned_wf.UpdateObj(computingObj, *datacenterLinked)
}
} else {
targetObj.addLink(INPUT, *cell.Source)
returned_wf.UpdateObj(targetObj, *cell.Target) // save back
// If we have a relationship of:
// Source ----> Target
//
// The Source will be in the INPUTs of the Target.
// But we also must make sure that the Target will be in the OUTPUTs of the Source
sourceObj.addLink(OUTPUT, *cell.Target)
returned_wf.UpdateObj(sourceObj, *cell.Source)
}
} }
} }
issues = ws.CreateLinks(returned_wf,xmlmodel.Root.MxLink, issues)
dcslist := make(map[string]bool) dcslist := make(map[string]bool)
dataslist := make(map[string]bool) dataslist := make(map[string]bool)
// datalist := make(map[string]bool) // datalist := make(map[string]bool)
@ -856,6 +819,57 @@ func (ws Workspace) ConsumeMxGraphModel(xmlmodel MxGraphModel) (returned_wf *Wor
return return
} }
func (w Workspace) CreateLinks(returned_wf *Workflow, links []MxLink, issues []error) []error {
for _, link := range links {
sourceObj := returned_wf.GetResource(&link.Source)
targetObj := returned_wf.GetResource(&link.Target)
link_object := NewLink(sourceObj,link.Source, targetObj, link.Target)
returned_wf.AddLinkToWorkflow(link_object,link.ID)
if sourceObj == nil || targetObj == nil {
if sourceObj == nil && targetObj == nil {
issues = append(issues, errors.New("Arrow "+link.ID +" is alone"))
} else if sourceObj == nil {
issues = append(issues, errors.New("Arrow ("+link.ID+") to "+*targetObj.getName()+" without parent"))
} else {
issues = append(issues, errors.New("Arrow "+link.ID+" from "+*sourceObj.getName()+" without target"))
}
}
// if sourceObj.getRtype() == rtype.DATACENTER || targetObj.getRtype() == rtype.DATACENTER {
// var datacenter, datacenterLinked *string
// if sourceObj.getRtype() == rtype.DATACENTER {
// datacenter = &link.Source
// datacenterLinked = &link.Target
// } else {
// datacenter = &link.Target
// datacenterLinked = &link.Source
// }
// switch returned_wf.GetResource(datacenterLinked).getRtype() {
// case rtype.COMPUTING:
// computingObj := returned_wf.GetResource(datacenterLinked).(*ComputingObject)
// computingObj.DataCenterID = *datacenter
// returned_wf.UpdateObj(computingObj, *datacenterLinked)
// }
// } else {
// targetObj.addLink(INPUT, *link.Source)
// returned_wf.UpdateObj(targetObj, *link.Target)
// sourceObj.addLink(OUTPUT, *link.Target)
// returned_wf.UpdateObj(sourceObj, *link.Source)
// }
}
return issues
}
func sumExecutionReqs(exeqReq ...ExecutionRequirementsModel) (ret ExecutionRequirementsModel) { func sumExecutionReqs(exeqReq ...ExecutionRequirementsModel) (ret ExecutionRequirementsModel) {
for _, v := range exeqReq { for _, v := range exeqReq {
ret.CPUs += v.CPUs ret.CPUs += v.CPUs