AMBARI-19610. User is not able to import the draft version for a coordinator. (Padma Priya N via gauravn7)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/8b4dd3a4 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/8b4dd3a4 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/8b4dd3a4 Branch: refs/heads/branch-dev-patch-upgrade Commit: 8b4dd3a4826c8b13aec9087de51fce7a856326c4 Parents: 7e00f58 Author: Gaurav Nagar <grv...@gmail.com> Authored: Fri Jan 27 11:23:55 2017 +0530 Committer: Gaurav Nagar <grv...@gmail.com> Committed: Fri Jan 27 11:23:55 2017 +0530 ---------------------------------------------------------------------- .../org/apache/oozie/ambari/view/Constants.java | 4 +- .../ambari/view/OozieProxyImpersonator.java | 56 ++++++++++++-- .../oozie/ambari/view/WorkflowFileInfo.java | 6 +- .../oozie/ambari/view/WorkflowFilesService.java | 64 ++++++++++++---- .../workflowmanager/WorkflowManagerService.java | 10 +-- .../ui/app/components/bundle-config.js | 53 +++++++++++-- .../resources/ui/app/components/coord-config.js | 46 +++++++++-- .../ui/app/components/designer-workspace.js | 2 +- .../ui/app/components/flow-designer.js | 80 +++++++++++--------- .../main/resources/ui/app/components/save-wf.js | 4 +- .../ui/app/services/workspace-manager.js | 3 +- .../app/templates/components/bundle-config.hbs | 4 +- .../app/templates/components/coord-config.hbs | 2 +- .../app/templates/components/flow-designer.hbs | 2 +- 14 files changed, 252 insertions(+), 84 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/8b4dd3a4/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/Constants.java ---------------------------------------------------------------------- diff --git a/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/Constants.java b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/Constants.java index f7c1936..f413a0d 100644 --- a/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/Constants.java +++ b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/Constants.java @@ -24,7 +24,9 @@ public interface Constants { String MESSAGE_KEY = "message"; String WF_DRAFT_EXTENSION = ".wfdraft"; String WF_EXTENSION = ".xml"; - String DEFAULT_WORKFLOW_FILENAME="workflow.xml"; + String DEFAULT_WORKFLOW_FILENAME="workflow"; + String DEFAULT_COORDINATOR_FILENAME="coordinator"; + String DEFAULT_BUNDLE_FILENAME="bundle"; String DEFAULT_DRAFT_FILENAME="workflow"+WF_DRAFT_EXTENSION; String WF_ASSET_EXTENSION = ".wfasset"; String DEFAULT_WORKFLOW_ASSET_FILENAME="asset"+WF_ASSET_EXTENSION; http://git-wip-us.apache.org/repos/asf/ambari/blob/8b4dd3a4/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/OozieProxyImpersonator.java ---------------------------------------------------------------------- diff --git a/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/OozieProxyImpersonator.java b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/OozieProxyImpersonator.java index d029c39..a119a7e 100644 --- a/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/OozieProxyImpersonator.java +++ b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/OozieProxyImpersonator.java @@ -122,11 +122,15 @@ public class OozieProxyImpersonator { viewContext.getInstanceName())); } + + @GET @Path("hdfsCheck") public Response hdfsCheck(){ hdfsFileUtils.hdfsCheck(); return Response.ok().build(); } + + @GET @Path("homeDirCheck") public Response homeDirCheck(){ hdfsFileUtils.homeDirCheck(); @@ -179,13 +183,17 @@ public class OozieProxyImpersonator { if (StringUtils.isEmpty(appPath)) { throw new RuntimeException("app path can't be empty."); } - appPath = workflowFilesService.getWorkflowFileName(appPath.trim()); + + JobType deducedJobType = oozieUtils.deduceJobType(postBody); + appPath = workflowFilesService.getWorkflowFileName(appPath.trim(),deducedJobType); + if (!overwrite) { boolean fileExists = hdfsFileUtils.fileExists(appPath); if (fileExists) { return getFileExistsResponse(); } } + postBody = utils.formatXml(postBody); try { String filePath = workflowFilesService.createFile(appPath, @@ -193,7 +201,6 @@ public class OozieProxyImpersonator { LOGGER.info(String.format( "submit workflow job done. filePath=[%s]", filePath)); if (PROJ_MANAGER_ENABLED) { - JobType deducedJobType = oozieUtils.deduceJobType(postBody); String workflowName = oozieUtils.deduceWorkflowNameFromXml(postBody); workflowManagerService.saveWorkflow(projectId, appPath, deducedJobType, description, @@ -220,10 +227,10 @@ public class OozieProxyImpersonator { if (StringUtils.isEmpty(appPath)) { throw new RuntimeException("app path can't be empty."); } - appPath = workflowFilesService.getWorkflowDraftFileName(appPath.trim()); + JobType jobType = StringUtils.isEmpty(jobTypeStr) ? JobType.WORKFLOW : JobType.valueOf(jobTypeStr); + appPath = workflowFilesService.getWorkflowDraftFileName(appPath.trim(),jobType); workflowFilesService.createFile(appPath, postBody, overwrite); if (PROJ_MANAGER_ENABLED) { - JobType jobType = StringUtils.isEmpty(jobTypeStr) ? JobType.WORKFLOW : JobType.valueOf(jobTypeStr); String name = oozieUtils.deduceWorkflowNameFromJson(postBody); workflowManagerService.saveWorkflow(projectId, appPath, jobType, description, @@ -337,7 +344,7 @@ public class OozieProxyImpersonator { if (StringUtils.isEmpty(appPath)) { throw new RuntimeException("app path can't be empty."); } - appPath = workflowFilesService.getWorkflowFileName(appPath.trim()); + appPath = workflowFilesService.getWorkflowFileName(appPath.trim(), jobType); if (!overwrite) { boolean fileExists = hdfsFileUtils.fileExists(appPath); if (fileExists) { @@ -412,17 +419,52 @@ public class OozieProxyImpersonator { public Response getWorkflowDetail( @QueryParam("workflowXmlPath") String workflowPath) { WorkflowFileInfo workflowDetails = workflowFilesService - .getWorkflowDetails(workflowPath); + .getWorkflowDetails(workflowPath, null); return Response.ok(workflowDetails).build(); } @GET + @Path("/readWorkflow") + public Response readWorkflow( + @QueryParam("workflowPath") String workflowPath,@QueryParam("jobType") String jobTypeStr) { + WorkflowFileInfo workflowDetails = workflowFilesService + .getWorkflowDetails(workflowPath,JobType.valueOf(jobTypeStr)); + String filePath; + String responseType; + + if (workflowPath.endsWith(Constants.WF_DRAFT_EXTENSION) || workflowDetails.getIsDraftCurrent()){ + filePath=workflowFilesService.getWorkflowDraftFileName(workflowPath,JobType.valueOf(jobTypeStr)); + responseType="draft"; + }else{ + filePath=workflowFilesService.getWorkflowFileName(workflowPath,JobType.valueOf(jobTypeStr)); + responseType="xml"; + } + try { + final InputStream is = workflowFilesService + .readWorkflowXml(filePath); + StreamingOutput streamer = new StreamingOutput() { + @Override + public void write(OutputStream os) throws IOException, + WebApplicationException { + IOUtils.copy(is, os); + is.close(); + os.close(); + } + }; + return Response.ok(streamer).header("response-type",responseType).status(200).build(); + } catch (IOException e) { + return getRespCodeForException(e); + } + } + + @GET @Path("/readWorkflowXml") public Response readWorkflowXml( - @QueryParam("workflowXmlPath") String workflowPath) { + @QueryParam("workflowXmlPath") String workflowPath,@QueryParam("jobType") String jobTypeStr) { if (StringUtils.isEmpty(workflowPath)) { throw new RuntimeException("workflowXmlPath can't be empty."); } + try { final InputStream is = workflowFilesService .readWorkflowXml(workflowPath); http://git-wip-us.apache.org/repos/asf/ambari/blob/8b4dd3a4/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/WorkflowFileInfo.java ---------------------------------------------------------------------- diff --git a/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/WorkflowFileInfo.java b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/WorkflowFileInfo.java index 6dbf30e..1f167b1 100644 --- a/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/WorkflowFileInfo.java +++ b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/WorkflowFileInfo.java @@ -22,6 +22,7 @@ public class WorkflowFileInfo { private String draftPath; private Boolean draftExists; private Boolean isDraftCurrent=false; + private Boolean workflowDefinitionExists=false; public Boolean getIsDraftCurrent() { return isDraftCurrent; } @@ -60,5 +61,8 @@ public class WorkflowFileInfo { public Long getDraftModificationTime() { return draftModificationTime; } - + + public void setWorkflowDefinitionExists(Boolean workflowDefinitionExists) { + this.workflowDefinitionExists = workflowDefinitionExists; + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/8b4dd3a4/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/WorkflowFilesService.java ---------------------------------------------------------------------- diff --git a/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/WorkflowFilesService.java b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/WorkflowFilesService.java index 289e68b..24c263b 100644 --- a/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/WorkflowFilesService.java +++ b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/WorkflowFilesService.java @@ -47,40 +47,69 @@ public class WorkflowFilesService { } public InputStream readDraft(String appPath) throws IOException { - return hdfsFileUtils.read(getWorkflowDraftFileName(appPath)); + return hdfsFileUtils.read(getWorkflowDraftFileName(appPath,null)); } public InputStream readWorkflowXml(String appPath) throws IOException { - return hdfsFileUtils.read(getWorkflowFileName(appPath)); + return hdfsFileUtils.read(appPath); } public InputStream readAssset(String assetPath) throws IOException { return hdfsFileUtils.read(getAssetFileName(assetPath)); } - public String getWorkflowDraftFileName(String appPath) { + public String getWorkflowDraftFileName(String appPath,JobType jobType) { if (appPath.endsWith(Constants.WF_DRAFT_EXTENSION)) { return appPath; } else if (appPath.endsWith(Constants.WF_EXTENSION)) { String folderPath = appPath.substring(0, appPath.lastIndexOf(Constants.WF_EXTENSION)); return folderPath + Constants.WF_DRAFT_EXTENSION; - } else if (appPath.endsWith("/")) { - return appPath + Constants.DEFAULT_DRAFT_FILENAME; + } + if (jobType==null){ + throw new RuntimeException("Could not determine jobType(Workflow/Coordniator/Bundle"); + } + if (appPath.endsWith("/")) { + return appPath + getDefaultDraftFileName(jobType); } else { - return appPath + "/" + Constants.DEFAULT_DRAFT_FILENAME; + return appPath + "/" + getDefaultDraftFileName(jobType); } } - public String getWorkflowFileName(String appPath) { + public String getWorkflowFileName(String appPath, JobType jobType) { if (appPath.endsWith(Constants.WF_EXTENSION)) { return appPath; } else if (appPath.endsWith(Constants.WF_DRAFT_EXTENSION)) { String folderPath = appPath.substring(0, appPath.lastIndexOf(Constants.WF_DRAFT_EXTENSION)); return folderPath + Constants.WF_EXTENSION; } else if (appPath.endsWith("/")) { - return appPath + Constants.DEFAULT_WORKFLOW_FILENAME; + return appPath + getDefaultFileName(jobType); } else { - return appPath + "/" + Constants.DEFAULT_WORKFLOW_FILENAME; + return appPath + "/" + getDefaultFileName(jobType); + } + } + + private String getDefaultFileName(JobType jobType){ + switch (jobType){ + case BUNDLE: + return Constants.DEFAULT_BUNDLE_FILENAME+Constants.WF_EXTENSION; + case COORDINATOR: + return Constants.DEFAULT_COORDINATOR_FILENAME+Constants.WF_EXTENSION; + case WORKFLOW: + return Constants.DEFAULT_WORKFLOW_FILENAME+Constants.WF_EXTENSION; + default: + return null; + } + } + private String getDefaultDraftFileName(JobType jobType) { + switch (jobType){ + case BUNDLE: + return Constants.DEFAULT_BUNDLE_FILENAME+Constants.WF_DRAFT_EXTENSION; + case COORDINATOR: + return Constants.DEFAULT_COORDINATOR_FILENAME+Constants.WF_DRAFT_EXTENSION; + case WORKFLOW: + return Constants.DEFAULT_WORKFLOW_FILENAME+Constants.WF_DRAFT_EXTENSION; + default: + return null; } } @@ -96,26 +125,29 @@ public class WorkflowFilesService { } public void discardDraft(String workflowPath) throws IOException { - hdfsFileUtils.deleteFile(getWorkflowDraftFileName(workflowPath)); + hdfsFileUtils.deleteFile(getWorkflowDraftFileName(workflowPath,null)); } - public WorkflowFileInfo getWorkflowDetails(String appPath) { + public WorkflowFileInfo getWorkflowDetails(String appPath, JobType jobType) { + appPath=appPath.trim(); WorkflowFileInfo workflowInfo = new WorkflowFileInfo(); - workflowInfo.setWorkflowPath(getWorkflowFileName(appPath)); + workflowInfo.setWorkflowPath(appPath); boolean draftExists = hdfsFileUtils - .fileExists(getWorkflowDraftFileName(appPath)); + .fileExists(getWorkflowDraftFileName(appPath,jobType + )); workflowInfo.setDraftExists(draftExists); - boolean workflowExists = hdfsFileUtils.fileExists(getWorkflowFileName(appPath)); + boolean workflowExists = hdfsFileUtils.fileExists(appPath); + workflowInfo.setWorkflowDefinitionExists(workflowExists); FileStatus workflowFileStatus = null; if (workflowExists) { workflowFileStatus = hdfsFileUtils - .getFileStatus(getWorkflowFileName(appPath)); + .getFileStatus(appPath); workflowInfo.setWorkflowModificationTime(workflowFileStatus .getModificationTime()); } if (draftExists) { FileStatus draftFileStatus = hdfsFileUtils - .getFileStatus(getWorkflowDraftFileName(appPath)); + .getFileStatus(getWorkflowDraftFileName(appPath,jobType)); workflowInfo.setDraftModificationTime(draftFileStatus .getModificationTime()); if (!workflowExists) { http://git-wip-us.apache.org/repos/asf/ambari/blob/8b4dd3a4/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/workflowmanager/WorkflowManagerService.java ---------------------------------------------------------------------- diff --git a/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/workflowmanager/WorkflowManagerService.java b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/workflowmanager/WorkflowManagerService.java index 7ce6081..fc08b80 100644 --- a/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/workflowmanager/WorkflowManagerService.java +++ b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/workflowmanager/WorkflowManagerService.java @@ -29,7 +29,7 @@ import java.util.Collection; public class WorkflowManagerService { private final static Logger LOGGER = LoggerFactory - .getLogger(WorkflowManagerService.class); + .getLogger(WorkflowManagerService.class); private final WorkflowsRepo workflowsRepository; private final WorkflowFilesService workflowFilesService; @@ -46,18 +46,18 @@ public class WorkflowManagerService { Workflow workflowById = workflowsRepository.findById(projectId); if (workflowById == null) { throw new RuntimeException("could not find project with id :" - + projectId); + + projectId); } setWorkflowAttributes(jobType, userName, name, workflowById); workflowsRepository.update(workflowById); } else { - String workflowFileName = workflowFilesService.getWorkflowFileName(path); + String workflowFileName = workflowFilesService.getWorkflowFileName(path, jobType); Workflow workflowByPath = workflowsRepository.getWorkflowByPath(workflowFileName); - if (workflowByPath!=null){ + if (workflowByPath != null) { setWorkflowAttributes(jobType, userName, name, workflowByPath); workflowsRepository.update(workflowByPath); - }else{ + } else { Workflow wf = new Workflow(); wf.setId(workflowsRepository.generateId()); setWorkflowAttributes(jobType, userName, name, wf); http://git-wip-us.apache.org/repos/asf/ambari/blob/8b4dd3a4/contrib/views/wfmanager/src/main/resources/ui/app/components/bundle-config.js ---------------------------------------------------------------------- diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/bundle-config.js b/contrib/views/wfmanager/src/main/resources/ui/app/components/bundle-config.js index 2e0dadb..e29935c 100644 --- a/contrib/views/wfmanager/src/main/resources/ui/app/components/bundle-config.js +++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/bundle-config.js @@ -89,6 +89,9 @@ export default Ember.Component.extend(Ember.Evented, Validations, { this.sendAction('changeTabName', this.get('tabInfo'), this.get('bundle.name')); } }), + bundleFilePath : Ember.computed('tabInfo.filePath', function(){ + return this.get('tabInfo.filePath'); + }), schedulePersistWorkInProgress (){ Ember.run.later(function(){ this.persistWorkInProgress(); @@ -133,18 +136,46 @@ export default Ember.Component.extend(Ember.Evented, Validations, { }, importBundle (filePath){ this.set("bundleFilePath", filePath); - this.set("isImporting", false); + this.set("isImporting", true); filePath = this.appendFileName(filePath, 'bundle'); - var deferred = this.getFromHdfs(filePath); - deferred.promise.then(function(data){ - this.getBundleFromXml(data); + var deferred = this.getBundleFromHdfs(filePath); + deferred.promise.then(function(response){ + if(response.type === 'xml'){ + this.getBundleFromXml(response.data); + }else{ + this.getBundleFromJSON(response.data); + } + this.set('bundleFilePath', filePath); this.set("isImporting", false); }.bind(this)).catch(function(e){ this.set("isImporting", false); this.set("isImportingSuccess", false); - throw new Error(e); + throw new Error(e); }.bind(this)); }, + getBundleFromJSON(filePath){ + this.set('bundle', JSON.parse(draftBundle)); + }, + getBundleFromHdfs(filePath){ + var url = Ember.ENV.API_URL + "/readWorkflow?workflowPath="+filePath+"&jobType=BUNDLE"; + var deferred = Ember.RSVP.defer(); + Ember.$.ajax({ + url: url, + method: 'GET', + dataType: "text", + beforeSend: function (xhr) { + xhr.setRequestHeader("X-XSRF-HEADER", Math.round(Math.random()*100000)); + xhr.setRequestHeader("X-Requested-By", "Ambari"); + } + }).done(function(data, status, xhr){ + var type = xhr.getResponseHeader("response-type") === "xml" ? 'xml' : 'json'; + deferred.resolve({data : data, type : type}); + }).fail(function(e){ + console.error(e); + deferred.reject(); + }); + return deferred; + }, getFromHdfs(filePath){ var url = Ember.ENV.API_URL + "/readWorkflowXml?workflowXmlPath="+filePath; var deferred = Ember.RSVP.defer(); @@ -194,7 +225,9 @@ export default Ember.Component.extend(Ember.Evented, Validations, { return deferred; }, appendFileName(filePath, type){ - if(!filePath.endsWith('.xml') && type === 'bundle'){ + if(filePath.endsWith('.wfdraft')){ + return filePath; + }else if(!filePath.endsWith('.xml') && type === 'bundle'){ return filePath = `${filePath}/bundle.xml`; }else if(!filePath.endsWith('.xml') && type === 'coord'){ return filePath = `${filePath}/coordinator.xml`; @@ -263,8 +296,12 @@ export default Ember.Component.extend(Ember.Evented, Validations, { this.set('showingResetConfirmation', true); }, resetBundle(){ - this.set('bundle', this.createBundle()); - this.set('errors').clear(); + this.get('errors').clear(); + if(this.get('bundleFilePath')){ + this.importBundle(this.get('bundleFilePath')); + }else { + this.set('bundle', this.createBundle()); + } }, closeBundleSubmitConfig(){ this.set("showingJobConfig", false); http://git-wip-us.apache.org/repos/asf/ambari/blob/8b4dd3a4/contrib/views/wfmanager/src/main/resources/ui/app/components/coord-config.js ---------------------------------------------------------------------- diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/coord-config.js b/contrib/views/wfmanager/src/main/resources/ui/app/components/coord-config.js index bba7793..fa664c7 100644 --- a/contrib/views/wfmanager/src/main/resources/ui/app/components/coord-config.js +++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/coord-config.js @@ -141,6 +141,9 @@ export default Ember.Component.extend(Validations, Ember.Evented, { this.sendAction('changeTabName', this.get('tabInfo'), this.get('coordinator.name')); } }), + coordinatorFilePath : Ember.computed('tabInfo.filePath', function(){ + return this.get('tabInfo.filePath'); + }), schedulePersistWorkInProgress (){ Ember.run.later(function(){ this.persistWorkInProgress(); @@ -251,9 +254,14 @@ export default Ember.Component.extend(Validations, Ember.Evented, { filePath = this.appendFileName(filePath, 'coord'); this.set("coordinatorFilePath", filePath); this.set("isImporting", false); - var deferred = this.readFromHdfs(filePath); - deferred.promise.then(function(data){ - this.getCoordinatorFromXml(data); + var deferred = this.readCoordinatorFromHdfs(filePath); + deferred.promise.then(function(response){ + if(response.type === 'xml'){ + this.getCoordinatorFromXml(response.data); + }else { + this.getCoordinatorFromJSON(response.data); + } + this.set('coordinatorFilePath', filePath); this.set("isImporting", false); }.bind(this)).catch(function(e){ this.set("isImporting", false); @@ -261,6 +269,28 @@ export default Ember.Component.extend(Validations, Ember.Evented, { throw new Error(e); }.bind(this)); }, + getCoordinatorFromJSON(draftCoordinator){ + this.set('coordinator', JSON.parse(draftCoordinator)); + }, + readCoordinatorFromHdfs(filePath){ + var url = Ember.ENV.API_URL + "/readWorkflow?workflowPath="+filePath+"&jobType=COORDINATOR"; + var deferred = Ember.RSVP.defer(); + Ember.$.ajax({ + url: url, + method: 'GET', + dataType: "text", + beforeSend: function (xhr) { + xhr.setRequestHeader("X-XSRF-HEADER", Math.round(Math.random()*100000)); + xhr.setRequestHeader("X-Requested-By", "Ambari"); + } + }).done(function(data, status, xhr){ + var type = xhr.getResponseHeader("response-type") === "xml" ? 'xml' : 'json'; + deferred.resolve({data : data, type : type}); + }).fail(function(e){ + deferred.reject(e); + }); + return deferred; + }, readFromHdfs(filePath){ var url = Ember.ENV.API_URL + "/readWorkflowXml?workflowXmlPath="+filePath; var deferred = Ember.RSVP.defer(); @@ -280,7 +310,9 @@ export default Ember.Component.extend(Validations, Ember.Evented, { return deferred; }, appendFileName(filePath, type){ - if(!filePath.endsWith('.xml') && type === 'coord'){ + if(filePath.endsWith('.wfdraft')){ + return filePath; + }else if(!filePath.endsWith('.xml') && type === 'coord'){ return filePath = `${filePath}/coordinator.xml`; }else if(!filePath.endsWith('.xml') && type === 'wf'){ return filePath = `${filePath}/workflow.xml`; @@ -517,8 +549,12 @@ export default Ember.Component.extend(Validations, Ember.Evented, { this.set('showingResetConfirmation', true); }, resetCoordinator(){ - this.set('coordinator', this.createNewCoordinator()); this.get("errors").clear(); + if(this.get('coordinatorFilePath')){ + this.importCoordinator(this.get('coordinatorFilePath')); + }else{ + this.set('coordinator', this.createNewCoordinator()); + } }, importCoordinatorTest(){ var deferred = this.importSampleCoordinator(); http://git-wip-us.apache.org/repos/asf/ambari/blob/8b4dd3a4/contrib/views/wfmanager/src/main/resources/ui/app/components/designer-workspace.js ---------------------------------------------------------------------- diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/designer-workspace.js b/contrib/views/wfmanager/src/main/resources/ui/app/components/designer-workspace.js index 422253d..53fd27d 100644 --- a/contrib/views/wfmanager/src/main/resources/ui/app/components/designer-workspace.js +++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/designer-workspace.js @@ -30,7 +30,7 @@ export default Ember.Component.extend({ currentIndex : Ember.computed('tabs.[]', function() { return this.get('tabs').length > 0 ? this.get('tabs').length - 1 : 0; }), - tabsObserver : Ember.observer('tabs.[]', function(){ + tabsObserver : Ember.observer('tabs.[]', 'ta...@each.name', 'tabs.@each.filePath', function(){ this.get('workspaceManager').saveTabs(this.get('tabs')); }), initialize : function(){ http://git-wip-us.apache.org/repos/asf/ambari/blob/8b4dd3a4/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 c682ea9..0a0d2f2 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 @@ -171,6 +171,9 @@ export default Ember.Component.extend(FindNodeMixin, Validations, { this.sendAction('changeTabName', this.get('tabInfo'), this.get('workflow.name')); } }), + workflowFilePath : Ember.computed('tabInfo.filePath', function(){ + return this.get('tabInfo.filePath'); + }), showParentWorkflow(type, path){ this.sendAction('openTab', type, path); }, @@ -301,10 +304,13 @@ export default Ember.Component.extend(FindNodeMixin, Validations, { var self = this; this.set("isWorkflowImporting", true); this.resetDesigner(); - //this.set("isWorkflowImporting", true); var workflowXmlDefered=this.getWorkflowFromHdfs(filePath); - workflowXmlDefered.promise.then(function(data){ - this.importWorkflowFromString(data); + workflowXmlDefered.promise.then(function(response){ + if(response.type === 'xml'){ + this.importWorkflowFromString(response.data); + }else { + this.importWorkflowFromJSON(response.data); + } this.set("isWorkflowImporting", false); this.set("workflowFilePath", filePath); }.bind(this)).catch(function(data){ @@ -331,8 +337,35 @@ export default Ember.Component.extend(FindNodeMixin, Validations, { this.$('#wf_title').focus(); } }, + importWorkflowFromJSON(data){ + var workflowImporter=WorkflowJsonImporter.create({}); + var workflow=workflowImporter.importWorkflow(data); + this.resetDesigner(); + this.set("workflow", workflow); + this.rerender(); + this.doValidation(); + }, getWorkflowFromHdfs(filePath){ - var url = Ember.ENV.API_URL + "/readWorkflowXml?workflowXmlPath="+filePath; + var url = Ember.ENV.API_URL + "/readWorkflow?workflowPath="+filePath+'&jobType=WORKFLOW'; + var deferred = Ember.RSVP.defer(); + Ember.$.ajax({ + url: url, + method: 'GET', + dataType: "text", + beforeSend: function (xhr) { + xhr.setRequestHeader("X-XSRF-HEADER", Math.round(Math.random()*100000)); + xhr.setRequestHeader("X-Requested-By", "Ambari"); + } + }).done(function(data, status, xhr){ + var type = xhr.getResponseHeader("response-type") === "xml" ? 'xml' : 'json'; + deferred.resolve({data : data, type : type}); + }).fail(function(data){ + deferred.reject(data); + }); + return deferred; + }, + getAssetFromHdfs(filePath){ + var url = Ember.ENV.API_URL + "/readAsset?assetPath="+filePath; var deferred = Ember.RSVP.defer(); Ember.$.ajax({ url: url, @@ -439,7 +472,6 @@ export default Ember.Component.extend(FindNodeMixin, Validations, { this.set('errors',[]); this.set('errorMsg',""); this.set('validationErrors',[]); - this.set('workflowFilePath',""); this.get("workflow").resetWorfklow(); this.set('globalConfig', {}); this.set('parameters', {}); @@ -811,7 +843,6 @@ export default Ember.Component.extend(FindNodeMixin, Validations, { this.doValidation(); this.scrollToNewPosition(); }, - nameChanged(){ this.doValidation(); }, @@ -929,30 +960,7 @@ export default Ember.Component.extend(FindNodeMixin, Validations, { var self = this, path = this.get('workflowFilePath'); this.set("showingFileBrowser",false); 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 workflowImporter=WorkflowJsonImporter.create({}); - var workflow=workflowImporter.importWorkflow(data); - - 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); - }); + self.importWorkflow(path); } }, showFileBrowser(){ @@ -1007,10 +1015,14 @@ export default Ember.Component.extend(FindNodeMixin, Validations, { this.set('showingExportActionNodeFileBrowser', true); }, createNewWorkflow(){ - this.resetDesigner(); - this.rerender(); - this.set("workflowFilePath", ""); - this.$('#wf_title').focus(); + if(Ember.isBlank(this.get('workflowFilePath'))){ + this.resetDesigner(); + this.rerender(); + this.set("workflowFilePath", ""); + this.$('#wf_title').focus(); + }else{ + this.importWorkflow(this.get('workflowFilePath')); + } }, conirmCreatingNewWorkflow(){ this.set('showingConfirmationNewWorkflow', true); http://git-wip-us.apache.org/repos/asf/ambari/blob/8b4dd3a4/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 c6c0421..80bea99 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 @@ -53,6 +53,7 @@ export default Ember.Component.extend(Validations, { filePath : Ember.computed.oneWay('jobFilePath',function(){ return Ember.copy(this.get('jobFilePath')); }), + isDraft : Ember.computed.alias('jobConfigs.isDraft'), initialize : function(){ this.set('overwritePath', true); }.on('init'), @@ -82,7 +83,7 @@ export default Ember.Component.extend(Validations, { } }, saveJob(){ - var url = Ember.ENV.API_URL + "/saveWorkflowDraft?app.path=" + this.get("filePath") + "&overwrite=" + this.get("overwritePath"); + var url = Ember.ENV.API_URL + "/saveWorkflowDraft?app.path=" + this.get("filePath") + "&overwrite=" + this.get("overwritePath") + "&jobType="+this.get('displayName').toUpperCase(); this.saveWfJob(url, this.get("jobJson")); if(!this.get('isDraft')){ url = Ember.ENV.API_URL + "/saveWorkflow?app.path=" + this.get("filePath") + "&overwrite=" + this.get("overwritePath"); @@ -91,6 +92,7 @@ export default Ember.Component.extend(Validations, { }, saveWfJob(url, workflowData) { var self = this; + self.set("savingInProgress",true); this.get("saveJobService").saveWorkflow(url, workflowData).promise.then(function(response){ self.showNotification({ "type": "success", http://git-wip-us.apache.org/repos/asf/ambari/blob/8b4dd3a4/contrib/views/wfmanager/src/main/resources/ui/app/services/workspace-manager.js ---------------------------------------------------------------------- diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/services/workspace-manager.js b/contrib/views/wfmanager/src/main/resources/ui/app/services/workspace-manager.js index f5eb6e7..24ab53c 100644 --- a/contrib/views/wfmanager/src/main/resources/ui/app/services/workspace-manager.js +++ b/contrib/views/wfmanager/src/main/resources/ui/app/services/workspace-manager.js @@ -42,7 +42,8 @@ export default Ember.Service.extend({ tabArray.push({ type : tab.type, id : tab.id, - name : tab.name + name : tab.name, + filePath : tab.filePath }); }); console.log("Saving tabs "+JSON.stringify(tabArray)); http://git-wip-us.apache.org/repos/asf/ambari/blob/8b4dd3a4/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/bundle-config.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/bundle-config.hbs b/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/bundle-config.hbs index 8b42447..37150f5 100644 --- a/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/bundle-config.hbs +++ b/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/bundle-config.hbs @@ -35,7 +35,7 @@ <ul class="dropdown-menu"> <li> <a class="pointer" title="Import workflow" {{action "openFileBrowser" "bundleFilePath"}}> - <i class="fa fa-download"> Import</i> + <i class="fa fa-download marginright5"></i>Import </a> </li> <li> @@ -128,7 +128,7 @@ {{/if}} {{#if showingResetConfirmation}} {{#confirmation-dialog title="Confirm Bundle Reset" - confirmationMessage="Any unsaved changes may be lost. Do you want to proceed resetting the bundle ?" + confirmationMessage="File will be reset to last saved version in the HDFS. Do you want to proceed?" okBtnText="Continue" cancelBtnText="Cancel" onOk="resetBundle"}}{{/confirmation-dialog}} {{/if}} {{#if showingPreview}} http://git-wip-us.apache.org/repos/asf/ambari/blob/8b4dd3a4/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/coord-config.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/coord-config.hbs b/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/coord-config.hbs index 296463d..13f3ae7 100644 --- a/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/coord-config.hbs +++ b/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/coord-config.hbs @@ -343,7 +343,7 @@ {{/if}} {{#if showingResetConfirmation}} {{#confirmation-dialog title="Confirm Coordinator Reset" -confirmationMessage="Any unsaved changes may be lost. Do you want to proceed resetting the coordinator ?" +confirmationMessage="File will be reset to last saved version in the HDFS. Do you want to proceed?" okBtnText="Continue" cancelBtnText="Cancel" onOk="resetCoordinator"}}{{/confirmation-dialog}} {{/if}} {{#if showingPreview}} http://git-wip-us.apache.org/repos/asf/ambari/blob/8b4dd3a4/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 1758946..2b8844e 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 @@ -313,7 +313,7 @@ {{/if}} {{#if showingConfirmationNewWorkflow}} {{#confirmation-dialog title="Confirm workflow reset" - confirmationMessage="Any unsaved changes may be lost. Do you want to proceed resetting the workflow ?" + confirmationMessage="File will be reset to last saved version in the HDFS. Do you want to proceed?" okBtnText="Continue" cancelBtnText="Cancel" onOk="createNewWorkflow"}}{{/confirmation-dialog}} {{/if}} {{#if showCreateKillNode}}