update the object stored for one workflow with user input
This commit is contained in:
		@@ -1,11 +1,13 @@
 | 
			
		||||
package models
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/xml"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"cloud.o-forge.io/core/oc-catalog/models/rtype"
 | 
			
		||||
	"cloud.o-forge.io/core/oc-catalog/services"
 | 
			
		||||
	structtomap "github.com/Klathmon/StructToMap"
 | 
			
		||||
	"github.com/beego/beego/v2/core/logs"
 | 
			
		||||
	"go.mongodb.org/mongo-driver/bson/primitive"
 | 
			
		||||
)
 | 
			
		||||
@@ -35,21 +37,21 @@ type ComputingNEWModel struct {
 | 
			
		||||
	ShortDescription string `json:"short_description,omitempty" required:"true" validate:"required"`
 | 
			
		||||
	Logo             string `json:"logo,omitempty" required:"true" validate:"required"`
 | 
			
		||||
 | 
			
		||||
	// Type    string `json:"type,omitempty" required:"true"`
 | 
			
		||||
	Type    string `json:"type,omitempty" required:"true"`
 | 
			
		||||
	Owner   string `json:"owner,omitempty"`
 | 
			
		||||
	License string `json:"license,omitempty"`
 | 
			
		||||
	Price   uint   `json:"price,omitempty"`
 | 
			
		||||
 | 
			
		||||
	ExecutionRequirements ExecutionRequirementsModel `json:"execution_requirements,omitempty"`
 | 
			
		||||
 | 
			
		||||
	// Dinputs  []string `json:"dinputs,omitempty"`		// Possibly redundant with Links object	in oc-schedule
 | 
			
		||||
	// Doutputs []string `json:"doutputs,omitempty"`		// Possibly redundant with Links objects in oc-schedule
 | 
			
		||||
	Dinputs  []string `json:"dinputs,omitempty"`		// Possibly redundant with Links object	in oc-schedule
 | 
			
		||||
	Doutputs []string `json:"doutputs,omitempty"`		// Possibly redundant with Links objects in oc-schedule
 | 
			
		||||
 | 
			
		||||
	Image       string   `json:"image,omitempty"`
 | 
			
		||||
	Command     string   `json:"command,omitempty"`
 | 
			
		||||
	Arguments   []string `json:"arguments,omitempty"`
 | 
			
		||||
	Environment []string `json:"environment,omitempty"`
 | 
			
		||||
	// Ports       []string `json:"ports,omitempty"`
 | 
			
		||||
	Ports       []string `json:"ports,omitempty"`
 | 
			
		||||
 | 
			
		||||
	// CustomDeployment string `json:"custom_deployment,omitempty"`
 | 
			
		||||
 | 
			
		||||
@@ -77,6 +79,11 @@ type ComputingObject struct {
 | 
			
		||||
 | 
			
		||||
	Inputs  []string `json:"inputs"`
 | 
			
		||||
	Outputs []string `json:"outputs"`
 | 
			
		||||
	Image       string   `json:"image,omitempty"`
 | 
			
		||||
	Command     string   `json:"command,omitempty"`
 | 
			
		||||
	Arguments   []string `json:"arguments,omitempty"`
 | 
			
		||||
	Environment []string `json:"environment,omitempty"`
 | 
			
		||||
	Ports       []string `json:"ports,omitempty"`
 | 
			
		||||
 | 
			
		||||
	DataCenterID string `json:"datacenterID" description:"Datacenter where the computing will be executed"`
 | 
			
		||||
}
 | 
			
		||||
@@ -174,19 +181,42 @@ func PostOneComputing(obj ComputingNEWModel) (ID string, err error) {
 | 
			
		||||
	return postOneResource(obj, rtype.COMPUTING)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (obj ComputingModel) AddUserInput(inputs map[string]interface{} ){
 | 
			
		||||
func (obj *ComputingObject) AddUserInput(inputs []xml.Attr){
 | 
			
		||||
	// So far only a few input to handle so a switch with a case for each type of attribute
 | 
			
		||||
	// is enough, to prevent too much complexity
 | 
			
		||||
	for key, value := range inputs {
 | 
			
		||||
		switch strings.ToLower(key) {
 | 
			
		||||
	
 | 
			
		||||
	for _, j := range(inputs){
 | 
			
		||||
		setting, _ := structtomap.Convert(j)
 | 
			
		||||
		// fmt.Println(strings.ToLower(setting["Name"]))
 | 
			
		||||
		name := setting["Name"].(xml.Name).Local
 | 
			
		||||
		value := setting["Value"]
 | 
			
		||||
		switch name {
 | 
			
		||||
		case "command":
 | 
			
		||||
			obj.Command = value.(string)
 | 
			
		||||
		case "arguments":
 | 
			
		||||
			obj.Arguments = value.([]string)
 | 
			
		||||
		case "args":
 | 
			
		||||
			empty, sliced_arguments := getSliceSettings(value.(string))
 | 
			
		||||
			if (!empty){
 | 
			
		||||
				obj.Arguments = sliced_arguments
 | 
			
		||||
			}
 | 
			
		||||
		case "env" :
 | 
			
		||||
			obj.Environment = value.([]string)
 | 
			
		||||
			empty, sliced_arguments := getSliceSettings(value.(string))
 | 
			
		||||
			if (!empty){
 | 
			
		||||
				obj.Environment = sliced_arguments
 | 
			
		||||
			}
 | 
			
		||||
		default:
 | 
			
		||||
			logs.Alert(fmt.Printf("%s is not an attribute of storage componants", key))
 | 
			
		||||
			logs.Alert(fmt.Printf("%s is not an attribute of computing componants", name))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getSliceSettings(string_to_parse string)(empty bool, sliced_string []string){
 | 
			
		||||
	if len(string_to_parse) == 0 {
 | 
			
		||||
		return true, nil
 | 
			
		||||
 	}
 | 
			
		||||
	empty = false	
 | 
			
		||||
	sliced_string = strings.Split(string_to_parse," ")
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
@@ -2,6 +2,7 @@ package models
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/xml"
 | 
			
		||||
	"strconv"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type MxGraphModel struct {
 | 
			
		||||
@@ -43,3 +44,18 @@ func (m *mxissue) Error() string {
 | 
			
		||||
func newMxIssue(message string) error {
 | 
			
		||||
	return &mxissue{message}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// mxCell inside object tags are create twice when unmarshalling
 | 
			
		||||
// once as they appear in the xml inside the MxObject struct and once in the MxCell struct
 | 
			
		||||
// so once retrieved from object we remove them from the root's MxCell list
 | 
			
		||||
func (m *MxGraphModel) removeMxCell(id string){
 | 
			
		||||
	int_id,_ := strconv.Atoi(id)
 | 
			
		||||
	int_id = int_id + 1
 | 
			
		||||
	cell_id := strconv.Itoa(int_id)
 | 
			
		||||
 | 
			
		||||
	for i, cell := range(m.Root.MxCell){
 | 
			
		||||
		if cell.ID == cell_id {
 | 
			
		||||
			m.Root.MxCell = append(m.Root.MxCell[:i],m.Root.MxCell[i+1:]...)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -4,6 +4,7 @@ import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"encoding/xml"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"os"
 | 
			
		||||
	"sort"
 | 
			
		||||
@@ -73,7 +74,7 @@ type ResourceObject interface {
 | 
			
		||||
	addLink(direction LinkingState, rObjID string)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// This type allows to process computing and storage componant
 | 
			
		||||
// This type allows to process computing and storage component
 | 
			
		||||
// which can get input from the user
 | 
			
		||||
type EditableResourceObject interface{
 | 
			
		||||
	ResourceObject
 | 
			
		||||
@@ -600,10 +601,10 @@ func (ws Workspace) ConsumeMxGraphModel(xmlmodel MxGraphModel) (returned_wf *Wor
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// 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
 | 
			
		||||
			// retrieve the componant's type
 | 
			
		||||
		// in the case cell has a rID retrieve its rType from the value of rID of the component in the worfklow
 | 
			
		||||
			// retrieve the component's type
 | 
			
		||||
			// create an object from the rType
 | 
			
		||||
			// update the existing workflow with the new componant
 | 
			
		||||
			// update the existing workflow with the new component
 | 
			
		||||
		// or by defautlt : the cell represents an arrow
 | 
			
		||||
			// if the source or the target of the arrow is a datacenter
 | 
			
		||||
				// define which end of the arrow is the DC
 | 
			
		||||
@@ -614,18 +615,26 @@ func (ws Workspace) ConsumeMxGraphModel(xmlmodel MxGraphModel) (returned_wf *Wor
 | 
			
		||||
	
 | 
			
		||||
	for _, object := range *xmlmodel.Root.MxObject{
 | 
			
		||||
 | 
			
		||||
		resObj, err, mxissues := returned_wf.mxCellToComponant(object.MxCell,ws)
 | 
			
		||||
		resObj, err, mxissues := returned_wf.mxCellToComponent(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
 | 
			
		||||
		// add the component to the worflow's attribute that stores
 | 
			
		||||
		// all components in a map[string]Component where the key
 | 
			
		||||
		// is the component's ID in the mxGraph and the value the Component object 
 | 
			
		||||
		returned_wf.UpdateObj(resObj,object.ID)
 | 
			
		||||
		xmlmodel.removeMxCell(object.ID)
 | 
			
		||||
 | 
			
		||||
		// Construct the object corresponding to the componant's type and use its addUserInput method
 | 
			
		||||
		if(resObj.getRtype() == rtype.COMPUTING){
 | 
			
		||||
			comp_obj := returned_wf.GetResource(&object.ID).(*ComputingObject)
 | 
			
		||||
			comp_obj.AddUserInput(object.Settings)
 | 
			
		||||
			returned_wf.UpdateObj(comp_obj,object.ID)
 | 
			
		||||
		}
 | 
			
		||||
		// if(resObj.getRtype() == rtype.DATA){
 | 
			
		||||
		fmt.Printf("Test")
 | 
			
		||||
		// }
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
@@ -633,7 +642,7 @@ func (ws Workspace) ConsumeMxGraphModel(xmlmodel MxGraphModel) (returned_wf *Wor
 | 
			
		||||
 | 
			
		||||
		switch {
 | 
			
		||||
		case cell.RID != nil:
 | 
			
		||||
			resObj, err, mxissues := returned_wf.mxCellToComponant(cell,ws)
 | 
			
		||||
			resObj, err, mxissues := returned_wf.mxCellToComponent(cell,ws)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				issues = append(issues, mxissues...)
 | 
			
		||||
			}
 | 
			
		||||
@@ -705,7 +714,7 @@ func (ws Workspace) ConsumeMxGraphModel(xmlmodel MxGraphModel) (returned_wf *Wor
 | 
			
		||||
	// datalist := make(map[string]bool)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// Test wether the computing componants are linked with a DC
 | 
			
		||||
	// Test wether the computing components are linked with a DC
 | 
			
		||||
	for _, comp := range returned_wf.Computing {
 | 
			
		||||
		if comp.DataCenterID == "" {
 | 
			
		||||
			issues = append(issues, errors.New("Computing "+*comp.getName()+" without a Datacenter"))
 | 
			
		||||
@@ -1041,7 +1050,7 @@ func CheckAndBookWorkflowSchedule(username, workflowName string, book bool) (myR
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Not sure if this method handles error propagation well 
 | 
			
		||||
func (wf Workflow) mxCellToComponant(cell MxCell, ws Workspace) (resObj ResourceObject,err error, issues []error){
 | 
			
		||||
func (wf Workflow) mxCellToComponent(cell MxCell, ws Workspace) (resObj ResourceObject,err error, issues []error){
 | 
			
		||||
	rType := ws.getRtype(*cell.RID)
 | 
			
		||||
 | 
			
		||||
	if rType == rtype.INVALID {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user