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 2017/01/25 18:56:51 UTC
[02/50] [abbrv] ambari git commit: AMBARI-19622. Need abilities to
add a custom action node and import a workflow xml with custom action (Padma
Priya via pallavkul)
AMBARI-19622. Need abilities to add a custom action node and import a workflow xml with custom action (Padma Priya via pallavkul)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/3e5185ac
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/3e5185ac
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/3e5185ac
Branch: refs/heads/branch-dev-patch-upgrade
Commit: 3e5185acaea24bfeb28f4b10da6d3a94c90dcacd
Parents: 9abe8da
Author: pallavkul <pa...@gmail.com>
Authored: Mon Jan 23 15:00:03 2017 +0530
Committer: pallavkul <pa...@gmail.com>
Committed: Mon Jan 23 15:00:03 2017 +0530
----------------------------------------------------------------------
.../ui/app/components/flow-designer.js | 11 +++
.../ui/app/components/workflow-action-editor.js | 77 ++++++++++++++++----
.../ui/app/components/workflow-actions.js | 5 ++
.../ui/app/domain/action-type-resolver.js | 10 ++-
.../ui/app/domain/actionjob_hanlder.js | 22 +++++-
.../resources/ui/app/domain/node-handler.js | 10 +--
.../src/main/resources/ui/app/styles/app.less | 4 +
.../app/templates/components/flow-designer.hbs | 25 +++++++
.../components/workflow-action-editor.hbs | 16 ++++
.../templates/components/workflow-actions.hbs | 3 +
.../main/resources/ui/app/utils/common-utils.js | 4 +
.../main/resources/ui/app/utils/constants.js | 3 +-
12 files changed, 169 insertions(+), 21 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e5185ac/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 8bbe831..1822a20 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
@@ -775,6 +775,17 @@ export default Ember.Component.extend(FindNodeMixin, Validations, {
this.set('showCreateKillNode', false);
},
addNode(type){
+ if(type === 'custom'){
+ this.$('#customTypeModal').modal('show');
+ }else{
+ this.send('addAction', type);
+ }
+ },
+ createCustomAction(type){
+ this.send('addAction', type);
+ this.set('customActionType', '');
+ },
+ addAction(type){
this.createSnapshot();
var currentTransition=this.get("currentTransition");
this.get("workflow").addNode(this.findTransition(this.get("workflow").startNode, currentTransition.sourceNodeId, currentTransition.targetNode.id),type);
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e5185ac/contrib/views/wfmanager/src/main/resources/ui/app/components/workflow-action-editor.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/workflow-action-editor.js b/contrib/views/wfmanager/src/main/resources/ui/app/components/workflow-action-editor.js
index 8a3c7cf..f2d3ba8 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/components/workflow-action-editor.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/workflow-action-editor.js
@@ -17,6 +17,7 @@
import Ember from 'ember';
import Constants from '../utils/constants';
+import CommonUtils from '../utils/common-utils';
import {SlaInfo} from '../domain/sla-info';
export default Ember.Component.extend( Ember.Evented,{
@@ -40,6 +41,7 @@ export default Ember.Component.extend( Ember.Evented,{
clonedActionModel : {},
showingFileBrowser : false,
childComponents : new Map(),
+ errors : Ember.A([]),
isActionNode : Ember.computed('nodeType',function(){
if(this.get('nodeType') === 'action'){
return true;
@@ -58,13 +60,43 @@ export default Ember.Component.extend( Ember.Evented,{
return this.get('actionIcons')[this.get('actionType')];
}),
saveClicked : false,
- containsUnsupportedProperties : Ember.computed('actionModel.unsupportedProperties', function(){
- return this.get('actionModel.unsupportedProperties') ? !Ember.isEmpty(Object.keys(this.get('actionModel.unsupportedProperties'))) : false;
- }),
- unsupportedPropertiesXml : Ember.computed('actionModel.unsupportedProperties', function(){
- if(this.get('containsUnsupportedProperties')){
- var x2js = new X2JS();
+ unsupportedPropertiesXml : Ember.computed('actionModel.unsupportedProperties', {
+ get(key){
+ let x2js = new X2JS();
return vkbeautify.xml(x2js.json2xml_str(this.get('actionModel.unsupportedProperties')));
+ },
+ set(key, value) {
+ let x2js = new X2JS();
+ var temp = x2js.xml_str2json(vkbeautify.xmlmin(`<unsupportedProperties>${value}</unsupportedProperties>`));
+ this.set('actionModel.unsupportedProperties', temp.unsupportedProperties);
+ Object.keys(this.get('actionModel.unsupportedProperties')).forEach(key =>{
+ this.set(`actionModel.${key}`, this.get(`actionModel.unsupportedProperties.${key}`));
+ });
+ return value;
+ }
+ }),
+ actionXml : Ember.computed('actionModel', {
+ get(key) {
+ let x2js = new X2JS();
+ var startTag = `<${this.get('actionType')}`;
+ Object.keys(this.get('actionModel')).forEach(key => {
+ if(key.startsWith('_')){
+ startTag = `${startTag} ${key.substr(1)}="${this.get('actionModel')[key]}"`;
+ }
+ });
+ startTag = `${startTag}>`;
+ return vkbeautify.xml(`${startTag}${x2js.json2xml_str(this.get('actionModel'))}</${this.get('actionType')}>`);
+ },
+ set(key, value) {
+ let x2js = new X2JS();
+ this.set('errors', Ember.A([]));
+ let temp = x2js.xml_str2json(vkbeautify.xmlmin(value));
+ if(temp){
+ this.set('actionModel', temp[this.get('actionType')]);
+ }else{
+ this.get('errors').pushObject({message:'Action Xml is syntatically incorrect'});
+ }
+ return value;
}
}),
fileBrowser : Ember.inject.service('file-browser'),
@@ -87,15 +119,30 @@ export default Ember.Component.extend( Ember.Evented,{
errorNode : errorNode
});
this.set('transition',transition);
- if (Ember.isBlank(this.get("actionModel.jobTracker"))){
- this.set('actionModel.jobTracker',Constants.rmDefaultValue);
- }
- if (Ember.isBlank(this.get("actionModel.nameNode"))){
- this.set('actionModel.nameNode','${nameNode}');
+ if(CommonUtils.isSupportedAction(this.get('actionType'))){
+ if (Ember.isBlank(this.get("actionModel.jobTracker"))){
+ this.set('actionModel.jobTracker',Constants.rmDefaultValue);
+ }
+ if (Ember.isBlank(this.get("actionModel.nameNode"))){
+ this.set('actionModel.nameNode','${nameNode}');
+ }
}
- if(this.get('nodeType') === 'action' && this.get('actionModel.slaInfo') === undefined){
+ if(this.get('nodeType') === 'action' && CommonUtils.isSupportedAction(this.get('actionType')) && this.get('actionModel.slaInfo') === undefined){
this.set('actionModel.slaInfo', SlaInfo.create({}));
}
+ if(!CommonUtils.isSupportedAction(this.get('actionType')) && !this.get('actionModel.slaInfo')){
+ this.set('customSlaInfo', SlaInfo.create({}));
+ }else{
+ this.set('customSlaInfo', this.get('actionModel.slaInfo'));
+ this.set('customSlaEnabled', this.get('actionModel.slaEnabled'));
+ delete this.get('actionModel').slaInfo;
+ delete this.get('actionModel').slaEnabled;
+ }
+ if(this.get('actionModel.unsupportedProperties') && !Ember.isEmpty(Object.keys(this.get('actionModel.unsupportedProperties')))){
+ this.set('containsUnsupportedProperties', true);
+ }else{
+ this.set('containsUnsupportedProperties', false);
+ }
}.on('init'),
initialize : function(){
this.$('#action_properties_dialog').modal({
@@ -150,10 +197,14 @@ export default Ember.Component.extend( Ember.Evented,{
},
save () {
var isChildComponentsValid = this.validateChildrenComponents();
- if(this.get('validations.isInvalid') || !isChildComponentsValid) {
+ if(this.get('validations.isInvalid') || !isChildComponentsValid || this.get('errors').length > 0) {
this.set('showErrorMessage', true);
return;
}
+ if(!CommonUtils.isSupportedAction(this.get('actionType'))){
+ this.set('actionModel.slaInfo', this.get('customSlaInfo'));
+ this.set('actionModel.slaEnabled', this.get('customSlaEnabled'));
+ }
this.processMultivaluedComponents();
this.processStaticProps();
this.$('#action_properties_dialog').modal('hide');
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e5185ac/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 7c78eea..2f8cdaa 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
@@ -16,10 +16,15 @@
*/
import Ember from 'ember';
+import Constants from '../utils/constants';
+
export default Ember.Component.extend({
clipboardHasContents : Ember.computed.oneWay('clipboard', function(){
return !Ember.isEmpty(this.get('clipboard'));
}),
+ initialize : function(){
+ this.set('customActionEnabled', Constants.customActionEnabled);
+ }.on('init'),
actions : {
addAction : function(type){
this.$(".dr_action").css("background-color", "#fff");
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e5185ac/contrib/views/wfmanager/src/main/resources/ui/app/domain/action-type-resolver.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/domain/action-type-resolver.js b/contrib/views/wfmanager/src/main/resources/ui/app/domain/action-type-resolver.js
index c25b953..8cbcfaf 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/domain/action-type-resolver.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/domain/action-type-resolver.js
@@ -55,7 +55,15 @@ var ActionTypeResolver=Ember.Object.extend({
return resolvedType;
},
getActionJobHandler(jobType){
- return this.actionJobHandlerMap.get(jobType);
+ if(this.actionJobHandlerMap.has(jobType)) {
+ return this.actionJobHandlerMap.get(jobType);
+ }else{
+ var customActionJobHandler = actionJobHandler.CustomActionJobHandler.create({
+ actionType : jobType
+ });
+ this.actionJobHandlerMap.set(jobType,customActionJobHandler);
+ return customActionJobHandler;
+ }
}
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e5185ac/contrib/views/wfmanager/src/main/resources/ui/app/domain/actionjob_hanlder.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/domain/actionjob_hanlder.js b/contrib/views/wfmanager/src/main/resources/ui/app/domain/actionjob_hanlder.js
index 4cc89ef..34a9a4a 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/domain/actionjob_hanlder.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/domain/actionjob_hanlder.js
@@ -337,6 +337,26 @@ var MapRedActionJobHandler=ActionJobHandler.extend({
}
});
+var CustomActionJobHandler=ActionJobHandler.extend({
+ actionType:'',
+ mapping:null,
+ init(){
+ this.mapping=[];
+ },
+ handleImport(actionNode,json){
+ actionNode.set('domain', json);
+ },
+ handle(nodeDomain,nodeObj,nodeName){
+ var customDomain = {};
+ Object.keys(nodeDomain).forEach(key =>{
+ if(key !== 'slaInfo' && key !== 'slaEnabled' && key!=='credentials'){
+ customDomain[key] = nodeDomain[key];
+ }
+ });
+ nodeObj[this.get("actionType")] = customDomain;
+ }
+});
+
var FSActionJobHandler=ActionJobHandler.extend({
actionType:"fs",
mapping:null,
@@ -544,4 +564,4 @@ var FSActionJobHandler=ActionJobHandler.extend({
});
}
});
-export{ActionJobHandler,JavaActionJobHandler,PigActionJobHandler,HiveActionJobHandler,SqoopActionJobHandler,ShellActionJobHandler, EmailActionJobHandler,SparkActionJobHandler,MapRedActionJobHandler, Hive2ActionJobHandler, SubWFActionJobHandler, DistCpJobHandler, SshActionJobHandler, FSActionJobHandler};
+export{ActionJobHandler,JavaActionJobHandler,PigActionJobHandler,HiveActionJobHandler,SqoopActionJobHandler,ShellActionJobHandler, EmailActionJobHandler,SparkActionJobHandler,MapRedActionJobHandler, Hive2ActionJobHandler, SubWFActionJobHandler, DistCpJobHandler, SshActionJobHandler, FSActionJobHandler, CustomActionJobHandler};
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e5185ac/contrib/views/wfmanager/src/main/resources/ui/app/domain/node-handler.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/domain/node-handler.js b/contrib/views/wfmanager/src/main/resources/ui/app/domain/node-handler.js
index 6bc305a..28ea527 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/domain/node-handler.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/domain/node-handler.js
@@ -125,16 +125,16 @@ var ActionNodeHandler= NodeHandler.extend({
return actionNode;
}
var actionJobHandler=this.get("actionTypeResolver").getActionJobHandler(actionType);
- if (!actionJobHandler){
- console.error("cannot handle unsupported action type:"+actionType+" for "+nodeJson._name);//TODO error handling...
- return actionNode;
+ if(actionJobHandler){
+ actionJobHandler.handleImport(actionNode,nodeJson[actionType]);
}
- actionJobHandler.handleImport(actionNode,nodeJson[actionType]);
if (nodeJson.info && nodeJson.info.__prefix==="sla") {
actionNode.domain.slaEnabled=true;
this.slaMapper.handleImport(actionNode.domain,nodeJson.info,"slaInfo");
}
- actionNode.domain.credentials=nodeJson._cred;
+ if(nodeJson._cred){
+ actionNode.domain.credentials=nodeJson._cred;
+ }
return actionNode;
},
handleImportTransitions(node,json,nodeMap){
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e5185ac/contrib/views/wfmanager/src/main/resources/ui/app/styles/app.less
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/styles/app.less b/contrib/views/wfmanager/src/main/resources/ui/app/styles/app.less
index 05bdb5a..d91eb3b 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/styles/app.less
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/styles/app.less
@@ -1632,3 +1632,7 @@ input:invalid {
padding: 3px;
overflow-y: auto;
}
+.custom-action-xml{
+ width: 100%;
+ min-height: 175px;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e5185ac/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/flow-designer.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/flow-designer.hbs b/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/flow-designer.hbs
index 95c8c3b..38d8eaf 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/flow-designer.hbs
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/flow-designer.hbs
@@ -377,3 +377,28 @@
{{#if showKillNodeManager}}
{{#killnode-manager killNodes=workflow.killNodes killNode=killNode createKillnodeError=createKillnodeError createKillNode="createKillNode" deleteNode="deleteNode" addKillNodeMode=addKillNodeMode editMode=editMode closeKillNodeManager="closeKillNodeManager"}}{{/killnode-manager}}
{{/if}}
+
+<div id="customTypeModal" class="modal fade" role="dialog">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal">×</button>
+ <h4 class="modal-title">Custom Action</h4>
+ </div>
+ <div class="modal-body">
+ <form class="form-horizontal">
+ <div class="form-group">
+ <label for="inputEmail" class="control-label col-xs-2">Type</label>
+ <div class="col-xs-7">
+ {{input type="text" class="form-control" name="job-tracker" value=customActionType placeholder="Custom Action Type"}}
+ </div>
+ </div>
+ </form>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
+ <button type="button" class="btn btn-primary" data-dismiss="modal" {{action 'createCustomAction' customActionType}}>OK</button>
+ </div>
+ </div>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e5185ac/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/workflow-action-editor.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/workflow-action-editor.hbs b/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/workflow-action-editor.hbs
index b36578d..bb089c0 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/workflow-action-editor.hbs
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/workflow-action-editor.hbs
@@ -64,6 +64,22 @@
{{#fs-action actionModel=actionModel transition=transition killNodes=killNodes openFileBrowser="openFileBrowser" register="registerChild" addKillNode="addKillNode" currentNode=currentNode credentials=credentials}}{{/fs-action}}
{{else if (eq actionType 'sub-workflow')}}
{{#sub-workflow actionModel=actionModel transition=transition killNodes=killNodes openFileBrowser="openFileBrowser" register="registerChild" addKillNode="addKillNode" currentNode=currentNode credentials=credentials}}{{/sub-workflow}}
+ {{else}}
+ <div class="panel panel-default">
+ <div class="panel-heading">Action XML</div>
+ <div class="panel-body handlerPanel">
+ {{designer-errors errors=errors}}
+ {{textarea class="custom-action-xml" value=actionXml}}
+ </div>
+ </div>
+ <div class="panel panel-default">
+ <div class="panel-heading">Transition</div>
+ <div class="panel-body handlerPanel">
+ {{#transition-config transition=transition killNodes=killNodes currentNode=currentNode}}{{/transition-config}}
+ </div>
+ </div>
+ {{#action-credential-config credentials=credentials actionCredentials=actionModel.credentials}}{{/action-credential-config}}
+ {{#sla-info slaInfo=customSlaInfo slaEnabled=customSlaEnabled}}{{/sla-info}}
{{/if}}
{{#if containsUnsupportedProperties}}
<div id="unsupported-props" class=" panel panel-default">
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e5185ac/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/workflow-actions.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/workflow-actions.hbs b/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/workflow-actions.hbs
index 6d672b4..badf320 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/workflow-actions.hbs
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/workflow-actions.hbs
@@ -55,6 +55,9 @@
<li class="dr_action disabled hide" data-name="Stream" data-type="stream"> <i class="fa fa-exchange"></i> Stream </li>
<li {{action 'addAction' 'email'}} class="dr_action enabled" data-name="Email" data-type="email"> <i class="fa fa-envelope"></i> Email </li>
<li {{action 'addAction' 'fs'}} class="dr_action enabled" data-name="fs" data-type="fs"> <i class="fa fa-folder-o"></i> FS </li>
+ {{#if customActionEnabled}}
+ <li {{action 'addAction' 'custom'}} class="dr_action enabled" data-name="custom" data-type="custom"> <i class="fa fa-magic" aria-hidden="true"></i> Custom </li>
+ {{/if}}
</ul>
</div>
<div class="clearfix"></div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e5185ac/contrib/views/wfmanager/src/main/resources/ui/app/utils/common-utils.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/utils/common-utils.js b/contrib/views/wfmanager/src/main/resources/ui/app/utils/common-utils.js
index e3be7da..8cc40d6 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/utils/common-utils.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/utils/common-utils.js
@@ -16,6 +16,7 @@
*/
import Ember from 'ember';
+import Constants from '../utils/constants';
export default Ember.Object.create({
extractSchemaVersion(xmlns){
return xmlns.substring(xmlns.lastIndexOf(":")+1);
@@ -25,5 +26,8 @@ export default Ember.Object.create({
},
setTestContext(context){
window.flowDesignerTestContext=context;
+ },
+ isSupportedAction(actionType){
+ return Object.values(Constants.actions).findBy('name', actionType)? true : false;
}
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e5185ac/contrib/views/wfmanager/src/main/resources/ui/app/utils/constants.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/utils/constants.js b/contrib/views/wfmanager/src/main/resources/ui/app/utils/constants.js
index fc20359..9126819 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/utils/constants.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/utils/constants.js
@@ -88,5 +88,6 @@ export default Ember.Object.create({
persistWorkInProgressInterval : 30000,
elConstants : [
'${YEAR}', '${MONTH}', '${DAY}', '${HOUR}', '${MINUTE}'
- ]
+ ],
+ customActionEnabled : false
});