blob: 4d63cbda8455ebdec1bb4be93e6c5dd93e7861ff [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Ember from 'ember';
import {WorkflowXmlMapper} from '../domain/workflow_xml_mapper';
import {NodeVisitor} from '../domain/node-visitor';
import CustomMappingHandler from "../domain/custom-mapping-handler";
var WorkflowGenerator= Ember.Object.extend({
workflowMapper:null,
x2js : new X2JS({useDoubleQuotes:true,escapeMode:false}),
workflow:null,
workflowContext : {},
nodeVisitor:null,
ignoreErrors:false,
init(){
this.workflowMapper=WorkflowXmlMapper.create({schemaVersions:this.workflow.schemaVersions});
this.nodeVisitor=NodeVisitor.create({});
},
process(){
if (!this.ignoreErrors && (!this.workflow.get("name") || this.workflow.get("name").trim()==="")){
this.workflowContext.addError({message : "Workflow name is mandatory"});
return;
}
var workflowObj={"workflow-app":{}};
this.get("workflowMapper").getGlobalConfigHandler().handle(this.workflow.get("globalSetting"),workflowObj["workflow-app"]);
this.visitNode(workflowObj,this.workflow.startNode);
if (this.workflow.slaEnabled===true){
this.get("workflowMapper").handleSLAMapping(this.workflow.sla,workflowObj["workflow-app"]);
}
this.get("workflowMapper").handleCredentialsGeneration(this.workflow.credentials,workflowObj["workflow-app"]);
this.get("workflowMapper").hanldeParametersGeneration(this.workflow.parameters,workflowObj["workflow-app"]);
var reordered={"workflow-app":{}};
var srcWorkflowApp=workflowObj["workflow-app"];
var targetWorkflowApp=reordered["workflow-app"];
targetWorkflowApp["_name"]=this.workflow.get("name");
this.copyProp(srcWorkflowApp,targetWorkflowApp,["parameters","global","credentials","start","decision","fork","join","action","kill","end","info"]);
targetWorkflowApp["_xmlns"]="uri:oozie:workflow:"+this.workflow.schemaVersions.workflowVersion;
if (this.slaInfoExists(targetWorkflowApp)){
targetWorkflowApp["_xmlns:sla"]="uri:oozie:sla:0.2";
}
var xmlAsStr = this.get("x2js").json2xml_str(reordered);
return xmlAsStr;
},
getActionNodeXml(actionNodeName, actionNodeType) {
var workflowObj={"workflow-app":{}};
this.visitNode(workflowObj, this.workflow.startNode);
var workflowActions = workflowObj["workflow-app"].action;
var actionNodes = workflowActions.filter(function (workflowActionNode) {
return workflowActionNode._name === actionNodeName;
});
if (actionNodes.length>0) {
var actionNode = {};
actionNode[actionNodeType] = actionNodes[0][actionNodeType];
return this.get("x2js").json2xml_str(actionNode);
}
return "";
},
slaInfoExists(workflowApp){
if (workflowApp.info){
return true;
}
var slaExists= false;
if (!workflowApp.action){
return false;
}
workflowApp.action.forEach(function(action){
if (action.info){
slaExists=true;
}
});
return slaExists;
},
copyProp(src,dest,props){
props.forEach(function(prop){
if (src[prop]){
dest[prop]=src[prop];
}
});
},
visitNode(workflowObj,node,visitedNodes){
if (!visitedNodes){
visitedNodes=[];
}
if (visitedNodes.contains(node.get("name"))){
return;
}
visitedNodes.push(node.get("name"));
var self=this;
var workflowApp=workflowObj["workflow-app"];
if (node.isPlaceholder()){
return self.visitNode(workflowObj,node.transitions[0].targetNode,visitedNodes);
}
var nodeHandler=this.get("workflowMapper").getNodeHandler(node.type);
nodeHandler.setContext(this.workflowContext);
var nodeObj=nodeHandler.handleNode(node);
if (node.type==='action'){
var jobHandler=this.get("workflowMapper").getActionJobHandler(node.actionType);
if (jobHandler){
jobHandler.setContext(this.workflowContext);
if(/\s/g.test(node.name)) {
this.workflowContext.addError({node : node, message : "Action name cannot contain white space."});
}
if (!self.ignoreErrors && !node.get("domain")){
this.workflowContext.addError({node : node, message : "Action Properties are empty"});
}else{
if(node.customMapping){
CustomMappingHandler.setMapping(node.name, node.customMapping);
}
jobHandler.handle(node.get("domain"),nodeObj,node.get("name"));
if (!self.ignoreErrors){
var errors=jobHandler.validate(node.get("domain"));
if (errors && errors.length>0){
errors.forEach(function(err){
this.workflowContext.addError({node : node, message : err.message});
}.bind(this));
}
}
}
}else{
if (!self.ignoreErrors){
this.workflowContext.addError({node : node, message : "Unknown action:"+node.actionType});
}
}
}
if (nodeHandler.hasMany()){
if (!workflowApp[node.type]){
workflowApp[node.type]=[];
}
workflowApp[node.type].push(nodeObj);
}else{
workflowApp[node.type]=nodeObj;
}
nodeHandler.handleTransitions(node.transitions,nodeObj);
if (node.transitions){
node.transitions.forEach(function(tran){
self.visitNode(workflowObj,tran.targetNode,visitedNodes);
});
}
if (node.isActionNode()){
nodeHandler.handleSla(node.domain,nodeObj);
}
}
});
export {WorkflowGenerator};