bugfix empty workflow
This commit is contained in:
		@@ -78,7 +78,7 @@ type ResourceObject interface {
 | 
			
		||||
 | 
			
		||||
// This type allows to process computing and storage component
 | 
			
		||||
// which can get input from the user
 | 
			
		||||
type EditableResourceObject interface{
 | 
			
		||||
type EditableResourceObject interface {
 | 
			
		||||
	ResourceObject
 | 
			
		||||
	addUserInput(map[string]interface{})
 | 
			
		||||
}
 | 
			
		||||
@@ -119,13 +119,13 @@ func (w *Workflow) GetResource(rObjID *string) (retObj ResourceObject) {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if storVal, ok := w.Data[*rObjID]; ok {
 | 
			
		||||
		retObj = &storVal
 | 
			
		||||
	if datVal, ok := w.Data[*rObjID]; ok {
 | 
			
		||||
		retObj = &datVal
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if storVal, ok := w.Computing[*rObjID]; ok {
 | 
			
		||||
		retObj = &storVal
 | 
			
		||||
	if compVal, ok := w.Computing[*rObjID]; ok {
 | 
			
		||||
		retObj = &compVal
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -134,8 +134,8 @@ func (w *Workflow) GetResource(rObjID *string) (retObj ResourceObject) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if storVal, ok := w.Datacenter[*rObjID]; ok {
 | 
			
		||||
		retObj = &storVal
 | 
			
		||||
	if dcVal, ok := w.Datacenter[*rObjID]; ok {
 | 
			
		||||
		retObj = &dcVal
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -182,7 +182,7 @@ func (w *Workflow) AddObj(robj ResourceObject) *primitive.ObjectID {
 | 
			
		||||
	return &outputID
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (w *Workflow) AddLinkToWorkflow (link Link, id string){
 | 
			
		||||
func (w *Workflow) AddLinkToWorkflow(link Link, id string) {
 | 
			
		||||
	if w.Links == nil {
 | 
			
		||||
		w.Links = make(map[string]Link)
 | 
			
		||||
	}
 | 
			
		||||
@@ -548,7 +548,6 @@ func ParseMxGraph(username, workflowName, xmlData string) (err error, mxissues [
 | 
			
		||||
 | 
			
		||||
	xmlModel.createLinks()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	targetWorkspaceWorkflow, err, mxissues := userWorkspace.ConsumeMxGraphModel(xmlModel)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err, nil
 | 
			
		||||
@@ -608,9 +607,10 @@ func (ws Workspace) ConsumeMxGraphModel(xmlmodel MxGraphModel) (returned_wf *Wor
 | 
			
		||||
	// Create the object and add it to the appropriate list
 | 
			
		||||
	// for all the components with setting, which are identified
 | 
			
		||||
	// by a MxObject tag in the xml
 | 
			
		||||
	for _, object := range *xmlmodel.Root.MxObject{
 | 
			
		||||
	if ok := xmlmodel.Root.MxObject != nil; ok {
 | 
			
		||||
		for _, object := range *xmlmodel.Root.MxObject {
 | 
			
		||||
	
 | 
			
		||||
		resObj, err, mxissues := returned_wf.mxCellToComponent(object.MxCell,ws)
 | 
			
		||||
			resObj, err, mxissues := returned_wf.mxCellToComponent(object.MxCell, ws)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				issues = append(issues, mxissues...)
 | 
			
		||||
			}
 | 
			
		||||
@@ -618,24 +618,24 @@ func (ws Workspace) ConsumeMxGraphModel(xmlmodel MxGraphModel) (returned_wf *Wor
 | 
			
		||||
			// 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)
 | 
			
		||||
			returned_wf.UpdateObj(resObj, object.ID)
 | 
			
		||||
	
 | 
			
		||||
			// Construct the object corresponding to the componant's type and use its addUserInput method
 | 
			
		||||
		if(resObj.getRtype() == rtype.COMPUTING){
 | 
			
		||||
			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)
 | 
			
		||||
				returned_wf.UpdateObj(comp_obj, object.ID)
 | 
			
		||||
			}
 | 
			
		||||
			// if(resObj.getRtype() == rtype.DATA){
 | 
			
		||||
			// }
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, cell := range xmlmodel.Root.MxCell {
 | 
			
		||||
 | 
			
		||||
		switch {
 | 
			
		||||
		case cell.RID != nil:
 | 
			
		||||
			resObj, err, mxissues := returned_wf.mxCellToComponent(cell,ws)
 | 
			
		||||
			resObj, err, mxissues := returned_wf.mxCellToComponent(cell, ws)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				issues = append(issues, mxissues...)
 | 
			
		||||
			}
 | 
			
		||||
@@ -681,56 +681,6 @@ func (ws Workspace) ConsumeMxGraphModel(xmlmodel MxGraphModel) (returned_wf *Wor
 | 
			
		||||
	issues = returned_wf.CreateLinks(xmlmodel.Root.MxLink, issues)
 | 
			
		||||
	issues = returned_wf.CheckLinks(issues)
 | 
			
		||||
 | 
			
		||||
	// dcslist := make(map[string]bool)
 | 
			
		||||
	// dataslist := make(map[string]bool)
 | 
			
		||||
	// // datalist := make(map[string]bool)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// // 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"))
 | 
			
		||||
	// 	} else {
 | 
			
		||||
	// 		// If doesn't exist in the list, means is new element to register as used
 | 
			
		||||
	// 		dcslist[comp.DataCenterID] = true
 | 
			
		||||
 | 
			
		||||
	// 	}
 | 
			
		||||
 | 
			
		||||
	// 	for _, dcin := range comp.Inputs {
 | 
			
		||||
	// 		switch returned_wf.GetResource(&dcin).getRtype() {
 | 
			
		||||
	// 		case rtype.DATA:
 | 
			
		||||
	// 			dataslist[dcin] = true
 | 
			
		||||
	// 		}
 | 
			
		||||
	// 	}
 | 
			
		||||
 | 
			
		||||
	// 	for _, dcout := range comp.Outputs {
 | 
			
		||||
	// 		switch returned_wf.GetResource(&dcout).getRtype() {
 | 
			
		||||
	// 		case rtype.DATA:
 | 
			
		||||
	// 			dataslist[dcout] = true
 | 
			
		||||
	// 		}
 | 
			
		||||
	// 	}
 | 
			
		||||
 | 
			
		||||
	// }
 | 
			
		||||
 | 
			
		||||
	// for _, storage_component := range returned_wf.Storage {
 | 
			
		||||
	// 	if storage_component.Inputs == nil && storage_component.Outputs == nil {
 | 
			
		||||
	// 		issues = append(issues, errors.New("Storage "+*storage_component.getName()+" without compatible inputs and outputs"))
 | 
			
		||||
	// 	}
 | 
			
		||||
	// }
 | 
			
		||||
 | 
			
		||||
	// for dcID, dc_component := range returned_wf.Datacenter {
 | 
			
		||||
	// 	// if rID doesn't exist in the list, it means that it's not used
 | 
			
		||||
	// 	if _, ok := dcslist[dcID]; !ok {
 | 
			
		||||
	// 		issues = append(issues, errors.New("DC "+*dc_component.getName()+" not attached to any Computing"))
 | 
			
		||||
	// 	}
 | 
			
		||||
	// }
 | 
			
		||||
 | 
			
		||||
	// for dcID, data_component := range returned_wf.Data {
 | 
			
		||||
	// 	// if rID doesn't exist in the list, it means that it's not used
 | 
			
		||||
	// 	if _, ok := dataslist[dcID]; !ok {
 | 
			
		||||
	// 		issues = append(issues, errors.New("Data "+*data_component.getName()+" not attached to any Computing"))
 | 
			
		||||
	// 	}
 | 
			
		||||
	// }
 | 
			
		||||
 | 
			
		||||
	//////////////////////////////////////////////////////////
 | 
			
		||||
	//														//
 | 
			
		||||
@@ -836,11 +786,11 @@ func (ws Workspace) ConsumeMxGraphModel(xmlmodel MxGraphModel) (returned_wf *Wor
 | 
			
		||||
func (w *Workflow) CreateLinks(links []MxLink, issues []error) []error {
 | 
			
		||||
 | 
			
		||||
	for _, link := range links {
 | 
			
		||||
		if (len(link.Source) > 0 && len(link.Target) > 0){
 | 
			
		||||
		if len(link.Source) > 0 && len(link.Target) > 0 {
 | 
			
		||||
			sourceObj := w.GetResource(&link.Source)
 | 
			
		||||
			targetObj := w.GetResource(&link.Target)
 | 
			
		||||
			link_object := NewLink(sourceObj,link.Source, targetObj, link.Target)
 | 
			
		||||
			w.AddLinkToWorkflow(link_object,link.ID)
 | 
			
		||||
			link_object := NewLink(sourceObj, link.Source, targetObj, link.Target)
 | 
			
		||||
			w.AddLinkToWorkflow(link_object, link.ID)
 | 
			
		||||
		} else {
 | 
			
		||||
			issues = append(issues, w.processLinkErrors(link))
 | 
			
		||||
		}
 | 
			
		||||
@@ -850,13 +800,13 @@ func (w *Workflow) CreateLinks(links []MxLink, issues []error) []error {
 | 
			
		||||
 | 
			
		||||
func (w *Workflow) processLinkErrors(link MxLink) (issue error) {
 | 
			
		||||
	if len(link.Source) == 0 && len(link.Target) == 0 {
 | 
			
		||||
		issue = errors.New("Arrow "+link.ID+" is alone")
 | 
			
		||||
	} else if len(link.Source) == 0{
 | 
			
		||||
		issue = errors.New("Arrow " + link.ID + " is alone")
 | 
			
		||||
	} else if len(link.Source) == 0 {
 | 
			
		||||
		targetObj := w.GetResource(&link.Target)
 | 
			
		||||
		issue = errors.New("Arrow ("+link.ID+") to "+*targetObj.getName()+" without parent")
 | 
			
		||||
		issue = errors.New("Arrow (" + link.ID + ") to " + *targetObj.getName() + " without parent")
 | 
			
		||||
	} else {
 | 
			
		||||
		sourceObj := w.GetResource(&link.Source)
 | 
			
		||||
		issue = errors.New("Arrow "+link.ID+" from "+*sourceObj.getName()+" without target")
 | 
			
		||||
		issue = errors.New("Arrow " + link.ID + " from " + *sourceObj.getName() + " without target")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return issue
 | 
			
		||||
@@ -866,29 +816,29 @@ func (w *Workflow) CheckLinks(issues []error) []error {
 | 
			
		||||
 | 
			
		||||
	// Check that storage components have a valid link
 | 
			
		||||
	for id, storage := range w.Storage {
 | 
			
		||||
		if(!w.IsComponentSrc(id) && !w.IsComponentDst(id)){
 | 
			
		||||
		if !w.IsComponentSrc(id) && !w.IsComponentDst(id) {
 | 
			
		||||
			issues = append(issues, errors.New("Storage "+*storage.getName()+" without compatible inputs and outputs"))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check that data components are linked to a computing component
 | 
			
		||||
	for id, data := range w.Data {
 | 
			
		||||
		if(!w.HasLinkageToComputing(id)){
 | 
			
		||||
		if !w.HasLinkageToComputing(id) {
 | 
			
		||||
			issues = append(issues, errors.New("Data "+*data.getName()+" not attached to any Computing"))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check that DC is linked to a computing component
 | 
			
		||||
	for id, dc:= range w.Datacenter {
 | 
			
		||||
		if(!w.HasLinkageToComputing(id)){
 | 
			
		||||
	for id, dc := range w.Datacenter {
 | 
			
		||||
		if !w.HasLinkageToComputing(id) {
 | 
			
		||||
			issues = append(issues, errors.New("Datacenter "+*dc.getName()+" not attached to any Computing"))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check that all data computing components are linked to a DC
 | 
			
		||||
	for id,comp:= range w.Computing {
 | 
			
		||||
		if(!w.HasLinkageToDC(id)){
 | 
			
		||||
	for id, comp := range w.Computing {
 | 
			
		||||
		if !w.HasLinkageToDC(id) {
 | 
			
		||||
			issues = append(issues, errors.New("Computing "+*comp.getName()+" not attached to any datacenter"))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -897,11 +847,10 @@ func (w *Workflow) CheckLinks(issues []error) []error {
 | 
			
		||||
	return issues
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func (w *Workflow) IsComponentSrc(id string) bool {
 | 
			
		||||
 | 
			
		||||
	for _, link := range w.Links{
 | 
			
		||||
		if(link.Source == id && link.Source != ""){
 | 
			
		||||
	for _, link := range w.Links {
 | 
			
		||||
		if link.Source == id && link.Source != "" {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -911,8 +860,8 @@ func (w *Workflow) IsComponentSrc(id string) bool {
 | 
			
		||||
 | 
			
		||||
func (w *Workflow) IsComponentDst(id string) bool {
 | 
			
		||||
 | 
			
		||||
	for _, link := range w.Links{
 | 
			
		||||
		if(link.Destination == id && link.Source != ""){
 | 
			
		||||
	for _, link := range w.Links {
 | 
			
		||||
		if link.Destination == id && link.Source != "" {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -923,7 +872,7 @@ func (w *Workflow) IsComponentDst(id string) bool {
 | 
			
		||||
func (w *Workflow) HasLinkageToComputing(id string) bool {
 | 
			
		||||
 | 
			
		||||
	for idComputing, _ := range w.Computing {
 | 
			
		||||
		if( (w.IsComponentSrc(id) && w.IsComponentDst(idComputing)) || (w.IsComponentSrc(idComputing) && w.IsComponentDst(id))){
 | 
			
		||||
		if (w.IsComponentSrc(id) && w.IsComponentDst(idComputing)) || (w.IsComponentSrc(idComputing) && w.IsComponentDst(id)) {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -934,8 +883,8 @@ func (w *Workflow) HasLinkageToComputing(id string) bool {
 | 
			
		||||
 | 
			
		||||
func (w *Workflow) HasLinkageToDC(id string) bool {
 | 
			
		||||
 | 
			
		||||
	for _, link := range w.Links{
 | 
			
		||||
		if(link.Source == id && link.DCLink){
 | 
			
		||||
	for _, link := range w.Links {
 | 
			
		||||
		if link.Source == id && link.DCLink {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -1132,7 +1081,7 @@ func CheckAndBookWorkflowSchedule(username, workflowName string, book bool) (myR
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Not sure if this method handles error propagation well
 | 
			
		||||
func (wf Workflow) mxCellToComponent(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 {
 | 
			
		||||
 
 | 
			
		||||
@@ -236,6 +236,27 @@
 | 
			
		||||
                    },
 | 
			
		||||
                    "inputs": [],
 | 
			
		||||
                    "outputs": []
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Mosquito server",
 | 
			
		||||
                    "short_description": "open source message broker that implements the MQTT protocol versions 5.0, 3.1.1 and 3.1.",
 | 
			
		||||
                    "logo": "./local_imgs/mosquitto-logo.png",
 | 
			
		||||
                    "description": "A very long description of what this storage is",
 | 
			
		||||
                    "type": "computing",
 | 
			
		||||
                    "owner": "IRT",
 | 
			
		||||
                    "price": 300,
 | 
			
		||||
                    "license": "GPLv2",
 | 
			
		||||
                    "execution_requirements": {
 | 
			
		||||
                        "cpus": 1,
 | 
			
		||||
                        "ram": 1024,
 | 
			
		||||
                        "storage": 300,
 | 
			
		||||
                        "gpus": 1,
 | 
			
		||||
                        "disk_io": "30 MB/s",
 | 
			
		||||
                        "parallel": true,
 | 
			
		||||
                        "scaling_model": 2
 | 
			
		||||
                    },
 | 
			
		||||
                    "inputs": [],
 | 
			
		||||
                    "outputs": []
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
@@ -273,22 +294,6 @@
 | 
			
		||||
                    "inputs": [],
 | 
			
		||||
                    "outputs": [],
 | 
			
		||||
                    "URL" : ""
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Mosquito server",
 | 
			
		||||
                    "short_description": "open source message broker that implements the MQTT protocol versions 5.0, 3.1.1 and 3.1.",
 | 
			
		||||
                    "logo": "./local_imgs/mosquitto-logo.png",
 | 
			
		||||
                    "description": "A very long description of what this storage is",
 | 
			
		||||
                    "type": "storage",
 | 
			
		||||
                    "DCacronym": "DC_myDC",
 | 
			
		||||
                    "size": 40000,
 | 
			
		||||
                    "encryption": false,
 | 
			
		||||
                    "redundancy": "RAID5S",
 | 
			
		||||
                    "throughput": "r:300,w:350",
 | 
			
		||||
                    "bookingPrice": 90,
 | 
			
		||||
                    "inputs": [],
 | 
			
		||||
                    "outputs": [],
 | 
			
		||||
                    "URL" : ""
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user