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/27 18:17:44 UTC

[33/49] ambari git commit: AMBARI-19610. User is not able to import the draft version for a coordinator. (Padma Priya N via gauravn7)

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 <gr...@gmail.com>
Authored: Fri Jan 27 11:23:55 2017 +0530
Committer: Gaurav Nagar <gr...@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.[]', 'tabs.@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}}