You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by nc...@apache.org on 2016/12/16 22:02:11 UTC
[03/51] [abbrv] ambari git commit: AMBARI-19031: UI Enhancements,
import/export assets and smart version configuration (Padma Priya via
nitirajrathore)
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/components/flow-designer.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/flow-designer.js b/contrib/views/wfmanager/src/main/resources/ui/app/components/flow-designer.js
index ed743f4..02682a4 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/components/flow-designer.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/flow-designer.js
@@ -27,6 +27,8 @@ import {CytoscapeRenderer} from '../domain/cytoscape-flow-renderer';
import {FindNodeMixin} from '../domain/findnode-mixin';
import { validator, buildValidations } from 'ember-cp-validations';
import WorkflowPathUtil from '../domain/workflow-path-util';
+import {ActionTypeResolver} from '../domain/action-type-resolver';
+import CommonUtils from "../utils/common-utils";
const Validations = buildValidations({
'dataNodes': { /* For Cytoscape */
@@ -71,6 +73,7 @@ export default Ember.Component.extend(FindNodeMixin, Validations, {
dataNodes: [], /* For cytoscape */
hoveredAction: null,
workflowImporter:WorkflowImporter.create({}),
+ actionTypeResolver: ActionTypeResolver.create({}),
propertyExtractor : Ember.inject.service('property-extractor'),
clipboardService : Ember.inject.service('workflow-clipboard'),
workspaceManager : Ember.inject.service('workspace-manager'),
@@ -86,6 +89,8 @@ export default Ember.Component.extend(FindNodeMixin, Validations, {
killNode : {},
isWorkflowImporting: false,
isImportingSuccess: true,
+ isAssetPublishing: false,
+ isPublishingSuccess: true,
shouldPersist : false,
useCytoscape: Constants.useCytoscape,
cyOverflow: {},
@@ -93,10 +98,15 @@ export default Ember.Component.extend(FindNodeMixin, Validations, {
isStackTraceVisible: false,
isStackTraceAvailable: false,
stackTrace:"",
+ showingStreamImport:false,
+ fileInfo:Ember.Object.create(),
+ isDraft: false,
+ saveJobService : Ember.inject.service('save-job'),
initialize : function(){
var id = 'cy-' + Math.ceil(Math.random() * 1000);
this.set('cyId', id);
this.sendAction('register', this.get('tabInfo'), this);
+ CommonUtils.setTestContext(this);
}.on('init'),
elementsInserted :function(){
if (this.useCytoscape){
@@ -104,7 +114,6 @@ export default Ember.Component.extend(FindNodeMixin, Validations, {
}else{
this.flowRenderer=JSPlumbRenderer.create({});
}
-
this.setConentWidth();
this.set('workflow',Workflow.create({}));
if(this.get("xmlAppPath")){
@@ -121,17 +130,18 @@ export default Ember.Component.extend(FindNodeMixin, Validations, {
if(Ember.isBlank(this.get('workflow.name'))){
this.set('workflow.name', Ember.copy(this.get('tabInfo.name')));
}
-
}.on('didInsertElement'),
restoreWorkflow(){
if (!this.get("isNew")){
- var draftWorkflow=this.getDraftWorkflow();
- if (draftWorkflow){
- this.resetDesigner();
- this.set("workflow",draftWorkflow);
- this.rerender();
- this.doValidation();
- }
+ this.getDraftWorkflow().promise.then(function(draftWorkflow){
+ if (draftWorkflow){
+ this.resetDesigner();
+ this.set("workflow",draftWorkflow);
+ this.rerender();
+ this.doValidation();
+ }
+ }.bind(this)).catch(function(data){
+ });
}
},
observeXmlAppPath : Ember.observer('xmlAppPath', function(){
@@ -291,36 +301,30 @@ export default Ember.Component.extend(FindNodeMixin, Validations, {
this.set("isWorkflowImporting", true);
this.set("workflowFilePath", filePath);
this.resetDesigner();
- this.set("isWorkflowImporting", true);
+ //this.set("isWorkflowImporting", true);
var workflowXmlDefered=this.getWorkflowFromHdfs(filePath);
workflowXmlDefered.promise.then(function(data){
this.importWorkflowFromString(data);
this.set("isWorkflowImporting", false);
}.bind(this)).catch(function(data){
- var stackTraceMsg = self.getStackTrace(data.responseText);
- if(stackTraceMsg.length){
- self.set("isStackTraceVisible", true);
- self.set("stackTrace", stackTraceMsg);
- self.set("isStackTraceAvailable", true);
- } else {
- self.set("isStackTraceVisible", false);
- self.set("isStackTraceAvailable", false);
- }
- self.set("isWorkflowImporting", false);
- self.set("isImportingSuccess", false);
+ console.error(data);
+ var stackTraceMsg = self.getStackTrace(data.responseText);
+ self.set("errorMsg", "There is some problem while importing.Please try again.");
+ self.showingErrorMsgInDesigner(data);
});
},
importWorkflowFromString(data){
- var workflow=this.get("workflowImporter").importWorkflow(data);
+ var wfObject=this.get("workflowImporter").importWorkflow(data);
if(this.get('workflow')){
this.resetDesigner();
- this.set("workflow",workflow);
+ this.set("workflow",wfObject.workflow);
this.initAndRenderWorkflow();
this.rerender();
this.doValidation();
+ this.set("errors", wfObject.errors);
}else{
this.workflow.initialize();
- this.set("workflow",workflow);
+ this.set("workflow",wfObject.workflow);
this.initAndRenderWorkflow();
this.$('#wf_title').focus();
}
@@ -343,8 +347,94 @@ export default Ember.Component.extend(FindNodeMixin, Validations, {
});
return deferred;
},
+ importActionSettingsFromString(actionSettings) {
+ var x2js = new X2JS();
+ var actionNode = this.flowRenderer.currentCyNode.data().node;
+ var actionJobHandler = this.actionTypeResolver.getActionJobHandler(actionNode.actionType);
+ actionJobHandler.handleImport(actionNode, x2js.xml_str2json(actionSettings)[actionNode.actionType]);
+ this.flowRenderer.hideOverlayNodeActions();
+ },
+ importActionNodeFromString(actionNodeXmlString) {
+ var x2js = new X2JS();
+ var actionNodeXml = x2js.xml_str2json(actionNodeXmlString);
+ var actionNodeType = Object.keys(actionNodeXml)[0];
+ var currentTransition = this.get("currentTransition");
+ this.createSnapshot();
+ var actionNode = this.get("workflow").addNode(this.findTransition(this.get("workflow").startNode, currentTransition.sourceNodeId, currentTransition.targetNode.id),actionNodeType);
+ this.rerender();
+ this.doValidation();
+ this.scrollToNewPosition();
+ var actionJobHandler = this.actionTypeResolver.getActionJobHandler(actionNodeType);
+ actionJobHandler.handleImport(actionNode, actionNodeXml[actionNodeType]);
+ },
+ publishAsset(filePath, actionNodeXml, wfDynamicProps) {
+ var url = Ember.ENV.API_URL + "/publishAsset?uploadPath="+filePath;
+ wfDynamicProps.forEach(function(property){
+ url = url + "&config." + property.name + "=" + property.value;
+ });
+ var deferred = Ember.RSVP.defer();
+ Ember.$.ajax({
+ url: url,
+ method: "POST",
+ dataType: "text",
+ contentType: "text/plain;charset=utf-8",
+ beforeSend: function (xhr) {
+ xhr.setRequestHeader("X-XSRF-HEADER", Math.round(Math.random()*100000));
+ xhr.setRequestHeader("X-Requested-By", "Ambari");
+ },
+ data: actionNodeXml,
+ }).done(function(data){
+ deferred.resolve(data);
+ }).fail(function(data){
+ deferred.reject(data);
+ });
+ return deferred;
+ },
+ getRandomDataToDynamicProps(dynamicProperties) {
+ var wfDynamicProps = [];
+ var wfParams = this.get('workflow.parameters');
+ dynamicProperties.forEach(function(property) {
+ if (property!=="${nameNode}" && property!==Constants.rmDefaultValue) {
+ var propName = property.trim().substring(2, property.length-1);
+ var propValue;
+ if (wfParams && wfParams.configuration && wfParams.configuration.property) {
+ var param = wfParams.configuration.property.findBy('name', propName);
+ if (!(param && param.value)) {
+ propValue = param.value;
+ }
+ }
+ var prop = Ember.Object.create({
+ name: propName,
+ value: propValue ? propValue : Math.random().toString(36).slice(2)
+ });
+ wfDynamicProps.push(prop);
+ }
+ });
+ return wfDynamicProps;
+ },
+ exportActionNodeXml() {
+ var self = this;
+ self.set("isAssetPublishing", true);
+ var workflowGenerator = WorkflowGenerator.create({workflow:this.get("workflow"), workflowContext:this.get('workflowContext')});
+ var actionNodeXml = workflowGenerator.getActionNodeXml(this.flowRenderer.currentCyNode.data().name, this.flowRenderer.currentCyNode.data().node.actionType);
+ var dynamicProperties = this.get('propertyExtractor').getDynamicProperties(actionNodeXml);
+
+ var exportActionNodeXmlDefered=this.publishAsset(this.get('exportActionNodeFilePath'), actionNodeXml, this.getRandomDataToDynamicProps(dynamicProperties));
+ exportActionNodeXmlDefered.promise.then(function(data){
+ self.set("isAssetPublishing", false);
+ self.set("isPublishingSuccess", true);
+ self.set("successMsg", "Asset is successfully published.");
+ }.bind(this)).catch(function(data){
+ self.set("errorMsg", "There is some problem while publishing asset. Please try again.");
+ self.showingErrorMsgInDesigner(data);
+ self.set("isImportingSuccess", true);
+ });
+
+ console.log("Action Node", actionNodeXml);
+ },
resetDesigner(){
this.set("isImportingSuccess", true);
+ this.set("isPublishingSuccess", true);
this.set("xmlAppPath", null);
this.set('errors',[]);
this.set('validationErrors',[]);
@@ -374,8 +464,8 @@ export default Ember.Component.extend(FindNodeMixin, Validations, {
dataType: "text",
cache:false,
success: function(data) {
- var workflow=this.get("workflowImporter").importWorkflow(data);
- deferred.resolve(workflow);
+ var wfObject=this.get("workflowImporter").importWorkflow(data);
+ deferred.resolve(wfObject.workflow);
}.bind(this),
failure : function(data){
deferred.reject(data);
@@ -383,19 +473,95 @@ export default Ember.Component.extend(FindNodeMixin, Validations, {
});
return deferred;
},
+ saveAsDraft(){
+ var self = this, url = Ember.ENV.API_URL + "/saveWorkflowDraft?app.path=" + this.get("workflowFilePath") + "&overwrite=" + this.get("overwritePath");
+ Ember.$.ajax({
+ url: url,
+ method: "POST",
+ dataType: "text",
+ contentType: "text/plain;charset=utf-8",
+ beforeSend: function(request) {
+ request.setRequestHeader("X-XSRF-HEADER", Math.round(Math.random()*100000));
+ request.setRequestHeader("X-Requested-By", "workflow-designer");
+ },
+ data: self.persistWorkflowAsDraft(),
+ success: function(response) {
+ //deferred.resolve(response);
+ }.bind(this),
+ error: function(response) {
+ //deferred.reject(response);
+ }.bind(this)
+ });
+ },
persistWorkInProgress(){
- var json=JSON.stringify(this.get("workflow"));
+ var json=this.getWorkflowAsJson();
this.get('workspaceManager').saveWorkInProgress(this.get('tabInfo.id'), json);
},
+ getWorkflowAsJson(){
+ try{
+ var json=JSON.stringify(this.get("workflow")), self = this;
+ //this.get('workspaceManager').saveWorkInProgress(this.get('tabInfo.id'), json);
+ return json;
+ }catch(err){
+ console.error(err);
+ this.isCyclic(this.get("workflow"));
+ }
+ },
+ isCyclic (obj) {
+ var seenObjects = [];
+ function detect (obj) {
+ if (typeof obj === 'object') {
+ if (seenObjects.indexOf(obj) !== -1) {
+ console.log("object already seen",obj);
+ return true;
+ }
+ seenObjects.push(obj);
+ for (var key in obj) {
+ if (obj.hasOwnProperty(key) && detect(obj[key])) {
+ console.log("object already seen",key);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ return detect(obj);
+ },
+ persistWorkflowAsDraft(){
+
+ },
+ getDraftWorkflowData(path){
+ var deferred = Ember.RSVP.defer();
+ //var path = encodeURIComponent("/user/ambari-qa/examples/demo/draft");
+ var self = this, url = Ember.ENV.API_URL + "/readWorkflowDraft?workflowXmlPath=" + path;
+ Ember.$.ajax({
+ url: url,
+ dataType: "text",
+ contentType: "text/plain;charset=utf-8",
+ beforeSend: function(request) {
+ request.setRequestHeader("X-XSRF-HEADER", Math.round(Math.random()*100000));
+ request.setRequestHeader("X-Requested-By", "workflow-designer");
+ },
+ success: function(response) {
+ deferred.resolve(response);
+ }.bind(this),
+ error: function(response) {
+ deferred.reject(response);
+ }.bind(this)
+ });
+ return deferred;
+ },
getDraftWorkflow(){
+ var deferred = Ember.RSVP.defer();
var drafWorkflowJson = this.get('workspaceManager').restoreWorkInProgress(this.get('tabInfo.id'));
var workflowImporter=WorkflowJsonImporter.create({});
var workflow=workflowImporter.importWorkflow(drafWorkflowJson);
- return workflow;
+ deferred.resolve(workflow);
+ return deferred;
},
createSnapshot() {
this.set('undoAvailable', false);
- this.set('workflowSnapshot', JSON.stringify(this.get("workflow")));
+ this.set('workflowSnapshot', this.getWorkflowAsJson());
},
showUndo (type){
this.set('undoAvailable', true);
@@ -462,20 +628,26 @@ export default Ember.Component.extend(FindNodeMixin, Validations, {
scrollTop: scroll+200
}, 1000);
},
- openSaveWorkflow (){
+ openSaveWorkflow (isWfPathSet){
this.get('workflowContext').clearErrors();
var workflowGenerator=WorkflowGenerator.create({workflow:this.get("workflow"),
workflowContext:this.get('workflowContext')});
var workflowXml=workflowGenerator.process();
if(this.get('workflowContext').hasErrors()){
this.set('errors',this.get('workflowContext').getErrors());
+ this.set("jobXmlJSONStr", this.persistWorkflowAsDraft());
+ this.set("isDraft", true);
}else{
+ this.set("jobXmlJSONStr", "");
var dynamicProperties = this.get('propertyExtractor').getDynamicProperties(workflowXml);
var configForSubmit={props:dynamicProperties,xml:workflowXml,params:this.get('workflow.parameters')};
this.set("workflowSubmitConfigs",configForSubmit);
+ this.set("isDraft", false);
+ }
+ if(isWfPathSet) {
this.set("showingSaveWorkflow",true);
}
- },
+ },
openJobConfig (){
this.get('workflowContext').clearErrors();
var workflowGenerator=WorkflowGenerator.create({workflow:this.get("workflow"),
@@ -490,7 +662,96 @@ export default Ember.Component.extend(FindNodeMixin, Validations, {
this.set("showingWorkflowConfigProps",true);
}
},
+ showingErrorMsgInDesigner(data){
+ var self = this, stackTraceMsg = self.getStackTrace(data.responseText);
+ if(stackTraceMsg.length){
+ self.set("isStackTraceVisible", true);
+ self.set("stackTrace", stackTraceMsg);
+ self.set("isStackTraceAvailable", true);
+ } else {
+ self.set("isStackTraceVisible", false);
+ self.set("isStackTraceAvailable", false);
+ }
+ self.set("isWorkflowImporting", false);
+ self.set("isImportingSuccess", false);
+ this.set("isAssetPublishing", false);
+ this.set("isPublishingSuccess", false);
+ },
+ isDraftExists(path){
+ var deferred = Ember.RSVP.defer(), url, self = this;
+ if(!path){
+ path = this.get("workflowFilePath");
+ }
+ url = Ember.ENV.API_URL + "/readWorkflowDetail?workflowXmlPath=" + path;
+ Ember.$.ajax({
+ url: url,
+ dataType: "text",
+ contentType: "text/plain;charset=utf-8",
+ beforeSend: function(request) {
+ request.setRequestHeader("X-XSRF-HEADER", Math.round(Math.random()*100000));
+ request.setRequestHeader("X-Requested-By", "workflow-designer");
+ },
+ success: function(response) {
+ deferred.resolve(response);
+ }.bind(this),
+ error: function(response) {
+ deferred.reject(response);
+ }.bind(this)
+ });
+ return deferred;
+
+ },
+ importWorkflowFromFile(dataStr){
+ this.resetDesigner();
+ this.importWorkflowFromString(dataStr);
+ this.send("hideStreamImport");
+ },
actions:{
+ importWorkflowStream(dataStr){
+ this.importWorkflowFromFile(dataStr);
+ },
+ saveFileinfo(path, overWritePath){
+ this.get("fileInfo").set("path", path);
+ this.get("fileInfo").set("overWritePath", overWritePath);
+ },
+ showStreamImport() {
+ this.set("showingStreamImport", true);
+ },
+ hideStreamImport() {
+ this.set("showingStreamImport", false);
+ },
+ fileLoaded(file){
+ var self = this;
+ function importWorkflowFromFile(dataStr){
+ self.importWorkflowFromFile(dataStr);
+ }
+ var reader = new FileReader();
+ reader.addEventListener("load", function (event) {
+ importWorkflowFromFile(event.target.result);
+ });
+ reader.readAsText(file);
+ },
+ importActionSettings(file){
+ var self = this;
+ var reader = new FileReader();
+ reader.addEventListener("load", function (event) {
+ var actionSettings = event.target.result;
+ var x2js = new X2JS();
+ var actionNode = self.flowRenderer.currentCyNode.data().node;
+ var actionJobHandler = self.actionTypeResolver.getActionJobHandler(actionNode.actionType);
+ actionJobHandler.handleImport(actionNode, x2js.xml_str2json(actionSettings)[actionNode.actionType]);
+ self.flowRenderer.hideOverlayNodeActions();
+ });
+ reader.readAsText(file);
+ },
+ importActionNodeLocalFS(file){
+ var self = this;
+ var reader = new FileReader();
+ reader.addEventListener("load", function (event) {
+ self.importActionNodeFromString(event.target.result);
+ });
+ reader.readAsText(file);
+ },
showStackTrace(){
this.set("isStackTraceVisible", true);
},
@@ -515,7 +776,7 @@ export default Ember.Component.extend(FindNodeMixin, Validations, {
showVersionSettings(value){
this.set('showVersionSettings', value);
},
- showingParameterSettings(value){
+ showingParameterSettings(value){
if(this.get('workflow.parameters') !== null){
this.set('parameters', Ember.copy(this.get('workflow.parameters')));
}else{
@@ -616,7 +877,7 @@ export default Ember.Component.extend(FindNodeMixin, Validations, {
if(trans.targetNode.id !== transition.okToNode.id){
trans.targetNode = transition.okToNode;
this.showUndo('transition');
- }
+ }
}
}, this);
},
@@ -624,9 +885,29 @@ export default Ember.Component.extend(FindNodeMixin, Validations, {
this.set('dryrun', false);
this.openJobConfig();
},
- saveWorkflow(){
+ saveWorkflow(action){
+ if(this.get("fileInfo").get("path") && action === "save"){
+ this.openSaveWorkflow();
+ var url = Ember.ENV.API_URL + "/saveWorkflow?app.path=" + this.get("fileInfo").get("path") + "&overwrite=" + this.get("fileInfo").get("overWritePath");
+ var self = this, workflowData;
+
+ if(this.get('isDraft')){
+ url = Ember.ENV.API_URL + "/saveWorkflowDraft?app.path=" + this.get("fileInfo").get("path") + "&overwrite=" + this.get("fileInfo").get("overWritePath");;
+ workflowData = this.get("jobXmlJSONStr");
+ } else {
+ url = Ember.ENV.API_URL + "/saveWorkflow?app.path=" + this.get("fileInfo").get("path") + "&overwrite=" + this.get("fileInfo").get("overWritePath");;
+ workflowData = this.get("workflowSubmitConfigs").xml;
+ }
+
+ this.get("saveJobService").saveWorkflow(url, workflowData).promise.then(function(data){
+ }.bind(this)).catch(function(data){
+ self.set("errorMsg", "There is some problem while saving workflow.Please try again.");
+ self.showingErrorMsgInDesigner(data);
+ });
+ } else {
+ this.openSaveWorkflow(true);
+ }
this.set('dryrun', false);
- this.openSaveWorkflow();
},
previewWorkflow(){
this.set("showingPreview",false);
@@ -671,14 +952,85 @@ export default Ember.Component.extend(FindNodeMixin, Validations, {
});
},
closeFileBrowser(){
+ var self = this, path = this.get('workflowFilePath');
this.set("showingFileBrowser",false);
- if(this.get('workflowFilePath')){
- this.importWorkflow(this.get('workflowFilePath'));
+ if(path){
+ this.isDraftExists().promise.then(function(data){
+ var draftData = JSON.parse(data);
+ if(draftData.draftExists && draftData.isDraftCurrent){
+ self.getDraftWorkflowData(path).promise.then(function(data){
+ var drafWorkflowJson = self.get('workspaceManager').restoreWorkInProgress(data);
+ var workflowImporter=WorkflowJsonImporter.create({});
+ var workflow=workflowImporter.importWorkflow(drafWorkflowJson);
+
+ self.resetDesigner();
+ self.set("workflow",workflow);
+ self.rerender();
+ self.doValidation();
+
+ }.bind(this)).catch(function(data){
+
+ });
+
+ //deferred.resolve(workflow);
+ } else {
+ self.importWorkflow(path);
+ }
+ }.bind(this)).catch(function(data){
+ //self.importWorkflow(path);
+ console.error(data);
+ });
}
},
showFileBrowser(){
this.set('showingFileBrowser', true);
},
+ closeActionSettingsFileBrowser() {
+ var self = this;
+ this.set("showingActionSettingsFileBrowser", false);
+ if(this.get('actionSettingsFilePath')){
+ var actionSettingsXmlDefered=this.getWorkflowFromHdfs(this.get('actionSettingsFilePath'));
+ actionSettingsXmlDefered.promise.then(function(data){
+ this.importActionSettingsFromString(data);
+ }.bind(this)).catch(function(data){
+ console.error(data);
+ var stackTraceMsg = self.getStackTrace(data.responseText);
+ self.set("errorMsg", "There is some problem while importing.Please try again.");
+ self.showingErrorMsgInDesigner(data);
+ });
+ }
+ },
+ showActionSettingsFileBrowser() {
+ this.set('showingActionSettingsFileBrowser', true);
+ },
+ closeImportActionNodeFileBrowser() {
+ var self = this;
+ this.set("showingImportActionNodeFileBrowser", false);
+ if(this.get('actionNodeFilePath')){
+ var actionSettingsXmlDefered=this.getWorkflowFromHdfs(this.get('actionNodeFilePath'));
+ actionSettingsXmlDefered.promise.then(function(data){
+ this.importActionNodeFromString(data);
+ }.bind(this)).catch(function(data){
+ console.error(data);
+ var stackTraceMsg = self.getStackTrace(data.responseText);
+ self.set("errorMsg", "There is some problem while importing.Please try again.");
+ self.showingErrorMsgInDesigner(data);
+ });
+ }
+ },
+ showImportActionNodeFileBrowser() {
+ this.set('showingImportActionNodeFileBrowser', true);
+ },
+ closeExportActionNodeFileBrowser() {
+ var self = this;
+ this.set("showingExportActionNodeFileBrowser", false);
+ if(this.get('exportActionNodeFilePath')){
+ self.exportActionNodeXml();
+ }
+ },
+ showExportActionNodeFileBrowser() {
+ this.set('showingExportActionNodeFileBrowser', true);
+ },
createNewWorkflow(){
this.resetDesigner();
this.rerender();
@@ -768,6 +1120,13 @@ export default Ember.Component.extend(FindNodeMixin, Validations, {
dryRunWorkflow(){
this.set('dryrun', true);
this.openJobConfig();
+ },
+ scheduleWorkflow(){
+ if(!this.get('workflowFilePath')){
+ console.error("Workflow doesnot exists");
+ return;
+ }
+ this.sendAction('openTab', 'coord', this.get('workflowFilePath'));
}
}
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/components/hdfs-browser.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/hdfs-browser.js b/contrib/views/wfmanager/src/main/resources/ui/app/components/hdfs-browser.js
index 232df16..c9be41a 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/components/hdfs-browser.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/hdfs-browser.js
@@ -59,7 +59,8 @@ export default Ember.Component.extend({
var self=this;
var $elem=this.$('input[name="selectedPath"]');
//$elem.val($elem.val()+"/");
-
+ var folderHint="<enter folder here>";
+ this.set("selectedPath",this.get("selectedPath")+"/"+folderHint);
setTimeout(function(){
$elem[0].selectionStart = $elem[0].selectionEnd = self.get("selectedPath").length-folderHint.length;
},10);
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/components/import-from-stream.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/import-from-stream.js b/contrib/views/wfmanager/src/main/resources/ui/app/components/import-from-stream.js
new file mode 100644
index 0000000..c9aa3c4
--- /dev/null
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/import-from-stream.js
@@ -0,0 +1,67 @@
+/*
+* 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 Constants from '../utils/constants';
+import { validator, buildValidations } from 'ember-cp-validations';
+
+const Validations = buildValidations({
+ 'workflowStream': validator('presence', {
+ presence : true
+ }),
+ 'configMap': {
+ validators: [
+ validator('job-params-validator', {
+ dependentKeys: ['configMap.@each.value', 'showErrorMessage']
+ })
+ ]
+ }
+});
+
+
+export default Ember.Component.extend(Validations, {
+ workflowStream : "",
+ displayName : Ember.computed('type', function(){
+ if(this.get('type') === 'wf'){
+ return "Workflow";
+ }else if(this.get('type') === 'coord'){
+ return "Coordinator";
+ }else{
+ return "Bundle";
+ }
+ }),
+ initialize :function(){
+
+ }.on('init'),
+ rendered : function(){
+ this.$("#configureJob").modal("show");
+ }.on('didInsertElement'),
+
+ getParsedErrorResponse (response){
+
+ },
+ actions: {
+ save(){
+ this.$("#configureJob").modal("hide");
+ this.sendAction("importWorkflowStream", this.$('.CodeMirror')[0].CodeMirror.getValue());
+ },
+ close(){
+ this.$("#configureJob").modal("hide");
+ this.sendAction("hideStreamImport");
+ }
+ }
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/components/job-config.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/job-config.js b/contrib/views/wfmanager/src/main/resources/ui/app/components/job-config.js
index 4fa2666..8b685f0 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/components/job-config.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/job-config.js
@@ -142,7 +142,7 @@ export default Ember.Component.extend(Validations, {
}
this.set("alertDetails", data.details);
this.set("alertMessage", data.message);
- if(data.stackTrace.length){
+ if(data.stackTrace && data.stackTrace.length){
this.set("stackTrace", data.stackTrace);
this.set("isStackTraceAvailable", true);
} else {
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/components/job-details.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/job-details.js b/contrib/views/wfmanager/src/main/resources/ui/app/components/job-details.js
index 0e5fd36..32f5ef4 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/components/job-details.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/job-details.js
@@ -49,16 +49,21 @@ export default Ember.Component.extend({
}
}),
displayType : Ember.computed('model.jobType', function() {
- if(this.get('jobType') === 'wf'){
+ if(this.get('model.jobType') === 'wf'){
return "Workflow";
- }else if(this.get('jobType') === 'coords'){
+ }else if(this.get('model.jobType') === 'coords'){
return "Coordinator";
}
- else if(this.get('jobType') === 'bundles'){
+ else if(this.get('model.jobType') === 'bundles'){
return "Bundle";
}
return "Workflow";
}),
+ configurationProperties : Ember.computed('model', function(){
+ var x2js = new X2JS();
+ var configurationObj = x2js.xml_str2json(this.get('model.conf'));
+ return configurationObj.configuration.property;
+ }),
initialize : function(){
if(this.get('currentTab')){
this.$('.nav-tabs a[href="'+this.get('currentTab').attr("href")+'"]').click();
@@ -66,11 +71,6 @@ export default Ember.Component.extend({
this.set('model.actionDetails', this.get('model.actions')[0]);
}
}
-
- var x2js = new X2JS();
- var configurationObj = x2js.xml_str2json(this.get('model.conf'));
- this.set('model.configurationProperties', configurationObj.configuration.property);
-
this.$('.nav-tabs').on('shown.bs.tab', function(event){
this.sendAction('onTabChange', this.$(event.target));
}.bind(this));
@@ -229,7 +229,8 @@ export default Ember.Component.extend({
this.set('model.actionInfo', actionInfo);
},
renderDag(xmlString){
- var workflow = this.get("workflowImporter").importWorkflow(xmlString);
+ var wfObject = this.get("workflowImporter").importWorkflow(xmlString);
+ var workflow = wfObject.workflow;
console.log("Workflow Object..", workflow);
var dataNodes=this.getCyDataNodes(workflow);
var cy = cytoscape({
@@ -321,8 +322,8 @@ export default Ember.Component.extend({
});
},
actions : {
- back (){
- this.sendAction('back');
+ back (jobType, jobId){
+ this.sendAction('back', jobType, jobId);
},
close : function(){
this.sendAction('close');
@@ -332,7 +333,7 @@ export default Ember.Component.extend({
},
getJobDefinition : function () {
Ember.$.get(Ember.ENV.API_URL+'/v2/job/'+this.get('id')+'?show=definition&timezone=GMT',function(response){
- this.set('model.jobDefinition', (new XMLSerializer()).serializeToString(response).trim());
+ this.set('jobDefinition', (new XMLSerializer()).serializeToString(response).trim());
}.bind(this)).fail(function(error){
this.set('error',error);
}.bind(this));
@@ -400,6 +401,9 @@ export default Ember.Component.extend({
},
showCoord : function(coordId){
this.sendAction('showCoord', coordId);
+ },
+ editWorkflow(path){
+ this.sendAction('editWorkflow', path);
}
}
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/components/job-row.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/job-row.js b/contrib/views/wfmanager/src/main/resources/ui/app/components/job-row.js
index 297244a..2a5fc22 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/components/job-row.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/job-row.js
@@ -19,6 +19,10 @@ import Ember from 'ember';
export default Ember.Component.extend({
tagName: 'tr',
+ targetParentId: Ember.computed('job', function() {
+ var parentID = this.get('job').parentId;
+ return parentID.split("@")[0];
+ }),
onRender : function(){
this.$('#actions').hide();
}.on('didInsertElement'),
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/components/name-value-config.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/name-value-config.js b/contrib/views/wfmanager/src/main/resources/ui/app/components/name-value-config.js
index ae453a0..bac2124 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/components/name-value-config.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/name-value-config.js
@@ -33,7 +33,6 @@ export default Ember.Component.extend({
}
}.on('willDestroyElement'),
addProperty (){
- alert(this.get("validations"));
this.get('configuration.property').pushObject({name:this.get('propertyName'),value:this.get('propertyValue')});
//if(this.get("doNotInitialize")){
this.set('propertyName', "");
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/components/preview-dialog.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/preview-dialog.js b/contrib/views/wfmanager/src/main/resources/ui/app/components/preview-dialog.js
index 31f9df8..7e956a6 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/components/preview-dialog.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/preview-dialog.js
@@ -1,3 +1,4 @@
+
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -17,4 +18,10 @@
import Ember from 'ember';
export default Ember.Component.extend({
+ elementsInserted :function(){
+ var self = this;
+ this.$('#previewModal').on('shown.bs.modal', function (e) {
+ self.$('.CodeMirror')[0].CodeMirror.refresh();
+ });
+ }.on('didInsertElement'),
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/components/save-wf.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/save-wf.js b/contrib/views/wfmanager/src/main/resources/ui/app/components/save-wf.js
index b41f743..8514cb0 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/components/save-wf.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/save-wf.js
@@ -38,6 +38,7 @@ export default Ember.Component.extend(Validations, {
alertDetails : "",
filePath : "",
showErrorMessage: false,
+ saveJobService : Ember.inject.service('save-job'),
displayName : Ember.computed('type', function(){
if(this.get('type') === 'wf'){
return "Workflow";
@@ -69,7 +70,7 @@ export default Ember.Component.extend(Validations, {
}
this.set("alertDetails", data.details);
this.set("alertMessage", data.message);
- if(data.stackTrace.length){
+ if(data.stackTrace && data.stackTrace.length){
this.set("stackTrace", data.stackTrace);
this.set("isStackTraceAvailable", true);
} else {
@@ -77,36 +78,34 @@ export default Ember.Component.extend(Validations, {
}
},
saveJob(){
- var url = Ember.ENV.API_URL + "/saveWorkflow?app.path=" + this.get("filePath") + "&overwrite=" + this.get("overwritePath");
- Ember.$.ajax({
- url: url,
- method: "POST",
- dataType: "text",
- contentType: "text/plain;charset=utf-8",
- beforeSend: function(request) {
- request.setRequestHeader("X-XSRF-HEADER", Math.round(Math.random()*100000));
- request.setRequestHeader("X-Requested-By", "workflow-designer");
- },
- data: this.get("jobXml"),
- success: function(response) {
- //var result=JSON.parse(response);
- this.showNotification({
+ var url, workflowData;
+ if(this.get('isDraft')){
+ url = Ember.ENV.API_URL + "/saveWorkflowDraft?app.path=" + this.get("filePath") + "&overwrite=" + this.get("overwritePath");
+ workflowData = this.get("jobXmlJSONStr");
+ } else {
+ url = Ember.ENV.API_URL + "/saveWorkflow?app.path=" + this.get("filePath") + "&overwrite=" + this.get("overwritePath");
+ workflowData = this.get("jobXml");
+ }
+
+ var self = this;
+ this.get("saveJobService").saveWorkflow(url, workflowData).promise.then(function(response){
+ self.showNotification({
"type": "success",
"message": "Workflow have been saved"
});
- this.set("savingInProgress",false);
- }.bind(this),
- error: function(response) {
+ self.set("savingInProgress",false);
+ self.sendAction("saveFileinfo", this.get("filePath"), this.get("overwritePath"));
+ }.bind(this)).catch(function(response){
console.log(response);
- this.set("savingInProgress",false);
- this.set("isStackTraceVisible",true);
- this.showNotification({
+ self.set("savingInProgress",false);
+ self.set("isStackTraceVisible",true);
+ self.showNotification({
"type": "error",
- "message": "Error occurred while saving "+ this.get('displayName').toLowerCase(),
- "details": this.getParsedErrorResponse(response),
- "stackTrace": this.getStackTrace(response.responseText)
+ "message": "Error occurred while saving "+ self.get('displayName').toLowerCase(),
+ "details": self.getParsedErrorResponse(response),
+ "stackTrace": self.getStackTrace(response.responseText)
});
- }.bind(this)
+ self.sendAction("saveFileinfo", self.get("filePath"), self.get("overwritePath"));
});
},
getStackTrace(data){
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/components/search-create-new-bar.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/search-create-new-bar.js b/contrib/views/wfmanager/src/main/resources/ui/app/components/search-create-new-bar.js
index 420d3b0..f9226f4 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/components/search-create-new-bar.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/search-create-new-bar.js
@@ -98,6 +98,7 @@ export default Ember.Component.extend(Ember.Evented,{
}
strs.push('Name:'+ searchTerm);
strs.push('User:'+ searchTerm);
+ strs.push('Job id:'+ searchTerm);
var newLength = strs.length;
var matches, substrRegex;
matches = [];
@@ -115,19 +116,20 @@ export default Ember.Component.extend(Ember.Evented,{
typeaheadjs: {
name: 'source',
source: substringMatcher(source),
- highlight : true,
- limit : 10
+ highlight : true
}
});
this.get('tags').forEach(function(value){
this.$('#search-field').tagsinput('add', value);
}.bind(this));
this.$('#search-field').tagsinput('refresh');
+
this.$('#search-field').on('itemAdded itemRemoved',function(){
var searchTerms = this.$('#search-field').tagsinput('items');
var filter = searchTerms.map(function(value){
+
var eachTag = value.split(":");
- return eachTag[0].toLowerCase()+"="+eachTag[1];
+ return self.mapSearchItems(eachTag[0])+"="+eachTag[1];
});
if(filter.length > 0){
this.filter.tags = filter.join(";");
@@ -144,7 +146,14 @@ export default Ember.Component.extend(Ember.Evented,{
}
}.bind(this));
}.on('didInsertElement'),
-
+ mapSearchItems(key){
+ key = key.replace(" ", "_").toLowerCase();
+ var keys = {"job_id":"id"};
+ if(keys[key]){
+ return keys[key];
+ }
+ return key;
+ },
filterByDate(date, dateType){
var queryParam;
if(dateType === 'start'){
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/components/workflow-actions.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/workflow-actions.js b/contrib/views/wfmanager/src/main/resources/ui/app/components/workflow-actions.js
index 7fc1c94..55f86af 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/components/workflow-actions.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/workflow-actions.js
@@ -30,6 +30,14 @@ export default Ember.Component.extend({
pasteNode(){
this.$(this.get('element')).popover('hide');
this.sendAction("pasteNode");
+ },
+ importActionNodeLocalFS(file) {
+ this.$(this.get('element')).popover('hide');
+ this.sendAction("importActionNodeLocalFS", file);
+ },
+ showImportActionNodeFileBrowser() {
+ this.$(this.get('element')).popover('hide');
+ this.sendAction("showImportActionNodeFileBrowser");
}
}
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/components/workflow-icon.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/workflow-icon.js b/contrib/views/wfmanager/src/main/resources/ui/app/components/workflow-icon.js
new file mode 100644
index 0000000..31dd392
--- /dev/null
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/workflow-icon.js
@@ -0,0 +1,21 @@
+/*
+* 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';
+
+export default Ember.Component.extend({
+ tagName: 'span'
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/controllers/design/dashboardtab.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/controllers/design/dashboardtab.js b/contrib/views/wfmanager/src/main/resources/ui/app/controllers/design/dashboardtab.js
new file mode 100644
index 0000000..9760ddb
--- /dev/null
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/controllers/design/dashboardtab.js
@@ -0,0 +1,81 @@
+/*
+* 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';
+
+export default Ember.Controller.extend({
+ actions: {
+ launchDesign: function () {
+ this.transitionToRoute('design');
+ },
+ doRefresh : function(){
+ this.get('target.router').refresh();
+ },
+ onJobAction: function (params, deferred) {
+ if (Ember.ENV.API_FAILED) {
+ return { error: "Remote API Failed." };
+ }
+ var url = [Ember.ENV.API_URL,
+ "/v2/job/", params.id, "?action=", params.action,'&user.name=oozie'
+ ].join("");
+ var jobActionParams = {
+ url: url,
+ method: 'PUT',
+ beforeSend: function (xhr) {
+ xhr.setRequestHeader("X-XSRF-HEADER", Math.round(Math.random()*100000));
+ xhr.setRequestHeader("X-Requested-By", "Ambari");
+ if(params.action.indexOf('rerun') > -1){
+ xhr.setRequestHeader("Content-Type","application/xml");
+ }
+ }
+ };
+ if(params.action.indexOf('rerun') > -1){
+ jobActionParams.data = params.conf;
+ }
+ Ember.$.ajax(jobActionParams).done(function(){
+ deferred.resolve();
+ }).fail(function(){
+ deferred.reject();
+ });
+ },
+ onBulkAction : function(params, deferred){
+ if (Ember.ENV.API_FAILED) {
+ return { error: "Remote API Failed." };
+ }
+ var url = [Ember.ENV.API_URL,
+ "/v2/jobs?jobtype=", params.jobType,
+ "&offset=", params.start,
+ "&len=", params.len,
+ "&filter=", params.filter,
+ "&action=", params.action,
+ "&user.name=oozie"
+ ].join("");
+ Ember.$.ajax({
+ url: url,
+ method: 'PUT',
+ beforeSend: function (xhr) {
+ xhr.setRequestHeader("X-XSRF-HEADER", Math.round(Math.random()*100000));
+ xhr.setRequestHeader("X-Requested-By", "Ambari");
+ }
+ }).done(function(response){
+ deferred.resolve(response);
+ }).fail(function(response){
+ deferred.reject(response);
+ });
+ }
+ }
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/controllers/design/jobtab.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/controllers/design/jobtab.js b/contrib/views/wfmanager/src/main/resources/ui/app/controllers/design/jobtab.js
new file mode 100644
index 0000000..18559cc
--- /dev/null
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/controllers/design/jobtab.js
@@ -0,0 +1,59 @@
+/*
+* 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';
+
+export default Ember.Controller.extend({
+ dashboardContext: Ember.inject.service(),
+ fromBundleId: null,
+ fromCoordId: null,
+ actions : {
+ close : function(){
+ this.sendAction('onCloseJobDetails');
+ },
+ showWorkflow : function(workflowId){
+ this.get('dashboardContext').setCurrentCoordName(this.get('model.coordJobName'));
+ this.transitionToRoute('design.jobtab', {
+ queryParams: {
+ jobType: 'wf',
+ id: workflowId,
+ fromBundleId: this.get('fromBundleId'),
+ fromCoordId: this.get('model.coordJobId')
+ }
+ });
+ },
+ showCoord : function(coordJobId){
+ this.get('dashboardContext').setCurrentBundleName(this.get('model.bundleJobName'));
+ this.transitionToRoute('design.jobtab', {
+ queryParams: {
+ jobType: 'coords',
+ id: coordJobId,
+ fromBundleId: this.get('model.bundleJobId')
+ }
+ });
+ },
+ back : function (jobType, jobId){
+ this.transitionToRoute('design.jobtab', {
+ queryParams: {
+ jobType: jobType,
+ id: jobId,
+ fromBundleId : (jobType === 'coords') ? this.get('fromBundleId') : null,
+ fromCoordId : null
+ }
+ });
+ },
+ }
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/controllers/job.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/controllers/job.js b/contrib/views/wfmanager/src/main/resources/ui/app/controllers/job.js
index 2c90be4..5a95b84 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/controllers/job.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/controllers/job.js
@@ -17,8 +17,9 @@
import Ember from 'ember';
export default Ember.Controller.extend({
- from : null,
- fromType : null,
+ dashboardContext: Ember.inject.service(),
+ fromBundleId: null,
+ fromCoordId: null,
actions : {
close : function(){
this.sendAction('onCloseJobDetails');
@@ -27,32 +28,33 @@ export default Ember.Controller.extend({
this.get('target.router').refresh();
},
showWorkflow : function(workflowId){
- this.transitionToRoute('job', {
+ this.get('dashboardContext').setCurrentCoordName(this.get('model.coordJobName'));
+ this.transitionToRoute('design.jobtab', {
queryParams: {
jobType: 'wf',
id: workflowId,
- from : this.get('model.coordJobId'),
- fromType : this.get('model.jobType')
+ fromBundleId: this.get('fromBundleId'),
+ fromCoordId: this.get('model.coordJobId')
}
});
},
showCoord : function(coordJobId){
- this.transitionToRoute('job', {
+ this.get('dashboardContext').setCurrentBundleName(this.get('model.bundleJobName'));
+ this.transitionToRoute('design.jobtab', {
queryParams: {
jobType: 'coords',
id: coordJobId,
- from : this.get('model.bundleJobId'),
- fromType : this.get('model.jobType')
+ fromBundleId: this.get('model.bundleJobId')
}
});
},
- back : function (){
- this.transitionToRoute('job', {
+ back : function (jobType, jobId){
+ this.transitionToRoute('design.jobtab', {
queryParams: {
- jobType: this.get('fromType'),
- id: this.get('from'),
- from : null,
- fromType : null
+ jobType: jobType,
+ id: jobId,
+ fromBundleId : (jobType === 'coords') ? this.get('fromBundleId') : null,
+ fromCoordId : null
}
});
},
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/domain/bundle/bundle-xml-generator.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/domain/bundle/bundle-xml-generator.js b/contrib/views/wfmanager/src/main/resources/ui/app/domain/bundle/bundle-xml-generator.js
index 957d1c0..7dc05a9 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/domain/bundle/bundle-xml-generator.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/domain/bundle/bundle-xml-generator.js
@@ -22,7 +22,7 @@ var BundleGenerator= Ember.Object.extend({
var xmlJson={"bundle-app":{}};
console.log(this.bundle);
var bundleApp=xmlJson["bundle-app"];
- bundleApp._xmlns = "uri:oozie:bundle:0.1";
+ bundleApp._xmlns = "uri:oozie:bundle:"+this.bundle.schemaVersions.bundleVersion;
bundleApp._name = this.bundle.name;
if(!Ember.isEmpty(this.bundle.kickOffTime.value)){
bundleApp["control"] = {};
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/domain/bundle/bundle-xml-importer.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/domain/bundle/bundle-xml-importer.js b/contrib/views/wfmanager/src/main/resources/ui/app/domain/bundle/bundle-xml-importer.js
index aa96221..2714ca1 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/domain/bundle/bundle-xml-importer.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/domain/bundle/bundle-xml-importer.js
@@ -16,14 +16,18 @@
*/
import Ember from 'ember';
import { Bundle } from '../bundle/bundle';
+import SchemaVersions from '../schema-versions';
+import CommonUtils from "../../utils/common-utils";
var BundleXmlImporter= Ember.Object.extend({
x2js : new X2JS(),
- importBundle (xml){
+ schemaVersions : null,
+ importBundle (xml, errors){
var bundleJson = this.get("x2js").xml_str2json(xml);
- return this.processBundleXML(bundleJson);
+ return this.processBundleXML(bundleJson, errors);
},
processBundleXML(bundleJson){
+ var errors=Ember.A([]);
var bundle = Bundle.create({
name : '',
kickOffTime : {
@@ -31,17 +35,25 @@ var BundleXmlImporter= Ember.Object.extend({
displayValue : '',
type : 'date'
},
- coordinators : Ember.A([])
+ coordinators : Ember.A([]),
+ schemaVersions : this.get("schemaVersions")
});
var bundleApp=bundleJson["bundle-app"];
bundle.name = bundleApp._name;
+ var bundleVersion=CommonUtils.extractSchemaVersion(bundleApp._xmlns);
+ var maxBundleVersion = Math.max.apply(Math, bundle.schemaVersions.getBundleVersions());
+ if (bundleVersion < maxBundleVersion) {
+ bundle.schemaVersions.setCurrentBundleVersion(bundleVersion);
+ } else {
+ errors.push({message: "Unsupported bundle version - " + bundleVersion});
+ }
if(bundleApp.control && bundleApp.control["kick-off-time"]) {
bundle.kickOffTime = this.extractDateField(bundleApp["control"]["kick-off-time"]);
}else{
}
this.processCoordinatorsJson(bundleApp, bundle);
- return bundle;
+ return {bundle: bundle, errors: errors};
},
processCoordinatorsJson(bundleApp, bundle){
if (bundleApp.coordinator){
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/domain/coordinator/coordinator-xml-generator.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/domain/coordinator/coordinator-xml-generator.js b/contrib/views/wfmanager/src/main/resources/ui/app/domain/coordinator/coordinator-xml-generator.js
index a657706..cbefa99 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/domain/coordinator/coordinator-xml-generator.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/domain/coordinator/coordinator-xml-generator.js
@@ -33,7 +33,7 @@ var CoordinatorGenerator= Ember.Object.extend({
coordinatorApp._start = this.coordinator.start.value;
coordinatorApp._end = this.coordinator.end.value;
coordinatorApp._timezone = this.coordinator.timezone;
- coordinatorApp._xmlns = "uri:oozie:coordinator:0.4";
+ coordinatorApp._xmlns = "uri:oozie:coordinator:"+this.coordinator.schemaVersions.coordinatorVersion;
this.generateDataSets(coordinatorApp);
if(this.coordinator.dataInputType === 'simple'){
this.generateInputEvents(coordinatorApp);
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/domain/coordinator/coordinator-xml-importer.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/domain/coordinator/coordinator-xml-importer.js b/contrib/views/wfmanager/src/main/resources/ui/app/domain/coordinator/coordinator-xml-importer.js
index fca90b3..76da535 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/domain/coordinator/coordinator-xml-importer.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/domain/coordinator/coordinator-xml-importer.js
@@ -16,12 +16,15 @@
*/
import Ember from 'ember';
import { Coordinator } from '../coordinator/coordinator';
+import SchemaVersions from '../schema-versions';
+import CommonUtils from "../../utils/common-utils";
var CoordinatorXmlImporter= Ember.Object.extend({
x2js : new X2JS(),
- importCoordinator (xml){
+ schemaVersions: null,
+ importCoordinator (xml, errors){
var coordinatorJson = this.get("x2js").xml_str2json(xml);
- return this.processCoordinatorXML(coordinatorJson);
+ return this.processCoordinatorXML(coordinatorJson, errors);
},
createNewCoordinator(){
return Coordinator.create({
@@ -55,13 +58,22 @@ var CoordinatorXmlImporter= Ember.Object.extend({
property : Ember.A([])
}
},
- controls : Ember.A([])
+ controls : Ember.A([]),
+ schemaVersions : this.get("schemaVersions")
});
},
processCoordinatorXML(coordinatorJson){
+ var errors=Ember.A([]);
var coordinatorApp = coordinatorJson["coordinator-app"];
var coordinator = this.createNewCoordinator();
coordinator.name = coordinatorApp._name;
+ var coordinatorVersion=CommonUtils.extractSchemaVersion(coordinatorApp._xmlns);
+ var maxCoordinatorVersion = Math.max.apply(Math, coordinator.schemaVersions.getCoordinatorVersions());
+ if (coordinatorVersion < maxCoordinatorVersion) {
+ coordinator.schemaVersions.setCurrentCoordinatorVersion(coordinatorVersion);
+ } else {
+ errors.push({message: "Unsupported coordinator version - " + coordinatorVersion});
+ }
var frequency = coordinatorApp._frequency;
if(frequency.startsWith('${coord:')){
coordinator.frequency.type = frequency.substring(frequency.indexOf(':')+1, frequency.indexOf('('));
@@ -77,7 +89,7 @@ var CoordinatorXmlImporter= Ember.Object.extend({
if(coordinatorApp['input-events'] && coordinatorApp['input-events']['data-in']){
coordinator.dataInputType = 'simple';
this.extractInputEvents(coordinatorApp, coordinator);
- }else{
+ }else if(coordinatorApp['input-events']){
coordinator.dataInputType = 'logical';
coordinator.supportsConditionalDataInput = true;
this.extractLogicalInputEvents(coordinatorApp, coordinator);
@@ -86,7 +98,7 @@ var CoordinatorXmlImporter= Ember.Object.extend({
this.extractAction(coordinatorApp, coordinator);
this.extractParameters(coordinatorApp, coordinator);
this.extractControls(coordinatorApp, coordinator);
- return coordinator;
+ return {coordinator: coordinator, errors: errors};
},
extractDateField(value){
var dateField = {};
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/domain/cytoscape-flow-renderer.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/domain/cytoscape-flow-renderer.js b/contrib/views/wfmanager/src/main/resources/ui/app/domain/cytoscape-flow-renderer.js
index 086916f..d1150c3 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/domain/cytoscape-flow-renderer.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/domain/cytoscape-flow-renderer.js
@@ -79,7 +79,7 @@ var CytoscapeRenderer= Ember.Object.extend({
return 'roundrectangle';
case 'fork' :
case 'join' :
- return 'rectangle';
+ return 'roundrectangle';
case 'decision' :
return 'diamond';
default :
@@ -199,6 +199,8 @@ var CytoscapeRenderer= Ember.Object.extend({
if (node.data().type === 'action') {
this.get("context").$(".overlay-copy-icon").show();
this.get("context").$(".overlay-cut-icon").show();
+ this.get("context").$(".overlay-hdfs-import-icon").show();
+ this.get("context").$(".overlay-hdfs-export-icon").show();
if(this.get('context').get('clipboard')){
this.get("context").$(".overlay-paste-icon").show();
}
@@ -317,6 +319,15 @@ var CytoscapeRenderer= Ember.Object.extend({
this._initCY(settings);
callback();
},
+
+ fitWorkflow() {
+ this.cy.fit();
+ },
+
+ hideOverlayNodeActions() {
+ this.get("context").$('.overlay-node-actions').hide();
+ },
+
reset(){
},
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/domain/mapping-utils.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/domain/mapping-utils.js b/contrib/views/wfmanager/src/main/resources/ui/app/domain/mapping-utils.js
index 2962e71..d4d8f50 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/domain/mapping-utils.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/domain/mapping-utils.js
@@ -65,7 +65,7 @@ var MappingMixin= Ember.Mixin.create({
var domain={};
if (json._xmlns){
var version=CommonUtils.extractSchemaVersion(json._xmlns);
- this.schemaVersions.setActionVersion(actionNode.actionType,version);
+ //this.schemaVersions.setActionVersion(actionNode.actionType,version);
}
actionNode.set("domain",domain);
mappings.forEach(function(mapping){
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/domain/schema-versions.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/domain/schema-versions.js b/contrib/views/wfmanager/src/main/resources/ui/app/domain/schema-versions.js
index 9562ae8..0a5083f 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/domain/schema-versions.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/domain/schema-versions.js
@@ -18,35 +18,133 @@ import Ember from 'ember';
export default Ember.Object.extend({
actionVersions: Ember.Map.create(),
currentActionVersion:Ember.Map.create(),
+ workflowVersions: [],
+ workflowVersion: null,
+ bundleVersions: [],
+ bundleVersion: null,
+ coordinatorVersions: [],
+ coordinatorVersion: null,
clone : {},
+ actionSchemaMap:{
+ "hive":["0.6","0.5","0.4","0.3","0.2","0.1"],
+ "hive2":["0.2","0.1"],
+ "sqoop":["0.3","0.2","0.1"],
+ "shell":["0.3","0.2","0.1"],
+ "spark":["0.2","0.1"],
+ "distcp":["0.2","0.1"],
+ "email":["0.2","0.1"]
+ },
createCopy(){
this.clone.workflowVersion = this.workflowVersion;
this.clone.currentActionVersion = this.currentActionVersion.copy();
+ this.clone.coordinatorVersion = this.coordinatorVersion;
+ this.clone.bundleVersion = this.bundleVersion;
},
rollBack(){
this.workflowVersion = this.clone.workflowVersion;
this.currentActionVersion = this.clone.currentActionVersion.copy();
},
+ importAdminConfigs(){
+ var url = Ember.ENV.API_URL + "/v1/admin/configuration";
+ var deferred = Ember.RSVP.defer();
+ Ember.$.ajax({
+ url: url,
+ method: "GET",
+ dataType: "text",
+ contentType: "text/plain;charset=utf-8",
+ beforeSend: function(request) {
+ request.setRequestHeader("X-Requested-By", "workflow-designer");
+ },
+ success: function(response) {
+ deferred.resolve(response);
+ }.bind(this),
+ error: function(response) {
+ deferred.reject(response);
+ }.bind(this)
+ });
+ return deferred;
+ },
+ setWfSchemaVersions(configSettings) {
+ this.workflowVersions = [];
+ var wfSchemaVersions = configSettings["oozie.service.SchemaService.wf.schemas"].trim().split(",");
+ wfSchemaVersions = wfSchemaVersions.map(Function.prototype.call, String.prototype.trim).sort();
+ wfSchemaVersions.forEach(function(wfSchemaVersion) {
+ var wfSchema = wfSchemaVersion.split("-");
+ var wfSchemaName = wfSchema[0];
+ var wfSchemaType = wfSchema[1];
+ var wfSchemaVersionNumber = wfSchema[2].replace(".xsd", "");
+ if (wfSchemaType === "action") {
+ if (this.actionVersions.get(wfSchemaName)) {
+ this.actionVersions.get(wfSchemaName).push(wfSchemaVersionNumber);
+ this.currentActionVersion.set(wfSchemaName, wfSchemaVersionNumber);
+ } else {
+ this.actionVersions.set(wfSchemaName, [wfSchemaVersionNumber]);
+ this.currentActionVersion.set(wfSchemaName, wfSchemaVersionNumber);
+ }
+ } else if (wfSchemaType === "workflow") {
+ this.workflowVersions.push(wfSchemaVersionNumber);
+ this.workflowVersion = wfSchemaVersionNumber;
+ }
+ }.bind(this));
+ },
+ setCoordSchemaVersions(configSettings) {
+ this.coordinatorVersions = [];
+ var coordSchemaVersions = configSettings["oozie.service.SchemaService.coord.schemas"].trim().split(",");
+ coordSchemaVersions = coordSchemaVersions.map(Function.prototype.call, String.prototype.trim).sort();
+ coordSchemaVersions.forEach(function(coordSchemaVersion) {
+ var coordSchema = coordSchemaVersion.split("-");
+ var coordSchemaType = coordSchema[1];
+ var coordSchemaVersionNumber = coordSchema[2].replace(".xsd", "");
+ if (coordSchemaType === "coordinator") {
+ this.coordinatorVersions.push(coordSchemaVersionNumber);
+ this.coordinatorVersion = coordSchemaVersionNumber;
+ }
+ }.bind(this));
+ },
+ setBundleSchemaVersions(configSettings) {
+ this.bundleVersions = [];
+ var bundleSchemaVersions = configSettings["oozie.service.SchemaService.bundle.schemas"].trim().split(",");
+ bundleSchemaVersions = bundleSchemaVersions.map(Function.prototype.call, String.prototype.trim).sort();
+ bundleSchemaVersions.forEach(function(bundleSchemaVersion) {
+ var bundleSchema = bundleSchemaVersion.split("-");
+ var bundleSchemaType = bundleSchema[1];
+ var bundleSchemaVersionNumber = bundleSchema[2].replace(".xsd", "");
+ if (bundleSchemaType === "bundle") {
+ this.bundleVersions.push(bundleSchemaVersionNumber);
+ this.bundleVersion = bundleSchemaVersionNumber;
+ }
+ }.bind(this));
+ },
init(){
- this.workflowVersion = "0.5";
- this.workflowVersions = ["0.5","0.4.5","0.4","0.3","0.2.5","0.2","0.1"];
- this.actionVersions.set("hive",["0.6","0.5","0.4","0.3","0.2","0.1"]);
- this.actionVersions.set("hive2",["0.2","0.1"]);
- this.actionVersions.set("pig",["0.3","0.2","0.1"]);
- this.actionVersions.set("sqoop",["0.3","0.2","0.1"]);
- this.actionVersions.set("shell",["0.3","0.2","0.1"]);
- this.actionVersions.set("spark",["0.2","0.1"]);
- this.actionVersions.set("distcp",["0.2","0.1"]);
- this.actionVersions.set("email",["0.2","0.1"]);
-
- this.currentActionVersion.set("hive","0.6");
- this.currentActionVersion.set("hive2","0.2");
- this.currentActionVersion.set("pig","0.3");
- this.currentActionVersion.set("sqoop","0.3");
- this.currentActionVersion.set("shell","0.3");
- this.currentActionVersion.set("spark","0.2");
- this.currentActionVersion.set("distcp","0.2");
- this.currentActionVersion.set("email","0.2");
+ var importAdminConfigsDefered=this.importAdminConfigs();
+ importAdminConfigsDefered.promise.then(function(data){
+ var configSettings = JSON.parse(data);
+ if (!(configSettings instanceof Object)) {
+ configSettings = JSON.parse(configSettings);
+ }
+ this.setWfSchemaVersions(configSettings);
+ this.setCoordSchemaVersions(configSettings);
+ this.setBundleSchemaVersions(configSettings);
+ this.setDefaultActionVersions();
+ }.bind(this)).catch(function(){
+ this.setWorkflowVersions(["0.5","0.4.5","0.4","0.3","0.2.5","0.2","0.1"]);
+ this.setCurrentWorkflowVersion("0.5");
+ this.setCoordinatorVersions(["0.4","0.3", "0.2","0.1"]);
+ this.setCurrentCoordinatorVersion("0.4");
+ this.setBundleVersions(["0.2","0.1"]);
+ this.setCurrentBundleVersion("0.2");
+ this.setDefaultActionVersions();
+ console.error("There is some problem while importing schema versions. defaulting to known versions.");
+ }.bind(this));
+ },
+ setDefaultActionVersions(){
+ var self=this;
+ Object.keys(this.actionSchemaMap).forEach(function(key) {
+ if (!self.actionVersions.get(key)){
+ self.actionVersions.set(key,self.actionSchemaMap[key]);
+ self.currentActionVersion.set(key,self.actionSchemaMap[key][0]);
+ }
+ });
},
getActionVersions(type){
return this.actionVersions.get(type);
@@ -60,11 +158,38 @@ export default Ember.Object.extend({
getWorkflowVersions(){
return this.workflowVersions;
},
+ getCurrentCoordinatorVersion(){
+ return this.coordinatorVersion;
+ },
+ getCoordinatorVersions(){
+ return this.coordinatorVersions;
+ },
+ getCurrentBundleVersion(){
+ return this.bundleVersion;
+ },
+ getBundleVersions(){
+ return this.bundleVersions;
+ },
setActionVersion(type, version){
this.currentActionVersion.set(type, version);
},
setCurrentWorkflowVersion(version){
- return this.workflowVersion = version;
+ this.workflowVersion = version;
+ },
+ setCurrentCoordinatorVersion(version){
+ this.coordinatorVersion = version;
+ },
+ setCurrentBundleVersion(version){
+ this.bundleVersion = version;
+ },
+ setWorkflowVersions(versions){
+ this.workflowVersions = versions;
+ },
+ setCoordinatorVersions(versions){
+ this.coordinatorVersions = versions;
+ },
+ setBundleVersions(versions){
+ this.bundleVersions = versions;
}
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/domain/workflow-importer.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/domain/workflow-importer.js b/contrib/views/wfmanager/src/main/resources/ui/app/domain/workflow-importer.js
index 7415544..d001f38 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/domain/workflow-importer.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/domain/workflow-importer.js
@@ -24,11 +24,12 @@ var WorkflowImporter= Ember.Object.extend({
x2js : new X2JS(),
importWorkflow(workflowXml){
var workflow=Workflow.create({});
+ var errors=[];
workflow.initialize();
this.workflowMapper=WorkflowXmlMapper.create({schemaVersions:workflow.schemaVersions});
- return this.processWorkflowXml(workflowXml,workflow);
+ return this.processWorkflowXml(workflowXml,workflow, errors);
},
- processWorkflowXml(workflowXml,workflow){
+ processWorkflowXml(workflowXml,workflow, errors){
var workflowJson= this.get("x2js").xml_str2json(workflowXml);
if (!workflowJson["workflow-app"]){
throw "Invalid workflow";
@@ -36,6 +37,8 @@ var WorkflowImporter= Ember.Object.extend({
var workflowAppJson=workflowJson["workflow-app"];
var workflowVersion=CommonUtils.extractSchemaVersion(workflowAppJson._xmlns);
workflow.schemaVersions.setCurrentWorkflowVersion(workflowVersion);
+ this.processWorkflowActionVersions(workflowAppJson, workflow, errors);
+
if (workflowAppJson.info && workflowAppJson.info.__prefix==="sla") {
workflow.slaEnabled=true;
this.workflowMapper.handleSLAImport(workflow,workflowAppJson.info);
@@ -46,7 +49,33 @@ var WorkflowImporter= Ember.Object.extend({
this.setupTransitions(workflowAppJson,nodeMap);
workflow.set("startNode",nodeMap.get("start").node);
this.populateKillNodes(workflow,nodeMap);
- return workflow;
+ return {workflow: workflow, errors: errors};
+ },
+ processWorkflowActionVersions(workflowAppJson, workflow, errors) {
+ var importedWfActionVersions = Ember.Map.create();
+ var actions=workflowAppJson.action.length?workflowAppJson.action:[workflowAppJson.action];
+ actions.forEach(function(wfAction) {
+ var wfActionType = Object.keys(wfAction)[0];
+ var wfActionXmlns = wfAction[wfActionType]._xmlns;
+ if (!wfActionXmlns) {
+ return;
+ }
+ var wfActionVersion = CommonUtils.extractSchemaVersion(wfActionXmlns);
+ if (importedWfActionVersions.get(wfActionType)) {
+ importedWfActionVersions.get(wfActionType).push(wfActionVersion);
+ } else {
+ importedWfActionVersions.set(wfActionType, [wfActionVersion]);
+ }
+ });
+
+ importedWfActionVersions._keys.forEach(function(wfActionType){
+ var maxImportedActionVersion = Math.max.apply(Math, importedWfActionVersions.get(wfActionType))
+ if (workflow.schemaVersions.getActionVersion(wfActionType) < maxImportedActionVersion) {
+ errors.push({message: "Unsupported " + wfActionType + " version - " + maxImportedActionVersion});
+ } else {
+ workflow.schemaVersions.setActionVersion(wfActionType, maxImportedActionVersion.toString());
+ }
+ });
},
processActionNode(nodeMap,action){
var actionMapper=this.get("workflowMapper").getNodeHandler("action");
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/domain/workflow-xml-generator.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/domain/workflow-xml-generator.js b/contrib/views/wfmanager/src/main/resources/ui/app/domain/workflow-xml-generator.js
index 7049fde..012e7ac 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/domain/workflow-xml-generator.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/domain/workflow-xml-generator.js
@@ -58,6 +58,21 @@ var WorkflowGenerator= Ember.Object.extend({
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;
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/router.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/router.js b/contrib/views/wfmanager/src/main/resources/ui/app/router.js
index 1fcd633..f494f6f 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/router.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/router.js
@@ -24,7 +24,10 @@ const Router = Ember.Router.extend({
Router.map(function () {
this.route('dashboard');
- this.route('design');
+ this.route('design', function() {
+ this.route('dashboardtab');
+ this.route('jobtab');
+ });
this.route('designtest');
this.route('job');
this.route('connection-error');
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/routes/dashboard.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/routes/dashboard.js b/contrib/views/wfmanager/src/main/resources/ui/app/routes/dashboard.js
index 949d39a..84cbd28 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/routes/dashboard.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/routes/dashboard.js
@@ -31,8 +31,8 @@ export default Ember.Route.extend({
queryParams : {
id : params.id,
jobType : params.type,
- from: null,
- fromType: null
+ fromBundleId: null,
+ fromCoordId: null
}
});
},
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/routes/design.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/routes/design.js b/contrib/views/wfmanager/src/main/resources/ui/app/routes/design.js
index 5ed2619..10f745a 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/routes/design.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/routes/design.js
@@ -17,11 +17,24 @@
import Ember from 'ember';
-export default Ember.Route.extend({
+export default Ember.Route.extend(Ember.Evented, {
beforeModel: function(transition){
this.set("xmlAppPath", transition.queryParams.appPath);
this.controllerFor('design').set("xmlAppPath", transition.queryParams.appPath);
+ },
+ actions : {
+ editWorkflow(path){
+ this.trigger('openNewTab', path);
+ },
+ showDashboard(){
+ this.controller.set('dashboardShown', true);
+ this.transitionTo('design.dashboardtab');
+ },
+ hideDashboard(){
+ this.controller.set('dashboardShown', false);
+ this.transitionTo('design');
+ }
}
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/routes/design/dashboardtab.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/routes/design/dashboardtab.js b/contrib/views/wfmanager/src/main/resources/ui/app/routes/design/dashboardtab.js
new file mode 100644
index 0000000..ddb19af
--- /dev/null
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/routes/design/dashboardtab.js
@@ -0,0 +1,154 @@
+/*
+* 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';
+
+export default Ember.Route.extend({
+ history: Ember.inject.service(),
+ errorMessage : "Error",
+ queryParams: {
+ jobType: { refreshModel: true },
+ start: { refreshModel: true },
+ filter: { refreshModel: true }
+ },
+ actions: {
+ onShowJobDetails : function(params){
+ this.transitionTo('design.jobtab',{
+ queryParams : {
+ id : params.id,
+ jobType : params.type,
+ fromBundleId: null,
+ fromCoordId: null
+ }
+ });
+ },
+ loading: function ( /*transition, originRoute*/ ) {
+ Ember.$("#loading").css("display", "block");
+ var app = this.controllerFor('application');
+ if (app.get('currentRouteName') !== "dashboard") {
+ return true;
+ }
+ return false;
+ },
+ error: function() {
+
+ },
+ doSearch (params){
+ this.get('history').setSearchParams(params);
+ Ember.$("#loading").css("display", "block");
+ this.search(params);
+ }
+ },
+ fetchJobs (url){
+ var deferred = Ember.RSVP.defer();
+ Ember.$.get(url).done(function(res){
+ deferred.resolve(res);
+ }).fail(function(){
+ deferred.reject();
+ });
+ return deferred.promise;
+ },
+ setPageResultLen(){
+ /*
+ setting the no of jobs to be displayed to multiple of 5
+ */
+ var relHeight = parseInt(Ember.$(window).width()/100);
+ return relHeight - relHeight%5;
+ },
+ search(params){
+ params = params || {};
+ var type = params.type || "wf",
+ start = Number(params.start || 1),
+ //len = Number(params.len || Ember.ENV.PAGE_SIZE),
+ len = this.setPageResultLen(),
+ index = 0,
+ filter = params.filter || "",
+ API_URL = Ember.ENV.API_URL,
+ url = [API_URL,
+ "/v2/jobs?jobtype=", type,
+ "&offset=", start,
+ "&len=", len,
+ "&filter=", filter
+ ].join(""),
+ page = (start - 1) / len + 1;
+ return this.fetchJobs(url).catch(function(){
+ this.controllerFor('dashboard').set('model',{error : "Remote API Failed"});
+ Ember.$("#loading").css("display", "none");
+ }.bind(this)).then(function (res) {
+ if(!res){
+ return;
+ }
+ if (typeof res === "string") {
+ res = JSON.parse(res);
+ }
+ res.jobs = [];
+
+ if (res.workflows) {
+ res.areWfs = true;
+ res.type = "wf";
+ res.workflows.forEach(function (job) {
+ job.type = "wf";
+ res.jobs.push(job);
+ });
+ }
+ if (res.coordinatorjobs) {
+ res.areCoords = true;
+ res.type = "coords";
+ res.coordinatorjobs.forEach(function (job) {
+ job.type = "coordinatorjobs";
+ job.id = job.coordJobId;
+ job.appName = job.coordJobName;
+ res.jobs.push(job);
+ });
+ }
+ if (res.bundlejobs) {
+ res.areBundles = true;
+ res.type = "bundles";
+ res.bundlejobs.forEach(function (job) {
+ job.type = "bundlejobs";
+ job.id = job.bundleJobId;
+ job.appName = job.bundleJobName;
+ res.jobs.push(job);
+ });
+ }
+ res.pageSize = len;
+ res.pages = [];
+
+ while (index++ < (res.total / len)) {
+ res.pages.push({ index: index, active: page === index });
+ }
+
+ res.jobTypeValue = type;
+ res.filterValue = filter;
+ res.pageSize = len;
+ res.totalValue = res.total;
+ res.page = page;
+ res.start = start;
+ res.end = (start + res.jobs.length - 1);
+ res.time = new Date().getTime();
+ this.controllerFor('design.dashboardtab').set('model', res);
+ Ember.$("#loading").css("display", "none");
+ return res;
+ }.bind(this));
+ },
+ afterModel: function (model) {
+ Ember.$("#loading").css("display", "none");
+ },
+ model: function (params) {
+
+ }
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/routes/design/jobtab.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/routes/design/jobtab.js b/contrib/views/wfmanager/src/main/resources/ui/app/routes/design/jobtab.js
new file mode 100644
index 0000000..7d0fa92
--- /dev/null
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/routes/design/jobtab.js
@@ -0,0 +1,94 @@
+/*
+ * 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';
+
+export default Ember.Route.extend({
+ history: Ember.inject.service(),
+ queryParams: {
+ jobType: { refreshModel: true },
+ id: { refreshModel: true },
+ fromBundleId: {refreshModel: true},
+ fromCoordId: {refreshModel: true}
+ },
+ fromBundleId: null,
+ fromCoordId: null,
+ getJobInfo (url){
+ var deferred = Ember.RSVP.defer();
+ Ember.$.get(url).done(function(res){
+ deferred.resolve(res);
+ }).fail(function(){
+ deferred.reject();
+ });
+ return deferred.promise;
+ },
+ model : function(params){
+ return this.getJobInfo(Ember.ENV.API_URL+'/v2/job/'+params.id+'?show=info&timezone=GMT&offset=1&len='+Ember.ENV.PAGE_SIZE).catch(function(){
+ return {error : "Remote API Failed"};
+ }).then(function(response){
+ if (typeof response === "string") {
+ response = JSON.parse(response);
+ }
+ response.jobType = params.jobType;
+ return response;
+ });
+ },
+ afterModel : function (model, transition){
+ if(transition.queryParams.fromBundleId){
+ this.set('fromBundleId', transition.queryParams.fromBundleId);
+ }else{
+ this.set('fromBundleId', null);
+ }
+ if(transition.queryParams.fromCoordId){
+ this.set('fromCoordId', transition.queryParams.fromCoordId);
+ }else{
+ this.set('fromCoordId', null);
+ }
+ },
+ actions : {
+ didTransition (){
+ if (this.get('fromBundleId')) {
+ this.controller.set('fromBundleId', this.get('fromBundleId'));
+ }
+ if (this.get('fromCoordId')) {
+ this.controller.set('fromCoordId',this.get('fromCoordId'));
+ }
+ },
+ onTabChange : function(tab){
+ this.set('currentTab', tab);
+ this.controller.set('currentTab',tab);
+ },
+ backToSearch : function(){
+ var params = this.get('history').getSearchParams();
+ if(null != params){
+ this.transitionTo('design.dashboardtab', {
+ queryParams: {
+ jobType: params.type,
+ start: params.start,
+ end: params.end,
+ filter: params.filter
+ }
+ });
+ }else{
+ this.transitionTo('design.dashboardtab');
+ }
+ },
+ doRefresh : function(){
+ this.refresh();
+ }
+ }
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/fb567758/contrib/views/wfmanager/src/main/resources/ui/app/routes/index.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/routes/index.js b/contrib/views/wfmanager/src/main/resources/ui/app/routes/index.js
index 0fbbaa2..23609e9 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/routes/index.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/routes/index.js
@@ -19,6 +19,6 @@ import Ember from 'ember';
export default Ember.Route.extend({
beforeModel() {
- this.transitionTo('dashboard');
+ this.transitionTo('design');
}
});