Retrieve component from mxCell inside object tag

This commit is contained in:
pb 2024-03-28 14:43:33 +01:00
parent 83c3c3d3f2
commit 49d3ba9763
2 changed files with 103 additions and 25 deletions

View File

@ -8,8 +8,9 @@ type MxGraphModel struct {
XMLName xml.Name `xml:"mxGraphModel"` XMLName xml.Name `xml:"mxGraphModel"`
Root struct { Root struct {
XMLName xml.Name `xml:"root"` XMLName xml.Name `xml:"root"`
MxCell []MxCell `xml:"mxCell"` MxCell []MxCell `xml:"mxCell"`
MxObject *[]MxObject `xml:"object"`
} }
} }
@ -20,6 +21,15 @@ type MxCell struct {
RID *string `xml:"rID,attr"` RID *string `xml:"rID,attr"`
Source *string `xml:"source,attr"` Source *string `xml:"source,attr"`
Target *string `xml:"target,attr"` Target *string `xml:"target,attr"`
Rtype *string `xml:"rType,attr"`
}
type MxObject struct {
XMLName xml.Name `xml:"object"`
ID string `xml:"id,attr"`
Settings []xml.Attr `xml:",any,attr"`
MxCell MxCell `xml:"mxCell"`
} }
type mxissue struct { type mxissue struct {

View File

@ -4,6 +4,8 @@ import (
"context" "context"
"encoding/xml" "encoding/xml"
"errors" "errors"
"net/url"
"os"
"sort" "sort"
"time" "time"
@ -71,18 +73,25 @@ type ResourceObject interface {
addLink(direction LinkingState, rObjID string) addLink(direction LinkingState, rObjID string)
} }
// This type allows to process computing and storage componant
// which can get input from the user
type EditableResourceObject interface{
ResourceObject
addUserInput(map[string]interface{})
}
// Get a sum of all execution requirements attached to a DC obj // Get a sum of all execution requirements attached to a DC obj
func (w Workflow) GetExecutionRequirements(dcIDobj string) (ret ExecutionRequirementsModel, err error) { func (wf Workflow) GetExecutionRequirements(dcIDobj string) (ret ExecutionRequirementsModel, err error) {
// Find the id of the DC obj // Find the id of the DC obj
if _, ok := w.Datacenter[dcIDobj]; !ok { if _, ok := wf.Datacenter[dcIDobj]; !ok {
return ExecutionRequirementsModel{}, errors.New("DC obj" + dcIDobj + " doesn't exist in the Workflow") return ExecutionRequirementsModel{}, errors.New("DC obj" + dcIDobj + " doesn't exist in the Workflow")
} }
// Get all elements that are attached to the DC // Get all elements that are attached to the DC
for _, computingObj := range w.Computing { for _, computingObj := range wf.Computing {
if computingObj.DataCenterID == dcIDobj { if computingObj.DataCenterID == dcIDobj {
mymodel, err := computingObj.getModel() mymodel, err := computingObj.getModel()
if err != nil { if err != nil {
@ -159,6 +168,7 @@ func (w *Workflow) CreateResourceObject(rt rtype.Rtype) ResourceObject {
default: default:
res = nil res = nil
} }
return res return res
} }
@ -510,6 +520,14 @@ func ParseMxGraph(username, workflowName, xmlData string) (err error, mxissues [
//return errors.New("Can't modify a booked workflow"), nil //return errors.New("Can't modify a booked workflow"), nil
} }
decodedValue, err := url.QueryUnescape(xmlData)
if err != nil {
return err, nil
}
// TEMPORARY test the xml created
os.WriteFile("graph.xml", []byte(decodedValue), 0660)
var xmlModel MxGraphModel var xmlModel MxGraphModel
// logs.Debug(xmlData) // logs.Debug(xmlData)
@ -518,13 +536,17 @@ func ParseMxGraph(username, workflowName, xmlData string) (err error, mxissues [
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 {
return err, nil return err, nil
} }
targetWorkspaceWorkflow.MxgraphXML = xmlData targetWorkspaceWorkflow.MxgraphXML = xmlData
targetWorkspaceWorkflow.Schedules = currentWorkflow.Schedules //TODO: Probably we should move schudles outside the workflow targetWorkspaceWorkflow.Schedules = currentWorkflow.Schedules //TODO: Probably we should move schedules outside the workflow
_, err = services.MngoCollWorkspace.UpdateOne(services.MngoCtx, _, err = services.MngoCollWorkspace.UpdateOne(services.MngoCtx,
primitive.M{"_id": username}, primitive.M{"_id": username},
@ -564,7 +586,8 @@ func FindSliceInSlice(slice1 []string, slice2 []string) (int, int, bool) {
return -1, -1, false return -1, -1, false
} }
func (w Workspace) ConsumeMxGraphModel(xmlmodel MxGraphModel) (returned_wf *Workflow, err error, issues []error) { // TODO : correct this method to suppport mxcells with settings
func (ws Workspace) ConsumeMxGraphModel(xmlmodel MxGraphModel) (returned_wf *Workflow, err error, issues []error) {
returned_wf = &Workflow{} returned_wf = &Workflow{}
@ -574,6 +597,8 @@ func (w Workspace) ConsumeMxGraphModel(xmlmodel MxGraphModel) (returned_wf *Work
return xmlmodel.Root.MxCell[i].RID != nil return xmlmodel.Root.MxCell[i].RID != nil
}) })
// For each cell of the xml graph, // For each cell of the xml graph,
// in the case cell has a rID retrieve its rType from the value of rID of the componant in the worfklow // in the case cell has a rID retrieve its rType from the value of rID of the componant in the worfklow
// retrieve the componant's type // retrieve the componant's type
@ -586,30 +611,33 @@ func (w Workspace) ConsumeMxGraphModel(xmlmodel MxGraphModel) (returned_wf *Work
// create a computing object // create a computing object
// attach the DC to it // attach the DC to it
// update the workflow with the object : create the list of this type of component or update the list with the id of the component with the object // update the workflow with the object : create the list of this type of component or update the list with the id of the component with the object
for _, object := range *xmlmodel.Root.MxObject{
resObj, err, mxissues := returned_wf.mxCellToComponant(object.MxCell,ws)
if err != nil {
issues = append(issues, mxissues...)
}
returned_wf.UpdateObj(resObj,object.ID)
// // retrieve the rType in the mxCell
// rType := w.getRtype(*object.MxCell.RID)
// // create a composant and add it to the appropriate list
// resObj := returned_wf.CreateResourceObject(rType)
// // use the addUserInput method with a map[string]string made of the
// resObj
}
for _, cell := range xmlmodel.Root.MxCell { for _, cell := range xmlmodel.Root.MxCell {
switch { switch {
case cell.RID != nil: case cell.RID != nil:
// Case of a Resource resObj, err, mxissues := returned_wf.mxCellToComponant(cell,ws)
rType := w.getRtype(*cell.RID)
if rType == rtype.INVALID {
return nil,
errors.New("Refering to a rID that is not in the workflow"),
nil
}
// Generate ObjectID for the reference ID
rIDObj, err := primitive.ObjectIDFromHex(*cell.RID)
if err != nil { if err != nil {
return nil, issues = append(issues, mxissues...)
errors.New("Bad ID format: " + *cell.RID),
nil
} }
resObj := returned_wf.CreateResourceObject(rType)
resObj.setReference(rIDObj)
returned_wf.UpdateObj(resObj, cell.ID) returned_wf.UpdateObj(resObj, cell.ID)
case cell.ID == "0" || cell.ID == "1": case cell.ID == "0" || cell.ID == "1":
@ -1005,9 +1033,49 @@ func CheckAndBookWorkflowSchedule(username, workflowName string, book bool) (myR
SchedulesDB: &currentWorkflow.Schedules}}, SchedulesDB: &currentWorkflow.Schedules}},
) )
if err != nil { if err != nil {
logs.Critical("Internal error when updating in DB: " + err.Error()) logs.Critical("Internal error when updating in DB: " + err.Error())
} }
return myRet, nil return myRet, nil
} }
// Not sure if this method handles error propagation well
func (wf Workflow) mxCellToComponant(cell MxCell, ws Workspace) (resObj ResourceObject,err error, issues []error){
rType := ws.getRtype(*cell.RID)
if rType == rtype.INVALID {
return nil,
errors.New("Refering to a rID that is not in the workflow"),
nil
}
// Generate ObjectID for the reference ID
rIDObj, err := primitive.ObjectIDFromHex(*cell.RID)
if err != nil {
return nil,
errors.New("Bad ID format: " + *cell.RID),
nil
}
resObj = wf.CreateResourceObject(rType)
resObj.setReference(rIDObj)
return
}
// func (ws Workspace) extractMxCell(xmlModel MxGraphModel){
// // Iterate through all objects of the MxGraph
// graphObjects := xmlModel.Root.MxObject
// for _, object := range(*graphObjects){
// current_obj_id, _ := strconv.Atoi(object.ID)
// inside_cell_id := strconv.Itoa(current_obj_id + 1)
// cell := ws.GetResource(&inside_cell_id)
// // component := w.GetResource(cell.RID)
// fmt.Print(cell)
// }
// // Extract the mxCell object
// // Invoke the addParameter method from the component
// // Edit the ID to get the object's one
// }