You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ni...@apache.org on 2016/12/16 09:33:00 UTC
[4/4] ambari git commit: AMBARI-19031: UI Enhancements,
import/export assets and smart version configuration (Padma Priya via
nitirajrathore)
AMBARI-19031: UI Enhancements, import/export assets and smart version configuration (Padma Priya via nitirajrathore)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/9bc0b996
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/9bc0b996
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/9bc0b996
Branch: refs/heads/branch-2.5
Commit: 9bc0b99609e8c746d055dafc5c42eea60a6b80ed
Parents: c63d692
Author: Nitiraj Rathore <ni...@gmail.com>
Authored: Fri Dec 16 15:01:36 2016 +0530
Committer: Nitiraj Rathore <ni...@gmail.com>
Committed: Fri Dec 16 15:01:36 2016 +0530
----------------------------------------------------------------------
contrib/views/wfmanager/pom.xml | 9 +-
.../apache/oozie/ambari/view/AmbariIOUtil.java | 65 +++
.../apache/oozie/ambari/view/HDFSFileUtils.java | 46 +-
.../ambari/view/OozieProxyImpersonator.java | 236 +++++++---
.../apache/oozie/ambari/view/OozieUtils.java | 52 +++
.../oozie/ambari/view/WorkflowFileInfo.java | 64 +++
.../oozie/ambari/view/WorkflowFilesService.java | 116 +++++
.../oozie/ambari/view/assets/AssetRepo.java | 42 ++
.../oozie/ambari/view/assets/AssetService.java | 51 +++
.../ambari/view/assets/model/ActionAsset.java | 60 +++
.../oozie/ambari/view/model/BaseModel.java | 48 ++
.../workflowmanager/WorkflowManagerService.java | 76 ++++
.../WorkflowsManagerResource.java | 51 +++
.../view/workflowmanager/WorkflowsRepo.java | 69 +++
.../view/workflowmanager/model/Workflow.java | 88 ++++
.../ui/app/components/bundle-config.js | 18 +-
.../ui/app/components/bundle-coord-config.js | 2 +-
.../app/components/bundle-version-settings.js | 49 +++
.../resources/ui/app/components/coord-config.js | 30 +-
.../ui/app/components/coord-version-settings.js | 49 +++
.../ui/app/components/date-with-expr.js | 1 -
.../ui/app/components/designer-workspace.js | 63 ++-
.../ui/app/components/flow-designer.js | 433 +++++++++++++++++--
.../resources/ui/app/components/hdfs-browser.js | 3 +-
.../ui/app/components/import-from-stream.js | 67 +++
.../resources/ui/app/components/job-config.js | 2 +-
.../resources/ui/app/components/job-details.js | 28 +-
.../main/resources/ui/app/components/job-row.js | 4 +
.../ui/app/components/name-value-config.js | 1 -
.../ui/app/components/preview-dialog.js | 7 +
.../main/resources/ui/app/components/save-wf.js | 49 +--
.../ui/app/components/search-create-new-bar.js | 17 +-
.../ui/app/components/workflow-actions.js | 8 +
.../ui/app/components/workflow-icon.js | 21 +
.../ui/app/controllers/design/dashboardtab.js | 81 ++++
.../ui/app/controllers/design/jobtab.js | 59 +++
.../main/resources/ui/app/controllers/job.js | 30 +-
.../app/domain/bundle/bundle-xml-generator.js | 2 +-
.../ui/app/domain/bundle/bundle-xml-importer.js | 20 +-
.../coordinator/coordinator-xml-generator.js | 2 +-
.../coordinator/coordinator-xml-importer.js | 22 +-
.../ui/app/domain/cytoscape-flow-renderer.js | 13 +-
.../resources/ui/app/domain/mapping-utils.js | 2 +-
.../resources/ui/app/domain/schema-versions.js | 165 ++++++-
.../ui/app/domain/workflow-importer.js | 35 +-
.../ui/app/domain/workflow-xml-generator.js | 15 +
.../src/main/resources/ui/app/router.js | 5 +-
.../main/resources/ui/app/routes/dashboard.js | 4 +-
.../src/main/resources/ui/app/routes/design.js | 15 +-
.../ui/app/routes/design/dashboardtab.js | 154 +++++++
.../resources/ui/app/routes/design/jobtab.js | 94 ++++
.../src/main/resources/ui/app/routes/index.js | 2 +-
.../src/main/resources/ui/app/routes/job.js | 29 +-
.../ui/app/services/dashboard-context.js | 38 ++
.../main/resources/ui/app/services/save-job.js | 42 ++
.../src/main/resources/ui/app/styles/app.less | 72 ++-
.../app/templates/components/bundle-config.hbs | 42 +-
.../components/bundle-coord-config.hbs | 17 +-
.../templates/components/bundle-job-details.hbs | 12 +-
.../components/bundle-version-settings.hbs | 45 ++
.../app/templates/components/coord-config.hbs | 359 +++++++--------
.../templates/components/coord-job-details.hbs | 6 +-
.../components/coord-version-settings.hbs | 45 ++
.../templates/components/designer-workspace.hbs | 119 ++---
.../app/templates/components/flow-designer.hbs | 154 +++++--
.../app/templates/components/hdfs-browser.hbs | 2 +-
.../templates/components/import-from-stream.hbs | 63 +++
.../ui/app/templates/components/job-config.hbs | 10 +-
.../ui/app/templates/components/job-details.hbs | 34 +-
.../ui/app/templates/components/job-row.hbs | 14 +-
.../app/templates/components/preview-dialog.hbs | 5 +-
.../components/search-create-new-bar.hbs | 2 +-
.../app/templates/components/search-table.hbs | 3 +-
.../templates/components/workflow-actions.hbs | 8 +-
.../app/templates/components/workflow-icon.hbs | 24 +
.../components/workflow-job-details.hbs | 28 +-
.../main/resources/ui/app/templates/design.hbs | 2 +-
.../ui/app/templates/design/dashboardtab.hbs | 30 ++
.../ui/app/templates/design/jobtab.hbs | 21 +
.../src/main/resources/ui/app/templates/job.hbs | 2 +-
.../main/resources/ui/app/utils/common-utils.js | 3 +
.../main/resources/ui/app/utils/constants.js | 2 +-
.../wfmanager/src/main/resources/ui/bower.json | 3 +-
.../src/main/resources/ui/ember-cli-build.js | 7 +
.../src/main/resources/ui/package.json | 4 +-
.../components/bundle-version-settings-test.js | 40 ++
.../components/coord-version-settings-test.js | 40 ++
.../components/import-from-stream-test.js | 41 ++
.../components/workflow-icon-test.js | 40 ++
.../unit/routes/design/dashboardtab-test.js | 27 ++
.../unit/services/dashboard-context-test.js | 28 ++
.../ui/tests/unit/services/save-job-test.js | 29 ++
92 files changed, 3530 insertions(+), 607 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/9bc0b996/contrib/views/wfmanager/pom.xml
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/pom.xml b/contrib/views/wfmanager/pom.xml
index b8578ac..95b988f 100644
--- a/contrib/views/wfmanager/pom.xml
+++ b/contrib/views/wfmanager/pom.xml
@@ -213,12 +213,11 @@
<goal>exec</goal>
</goals>
<configuration>
- <workingDirectory>${basedir}/src/main/resources/ui</workingDirectory>
- <executable>node/node</executable>
+ <workingDirectory>${ui.directory}</workingDirectory>
+ <executable>${ui.directory}/node_modules/.bin/${ember.executable}</executable>
<arguments>
- <argument>node_modules/.bin/ember</argument>
<argument>build</argument>
-
+ <argument>-prod</argument>
</arguments>
</configuration>
</execution>
@@ -303,6 +302,7 @@
</activation>
<properties>
<node.executable>node.exe</node.executable>
+ <ember.executable>ember.cmd</ember.executable>
<skip.nodegyp.chmod>true</skip.nodegyp.chmod>
</properties>
</profile>
@@ -315,6 +315,7 @@
</activation>
<properties>
<node.executable>node</node.executable>
+ <ember.executable>ember</ember.executable>
<skip.nodegyp.chmod>false</skip.nodegyp.chmod>
</properties>
</profile>
http://git-wip-us.apache.org/repos/asf/ambari/blob/9bc0b996/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/AmbariIOUtil.java
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/AmbariIOUtil.java b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/AmbariIOUtil.java
new file mode 100644
index 0000000..93447b7
--- /dev/null
+++ b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/AmbariIOUtil.java
@@ -0,0 +1,65 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.oozie.ambari.view;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+
+import org.apache.ambari.view.URLStreamProvider;
+import org.apache.ambari.view.ViewContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AmbariIOUtil {
+ private final static Logger LOGGER = LoggerFactory
+ .getLogger(AmbariIOUtil.class);
+ private ViewContext viewContext;
+
+ public AmbariIOUtil(ViewContext viewContext) {
+ super();
+ this.viewContext = viewContext;
+ }
+
+ public InputStream readFromUrl(String urlToRead, String method,
+ String body, Map<String, String> newHeaders) {
+ URLStreamProvider streamProvider = viewContext.getURLStreamProvider();
+ InputStream stream = null;
+ try {
+ if (isSecurityEnabled()) {
+ stream = streamProvider.readAsCurrent(urlToRead, method, body,
+ newHeaders);
+
+ } else {
+ stream = streamProvider.readFrom(urlToRead, method, body,
+ newHeaders);
+ }
+ } catch (IOException e) {
+ LOGGER.error("error talking to oozie", e);
+ throw new RuntimeException(e);
+ }
+ return stream;
+ }
+
+ private boolean isSecurityEnabled() {
+ String authType = viewContext.getCluster().getConfigurationValue(
+ "core-site", "hadoop.security.authentication");
+ LOGGER.info("Auth Type=" + authType);
+ return !"simple".equalsIgnoreCase(authType);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9bc0b996/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/HDFSFileUtils.java
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/HDFSFileUtils.java b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/HDFSFileUtils.java
index 58c3980..327d8fc 100644
--- a/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/HDFSFileUtils.java
+++ b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/HDFSFileUtils.java
@@ -17,6 +17,7 @@
*/
package org.apache.oozie.ambari.view;
+import java.io.FileNotFoundException;
import java.io.IOException;
import org.apache.ambari.view.ViewContext;
@@ -24,6 +25,7 @@ import org.apache.ambari.view.utils.hdfs.HdfsApi;
import org.apache.ambari.view.utils.hdfs.HdfsUtil;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
+import org.apache.hadoop.fs.FileStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -36,10 +38,10 @@ public class HDFSFileUtils {
super();
this.viewContext = viewContext;
}
+
public boolean fileExists(String path) {
- boolean fileExists;
try {
- fileExists = getHdfsgetApi().exists(path);
+ return getHdfsgetApi().exists(path);
} catch (IOException e) {
LOGGER.error(e.getMessage(), e);
throw new RuntimeException(e);
@@ -47,11 +49,9 @@ public class HDFSFileUtils {
LOGGER.error(e.getMessage(), e);
throw new RuntimeException(e);
}
- LOGGER.info("FILE exists for [" + path + "] returned [" + fileExists
- + "]");
- return fileExists;
}
- public FSDataInputStream read(String filePath)throws IOException{
+
+ public FSDataInputStream read(String filePath) throws IOException {
FSDataInputStream is;
try {
is = getHdfsgetApi().open(filePath);
@@ -60,19 +60,28 @@ public class HDFSFileUtils {
}
return is;
}
- public String createWorkflowFile( String workflowFile,String postBody,
- boolean overwrite) throws IOException {
+
+ public String writeToFile(String filePath, String content, boolean overwrite)
+ throws IOException {
FSDataOutputStream fsOut;
try {
- fsOut = getHdfsgetApi().create(workflowFile,
- overwrite);
+ fsOut = getHdfsgetApi().create(filePath, overwrite);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
- fsOut.write(postBody.getBytes());
+ fsOut.write(content.getBytes());
fsOut.close();
- return workflowFile;
+ return filePath;
+ }
+
+ public void deleteFile(String filePath) throws IOException {
+ try {
+ getHdfsgetApi().delete(filePath, false);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
}
+
private HdfsApi getHdfsgetApi() {
try {
return HdfsUtil.connectToHDFSApi(viewContext);
@@ -84,4 +93,17 @@ public class HDFSFileUtils {
}
}
+ public FileStatus getFileStatus(String filePath) {
+ try {
+ return getHdfsgetApi().getFileStatus(filePath);
+ } catch (FileNotFoundException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9bc0b996/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 0533f04..08a166d 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
@@ -45,13 +45,13 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
import javax.ws.rs.core.UriInfo;
-import org.apache.ambari.view.URLStreamProvider;
import org.apache.ambari.view.ViewContext;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
-import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.security.AccessControlException;
+import org.apache.oozie.ambari.view.workflowmanager.WorkflowManagerService;
+import org.apache.oozie.ambari.view.workflowmanager.WorkflowsManagerResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -81,9 +81,13 @@ public class OozieProxyImpersonator {
private static final String SERVICE_URI_PROP = "oozie.service.uri";
private static final String DEFAULT_SERVICE_URI = "http://sandbox.hortonworks.com:11000/oozie";
- private Utils utils=new Utils();
- private OozieUtils oozieUtils=new OozieUtils();
+ private Utils utils = new Utils();
+ private AmbariIOUtil ambariIOUtil;
+ private OozieUtils oozieUtils = new OozieUtils();
private HDFSFileUtils hdfsFileUtils;
+ private WorkflowFilesService workflowFilesService;
+ //private WorkflowManagerService workflowManagerService;
+
private static enum ErrorCodes {
OOZIE_SUBMIT_ERROR("error.oozie.submit", "Oozie Submit error"), OOZIE_IO_ERROR(
"error.oozie.io", "Oozie I/O error"), FILE_ACCESS_ACL_ERROR(
@@ -111,10 +115,14 @@ public class OozieProxyImpersonator {
@Inject
public OozieProxyImpersonator(ViewContext viewContext) {
this.viewContext = viewContext;
- hdfsFileUtils=new HDFSFileUtils(viewContext);
+ hdfsFileUtils = new HDFSFileUtils(viewContext);
+ workflowFilesService = new WorkflowFilesService(hdfsFileUtils);
+ ambariIOUtil=new AmbariIOUtil(viewContext);
+ //workflowManagerService = new WorkflowManagerService(viewContext);
LOGGER.info(String.format(
"OozieProxyImpersonator initialized for instance: %s",
viewContext.getInstanceName()));
+
}
@Path("/fileServices")
@@ -122,6 +130,11 @@ public class OozieProxyImpersonator {
return new FileServices(viewContext);
}
+ @Path("/wfprojects")
+ public WorkflowsManagerResource workflowsManagerResource() {
+ return new WorkflowsManagerResource(viewContext);
+ }
+
@GET
@Path("/getCurrentUserName")
public Response getCurrentUserName() {
@@ -171,9 +184,12 @@ public class OozieProxyImpersonator {
}
postBody = utils.formatXml(postBody);
try {
- String filePath = hdfsFileUtils.createWorkflowFile(getWorkflowFileName(appPath),postBody, overwrite);
+ String filePath = workflowFilesService.createWorkflowFile(appPath,
+ postBody, overwrite);
LOGGER.info(String.format(
"submit workflow job done. filePath=[%s]", filePath));
+ /* workflowManagerService.saveWorkflow(appPath, JobType.WORKFLOW,
+ "todo description", viewContext.getUsername());*/
return Response.ok().build();
} catch (Exception ex) {
LOGGER.error(ex.getMessage(), ex);
@@ -181,6 +197,125 @@ public class OozieProxyImpersonator {
}
}
+
+ @POST
+ @Path("/publishAsset")
+ @Consumes({ MediaType.TEXT_PLAIN + "," + MediaType.TEXT_XML })
+ public Response publishAsset(String postBody, @Context HttpHeaders headers,
+ @Context UriInfo ui, @QueryParam("uploadPath") String uploadPath,
+ @DefaultValue("false") @QueryParam("overwrite") Boolean overwrite) {
+ LOGGER.info("publish asset called");
+ if (StringUtils.isEmpty(uploadPath)) {
+ throw new RuntimeException("upload path can't be empty.");
+ }
+ uploadPath = uploadPath.trim();
+ Response dryRunResponse = validateAsset(headers, postBody, ui.getQueryParameters());
+ if (dryRunResponse.getStatus() == 200) {
+ return saveAsset(postBody, uploadPath, overwrite);
+ }
+ return dryRunResponse;
+ }
+
+ private Response validateAsset(HttpHeaders headers, String postBody, MultivaluedMap<String, String> queryParams) {
+ String workflowXml = oozieUtils.generateWorkflowXml(postBody);
+ try {
+ String tempWfPath = "/user/"+viewContext.getUsername()+"/tmpooziewfs/tempwf.xml";
+ hdfsFileUtils.writeToFile(tempWfPath, workflowXml, true);
+ queryParams.put("oozieparam.action",getAsList("dryrun"));
+ queryParams.put("oozieconfig.rerunOnFailure",getAsList("false"));
+ queryParams.put("oozieconfig.useSystemLibPath",getAsList("true"));
+ queryParams.put("resourceManager",getAsList("useDefault"));
+ String dryRunResp = submitWorkflowJobToOozie(headers,tempWfPath,queryParams,JobType.WORKFLOW);
+ LOGGER.info(String.format("resp from validating asset=[%s]",dryRunResp));
+ if (dryRunResp != null && dryRunResp.trim().startsWith("{")) {
+ return Response.status(Response.Status.OK).entity(dryRunResp).build();
+ } else {
+ HashMap<String, String> resp = new HashMap<String, String>();
+ resp.put("status", ErrorCodes.OOZIE_SUBMIT_ERROR.getErrorCode());
+ resp.put("message", dryRunResp);
+ //resp.put("stackTrace", dryRunResp);
+ return Response.status(Response.Status.BAD_REQUEST).entity(resp).build();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private List<String> getAsList(String string) {
+ ArrayList<String> li=new ArrayList<>(1);
+ li.add(string);
+ return li;
+ }
+
+ private Response saveAsset(String postBody, String uploadPath,
+ Boolean overwrite) {
+ uploadPath = workflowFilesService.getAssetFileName(uploadPath);
+ if (!overwrite) {
+ boolean fileExists = hdfsFileUtils.fileExists(uploadPath);
+ if (fileExists) {
+ return getFileExistsResponse();
+ }
+ }
+ postBody = utils.formatXml(postBody);
+ try {
+ String filePath = workflowFilesService.createAssetFile(uploadPath,
+ postBody, overwrite);
+ LOGGER.info(String.format(
+ "publish asset job done. filePath=[%s]", filePath));
+ return Response.ok().build();
+ } catch (Exception ex) {
+ LOGGER.error(ex.getMessage(), ex);
+ return getRespCodeForException(ex);
+ }
+ }
+
+ @POST
+ @Path("/saveWorkflowDraft")
+ @Consumes({ MediaType.TEXT_PLAIN + "," + MediaType.TEXT_XML })
+ public Response saveDraft(String postBody, @Context HttpHeaders headers,
+ @Context UriInfo ui, @QueryParam("app.path") String appPath,
+ @DefaultValue("false") @QueryParam("overwrite") Boolean overwrite)
+ throws IOException {
+ LOGGER.info("save workflow called");
+ if (StringUtils.isEmpty(appPath)) {
+ throw new RuntimeException("app path can't be empty.");
+ }
+ appPath = appPath.trim();
+ workflowFilesService.saveDraft(appPath, postBody, overwrite);
+ /* workflowManagerService.saveWorkflow(appPath, JobType.WORKFLOW,
+ "todo description", viewContext.getUsername());*/
+ return Response.ok().build();
+ }
+
+ @GET
+ @Path("/readWorkflowDraft")
+ public Response readDraft(@QueryParam("workflowXmlPath") String workflowPath) {
+ if (StringUtils.isEmpty(workflowPath)) {
+ throw new RuntimeException("workflowXmlPath can't be empty.");
+ }
+ try {
+ final InputStream is = workflowFilesService.readDraft(workflowPath);
+ 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).status(200).build();
+ } catch (IOException e) {
+ return getRespCodeForException(e);
+ }
+ }
+
+ @POST
+ @Path("/discardWorkflowDraft")
+ public Response discardDraft(@QueryParam("workflowXmlPath") String workflowPath) throws IOException{
+ workflowFilesService.discardDraft(workflowPath);
+ return Response.ok().build();
+ }
private Response submitJobInternal(String postBody, HttpHeaders headers,
UriInfo ui, String appPath, Boolean overwrite, JobType jobType) {
@@ -196,7 +331,8 @@ public class OozieProxyImpersonator {
}
postBody = utils.formatXml(postBody);
try {
- String filePath = hdfsFileUtils.createWorkflowFile(getWorkflowFileName(appPath),postBody,overwrite);
+ String filePath = hdfsFileUtils.writeToFile(appPath, postBody,
+ overwrite);
LOGGER.info(String.format(
"submit workflow job done. filePath=[%s]", filePath));
} catch (Exception ex) {
@@ -204,6 +340,8 @@ public class OozieProxyImpersonator {
return getRespCodeForException(ex);
}
+ /* workflowManagerService.saveWorkflow(appPath, jobType,
+ "todo description", viewContext.getUsername());*/
String response = submitWorkflowJobToOozie(headers, appPath,
ui.getQueryParameters(), jobType);
if (response != null && response.trim().startsWith("{")) {
@@ -226,21 +364,20 @@ public class OozieProxyImpersonator {
ErrorCodes.FILE_ACCESS_ACL_ERROR.getDescription(), ex);
return Response.status(Response.Status.BAD_REQUEST)
.entity(errorDetails).build();
- }else if (ex instanceof IOException){
+ } else if (ex instanceof IOException) {
HashMap<String, String> errorDetails = getErrorDetails(
ErrorCodes.FILE_ACCESS_UNKNOWN_ERROR.getErrorCode(),
ErrorCodes.FILE_ACCESS_UNKNOWN_ERROR.getDescription(), ex);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity(errorDetails).build();
- }else {
+ } else {
HashMap<String, String> errorDetails = getErrorDetails(
ErrorCodes.FILE_ACCESS_UNKNOWN_ERROR.getErrorCode(),
ErrorCodes.FILE_ACCESS_UNKNOWN_ERROR.getDescription(), ex);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity(errorDetails).build();
}
-
-
+
}
private Response getFileExistsResponse() {
@@ -250,18 +387,14 @@ public class OozieProxyImpersonator {
return Response.status(Response.Status.BAD_REQUEST).entity(resp)
.build();
}
-
- private String getWorkflowFileName(String appPath) {
- String workflowFile = null;
- if (appPath.endsWith(".xml")) {
- workflowFile = appPath;
- } else {
- workflowFile = appPath + (appPath.endsWith("/") ? "" : "/")
- + "workflow.xml";
- }
- return workflowFile;
+
+ @GET
+ @Path("/readWorkflowDetail")
+ public Response isDraftAvailable(@QueryParam("workflowXmlPath") String workflowPath){
+ WorkflowFileInfo workflowDetails = workflowFilesService.getWorkflowDetails(workflowPath);
+ return Response.ok(workflowDetails).build();
}
-
+
@GET
@Path("/readWorkflowXml")
public Response readWorkflowXxml(
@@ -270,7 +403,7 @@ public class OozieProxyImpersonator {
throw new RuntimeException("workflowXmlPath can't be empty.");
}
try {
- final FSDataInputStream is = hdfsFileUtils.read(workflowPath);
+ final InputStream is = workflowFilesService.readWorkflowXml(workflowPath);
StreamingOutput streamer = new StreamingOutput() {
@Override
public void write(OutputStream os) throws IOException,
@@ -281,7 +414,7 @@ public class OozieProxyImpersonator {
}
};
return Response.ok(streamer).status(200).build();
- } catch(IOException e){
+ } catch (IOException e) {
return getRespCodeForException(e);
}
}
@@ -405,7 +538,7 @@ public class OozieProxyImpersonator {
queryParams.put("config.nameNode", nameNodes);
}
- HashMap<String, String> workflowConigs = getWorkflowConfigs(filePath,
+ Map<String, String> workflowConigs = getWorkflowConfigs(filePath,
queryParams, jobType, nameNode);
String configXMl = oozieUtils.generateConfigXml(workflowConigs);
LOGGER.info("Config xml==" + configXMl);
@@ -415,7 +548,7 @@ public class OozieProxyImpersonator {
+ "/v2/jobs?" + getJobSumbitOozieParams(queryParams),
HttpMethod.POST, configXMl, customHeaders);
- LOGGER.info("REsp from oozie status entity=="
+ LOGGER.info("Resp from oozie status entity=="
+ serviceResponse.getEntity());
if (serviceResponse.getEntity() instanceof String) {
return (String) serviceResponse.getEntity();
@@ -425,7 +558,7 @@ public class OozieProxyImpersonator {
}
- private HashMap<String, String> getWorkflowConfigs(String filePath,
+ private Map<String, String> getWorkflowConfigs(String filePath,
MultivaluedMap<String, String> queryParams, JobType jobType,
String nameNode) {
HashMap<String, String> workflowConigs = new HashMap<String, String>();
@@ -466,7 +599,8 @@ public class OozieProxyImpersonator {
workflowConigs.put(OOZIE_WF_RERUN_FAILNODES_CONF_KEY, "true");
}
workflowConigs.put("user.name", viewContext.getUsername());
- workflowConigs.put(oozieUtils.getJobPathPropertyKey(jobType), nameNode + filePath);
+ workflowConigs.put(oozieUtils.getJobPathPropertyKey(jobType), nameNode
+ + filePath);
return workflowConigs;
}
@@ -497,10 +631,13 @@ public class OozieProxyImpersonator {
uiURI = uiURI.substring(index);
String serviceURI = getServiceUri();
serviceURI += uiURI;
- MultivaluedMap<String, String> params = addOrReplaceUserName(ui.getQueryParameters());
- return serviceURI+utils.convertParamsToUrl(params);
+ MultivaluedMap<String, String> params = addOrReplaceUserName(ui
+ .getQueryParameters());
+ return serviceURI + utils.convertParamsToUrl(params);
}
- private MultivaluedMap<String, String> addOrReplaceUserName(MultivaluedMap<String, String> parameters){
+
+ private MultivaluedMap<String, String> addOrReplaceUserName(
+ MultivaluedMap<String, String> parameters) {
for (Map.Entry<String, List<String>> entry : parameters.entrySet()) {
if ("user.name".equals(entry.getKey())) {
ArrayList<String> vals = new ArrayList<String>(1);
@@ -521,7 +658,7 @@ public class OozieProxyImpersonator {
String method, String body) throws Exception {
return consumeService(headers, urlToRead, method, body, null);
}
-
+
private Response consumeService(HttpHeaders headers, String urlToRead,
String method, String body, Map<String, String> customHeaders) {
Response response = null;
@@ -539,8 +676,8 @@ public class OozieProxyImpersonator {
.entity(stringResponse).type(MediaType.TEXT_PLAIN).build();
} else {
response = Response.status(Response.Status.OK)
- .entity(stringResponse).type(utils.deduceType(stringResponse))
- .build();
+ .entity(stringResponse)
+ .type(utils.deduceType(stringResponse)).build();
}
return response;
}
@@ -558,36 +695,7 @@ public class OozieProxyImpersonator {
}
LOGGER.info(String.format("Proxy request for url: [%s] %s", method,
urlToRead));
-
- return readFromUrl(urlToRead, method, body, newHeaders);
- }
- private InputStream readFromUrl(String urlToRead, String method, String body,
- Map<String, String> newHeaders) {
- URLStreamProvider streamProvider = viewContext.getURLStreamProvider();
- InputStream stream = null;
- try {
- if (isSecurityEnabled()) {
- stream = streamProvider.readAsCurrent(urlToRead, method, body,
- newHeaders);
-
- } else {
- stream = streamProvider.readFrom(urlToRead, method, body,
- newHeaders);
- }
- } catch (IOException e) {
- LOGGER.error("error talking to oozie", e);
- throw new RuntimeException(e);
- }
- return stream;
+ return ambariIOUtil.readFromUrl(urlToRead, method, body, newHeaders);
}
-
-
- private boolean isSecurityEnabled() {
- String authType = viewContext.getCluster().getConfigurationValue(
- "core-site", "hadoop.security.authentication");
- LOGGER.info("Auth Type=" + authType);
- return !"simple".equalsIgnoreCase(authType);
- }
-
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/9bc0b996/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/OozieUtils.java
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/OozieUtils.java b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/OozieUtils.java
index 170132f..f002102 100644
--- a/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/OozieUtils.java
+++ b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/OozieUtils.java
@@ -17,6 +17,8 @@
*/
package org.apache.oozie.ambari.view;
+import java.io.IOException;
+import java.io.StringReader;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
@@ -27,6 +29,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
public class OozieUtils {
private final static Logger LOGGER = LoggerFactory
@@ -68,4 +72,52 @@ public class OozieUtils {
}
throw new RuntimeException("Unknown Job Type");
}
+
+ public String generateWorkflowXml(String actionNodeXml) {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ DocumentBuilder db;
+ try {
+ db = dbf.newDocumentBuilder();
+ Document doc = db.newDocument();
+
+ Element workflowElement = doc.createElement("workflow-app");
+ workflowElement.setAttribute("name", "testWorkflow");
+ workflowElement.setAttribute("xmlns", "uri:oozie:workflow:0.5");
+ doc.appendChild(workflowElement);
+
+ Element startElement = doc.createElement("start");
+ startElement.setAttribute("to", "testAction");
+ workflowElement.appendChild(startElement);
+
+ Element actionElement = doc.createElement("action");
+ actionElement.setAttribute("name", "testAction");
+ Element actionSettingsElement = db.parse(new InputSource(new StringReader(actionNodeXml))).getDocumentElement();
+ actionElement.appendChild(doc.importNode(actionSettingsElement, true));
+ workflowElement.appendChild(actionElement);
+
+ Element actionOkTransitionElement = doc.createElement("ok");
+ actionOkTransitionElement.setAttribute("to", "end");
+ actionElement.appendChild(actionOkTransitionElement);
+
+ Element actionErrorTransitionElement = doc.createElement("error");
+ actionErrorTransitionElement.setAttribute("to", "kill");
+ actionElement.appendChild(actionErrorTransitionElement);
+
+ Element killElement = doc.createElement("kill");
+ killElement.setAttribute("name", "kill");
+ Element killMessageElement = doc.createElement("message");
+ killMessageElement.setTextContent("Kill node message");
+ killElement.appendChild(killMessageElement);
+ workflowElement.appendChild(killElement);
+
+ Element endElement = doc.createElement("end");
+ endElement.setAttribute("name", "end");
+ workflowElement.appendChild(endElement);
+
+ return utils.generateXml(doc);
+ } catch (ParserConfigurationException | SAXException | IOException e) {
+ LOGGER.error("error in generating workflow xml", e);
+ throw new RuntimeException(e);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9bc0b996/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
new file mode 100644
index 0000000..6dbf30e
--- /dev/null
+++ b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/WorkflowFileInfo.java
@@ -0,0 +1,64 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.oozie.ambari.view;
+
+public class WorkflowFileInfo {
+ private String workflowPath;
+ private String draftPath;
+ private Boolean draftExists;
+ private Boolean isDraftCurrent=false;
+ public Boolean getIsDraftCurrent() {
+ return isDraftCurrent;
+ }
+ public void setIsDraftCurrent(Boolean isDraftCurrent) {
+ this.isDraftCurrent = isDraftCurrent;
+ }
+ private Long workflowModificationTime;
+ private Long draftModificationTime;
+ public String getWorkflowPath() {
+ return workflowPath;
+ }
+ public void setWorkflowPath(String workflowPath) {
+ this.workflowPath = workflowPath;
+ }
+ public String getDraftPath() {
+ return draftPath;
+ }
+ public void setDraftPath(String draftPath) {
+ this.draftPath = draftPath;
+ }
+ public Boolean getDraftExists() {
+ return draftExists;
+ }
+ public void setDraftExists(Boolean draftExists) {
+ this.draftExists = draftExists;
+ }
+ public void setWorkflowModificationTime(Long modificationTime) {
+ this.workflowModificationTime=modificationTime;
+ }
+ public void setDraftModificationTime(Long modificationTime) {
+ this.draftModificationTime=modificationTime;
+ }
+ public Long getWorkflowModificationTime() {
+ return workflowModificationTime;
+ }
+ public Long getDraftModificationTime() {
+ return draftModificationTime;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9bc0b996/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
new file mode 100644
index 0000000..01bde47
--- /dev/null
+++ b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/WorkflowFilesService.java
@@ -0,0 +1,116 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.oozie.ambari.view;
+
+import java.io.IOException;
+import java.io.InputStream;
+import org.apache.hadoop.fs.FileStatus;
+
+public class WorkflowFilesService {
+ private HDFSFileUtils hdfsFileUtils;
+
+ public WorkflowFilesService(HDFSFileUtils hdfsFileUtils) {
+ super();
+ this.hdfsFileUtils = hdfsFileUtils;
+ }
+
+ public String createWorkflowFile(String appPath, String content,
+ boolean overwrite) throws IOException {
+ return hdfsFileUtils.writeToFile(getWorkflowFileName(appPath), content,
+ overwrite);
+ }
+
+ public String createAssetFile(String appPath, String content,
+ boolean overwrite) throws IOException {
+ return hdfsFileUtils.writeToFile(appPath, content,
+ overwrite);
+ }
+
+ public String saveDraft(String appPath, String content, boolean overwrite)
+ throws IOException {
+ return hdfsFileUtils.writeToFile(getWorkflowDrafFileName(appPath),
+ content, overwrite);
+ }
+
+ public InputStream readDraft(String appPath) throws IOException {
+ return hdfsFileUtils.read(getWorkflowDrafFileName(appPath));
+ }
+ public InputStream readWorkflowXml(String appPath) throws IOException {
+ return hdfsFileUtils.read(getWorkflowFileName(appPath));
+ }
+
+ private String getWorkflowDrafFileName(String appPath) {
+ return getWorkflowFileName(appPath).concat(".draft.json");
+ }
+
+ private String getWorkflowFileName(String appPath) {
+ String workflowFile = null;
+ if (appPath.endsWith(".xml")) {
+ workflowFile = appPath;
+ } else {
+ workflowFile = appPath + (appPath.endsWith("/") ? "" : "/")
+ + "workflow.xml";
+ }
+ return workflowFile;
+ }
+
+ public String getAssetFileName(String appPath) {
+ String assetFile = null;
+ if (appPath.endsWith(".xml")) {
+ assetFile = appPath;
+ } else {
+ assetFile = appPath + (appPath.endsWith("/") ? "" : "/")
+ + "asset.xml";
+ }
+ return assetFile;
+ }
+
+ public void discardDraft(String workflowPath) throws IOException {
+ hdfsFileUtils.deleteFile(getWorkflowDrafFileName(workflowPath));
+
+ }
+
+ public WorkflowFileInfo getWorkflowDetails(String appPath) {
+ WorkflowFileInfo workflowInfo = new WorkflowFileInfo();
+ workflowInfo.setWorkflowPath(getWorkflowFileName(appPath));
+ boolean draftExists = hdfsFileUtils
+ .fileExists(getWorkflowDrafFileName(appPath));
+ workflowInfo.setDraftExists(draftExists);
+ boolean workflowExists = hdfsFileUtils.fileExists(getWorkflowFileName(appPath));
+ FileStatus workflowFileStatus = null;
+ if (workflowExists){
+ workflowFileStatus = hdfsFileUtils
+ .getFileStatus(getWorkflowFileName(appPath));
+ workflowInfo.setWorkflowModificationTime(workflowFileStatus
+ .getModificationTime());
+ }
+ if (draftExists) {
+ FileStatus draftFileStatus = hdfsFileUtils
+ .getFileStatus(getWorkflowDrafFileName(appPath));
+ workflowInfo.setDraftModificationTime(draftFileStatus
+ .getModificationTime());
+ if (!workflowExists){
+ workflowInfo.setIsDraftCurrent(true);
+ }else{
+ workflowInfo.setIsDraftCurrent(draftFileStatus.getModificationTime()
+ - workflowFileStatus.getModificationTime() > 0);
+ }
+ }
+ return workflowInfo;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9bc0b996/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/assets/AssetRepo.java
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/assets/AssetRepo.java b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/assets/AssetRepo.java
new file mode 100644
index 0000000..1390ec0
--- /dev/null
+++ b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/assets/AssetRepo.java
@@ -0,0 +1,42 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.oozie.ambari.view.assets;
+
+import java.util.Collection;
+
+import org.apache.ambari.view.DataStore;
+import org.apache.oozie.ambari.view.assets.model.ActionAsset;
+
+public class AssetRepo {
+ private final DataStore dataStore;
+
+ public AssetRepo(DataStore dataStore) {
+ super();
+ this.dataStore = dataStore;
+ }
+ public void saveAsset(ActionAsset asset){
+
+ }
+ public void deleteAsset(ActionAsset asset){
+
+ }
+ public Collection<ActionAsset>listAllAssets(){
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9bc0b996/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/assets/AssetService.java
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/assets/AssetService.java b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/assets/AssetService.java
new file mode 100644
index 0000000..648a89f
--- /dev/null
+++ b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/assets/AssetService.java
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.oozie.ambari.view.assets;
+
+import java.util.Collection;
+
+import org.apache.ambari.view.ViewContext;
+import org.apache.oozie.ambari.view.assets.model.ActionAsset;
+
+public class AssetService {
+ private AssetRepo assetRepo;
+
+ public AssetService(ViewContext viewContext) {
+ super();
+ assetRepo = new AssetRepo(viewContext.getDataStore());
+ }
+
+ public Collection<ActionAsset> getAssets() {
+
+ return null;
+ }
+
+ public Collection<ActionAsset> getPrioritizedAssets() {
+ Collection<ActionAsset> assets = getAssets();
+ // reorder
+ return assets;
+ }
+
+ public void addAsset() {
+
+ }
+
+ public void deleteAsset() {
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9bc0b996/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/assets/model/ActionAsset.java
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/assets/model/ActionAsset.java b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/assets/model/ActionAsset.java
new file mode 100644
index 0000000..8eb6081
--- /dev/null
+++ b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/assets/model/ActionAsset.java
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.oozie.ambari.view.assets.model;
+
+import org.apache.oozie.ambari.view.model.BaseModel;
+
+public class ActionAsset extends BaseModel {
+ private String id;
+ private String name;
+ private String description;
+ private String assetLocation;
+ private String type;
+
+ public String getId() {
+ return id;
+ }
+ public void setId(String id) {
+ this.id = id;
+ }
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+ public String getDescription() {
+ return description;
+ }
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getType() {
+ return type;
+ }
+ public void setType(String type) {
+ this.type = type;
+ }
+ public String getAssetLocation() {
+ return assetLocation;
+ }
+ public void setAssetLocation(String assetLocation) {
+ this.assetLocation = assetLocation;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9bc0b996/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/model/BaseModel.java
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/model/BaseModel.java b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/model/BaseModel.java
new file mode 100644
index 0000000..553ce24
--- /dev/null
+++ b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/model/BaseModel.java
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.oozie.ambari.view.model;
+
+import java.io.Serializable;
+
+
+public class BaseModel implements Serializable{
+ private static final long serialVersionUID = 1L;
+ private String createdAt;
+ private String updatedAt;
+ private String owner;
+
+ public String getCreatedAt() {
+ return createdAt;
+ }
+ public void setCreatedAt(String createdAt) {
+ this.createdAt = createdAt;
+ }
+ public String getUpdatedAt() {
+ return updatedAt;
+ }
+ public void setUpdatedAt(String updatedAt) {
+ this.updatedAt = updatedAt;
+ }
+ public String getOwner() {
+ return owner;
+ }
+ public void setOwner(String owner) {
+ this.owner = owner;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9bc0b996/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
new file mode 100644
index 0000000..4c88454
--- /dev/null
+++ b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/workflowmanager/WorkflowManagerService.java
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.oozie.ambari.view.workflowmanager;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Date;
+
+import org.apache.ambari.view.ViewContext;
+import org.apache.oozie.ambari.view.HDFSFileUtils;
+import org.apache.oozie.ambari.view.JobType;
+import org.apache.oozie.ambari.view.workflowmanager.model.Workflow;
+
+public class WorkflowManagerService {
+
+ private WorkflowsRepo workflowsRepository;
+ private HDFSFileUtils hdfsFileUtils;
+
+ public WorkflowManagerService(ViewContext viewContext) {
+ workflowsRepository = new WorkflowsRepo(viewContext.getDataStore());
+ hdfsFileUtils = new HDFSFileUtils(viewContext);
+ }
+
+ public void saveWorkflow(String path, JobType jobType, String descripton,
+ String userName) {
+ // workflowsRepository.getWorkflow(path);
+ Workflow workflowByPath = getWorkflowByPath(path);
+ if (workflowByPath == null) {
+ Workflow wf = new Workflow();
+ wf.setOwner(userName);
+ wf.setType(jobType.name());
+ wf.setWorkflowDefinitionPath(path);
+ Date now = new Date();
+ wf.setUpdatedAt(String.valueOf(now.getTime()));
+ workflowsRepository.updateWorkflow(wf);
+ } else {
+ Date now = new Date();
+ workflowByPath.setUpdatedAt(String.valueOf(now.getTime()));
+ workflowsRepository.updateWorkflow(workflowByPath);
+ }
+ }
+
+ public Collection<Workflow> getAllWorkflows() {
+ return workflowsRepository.getAllWorkflows();
+ }
+
+ public Workflow getWorkflowByPath(String path) {
+ return workflowsRepository.getWorkflow(path);
+ }
+
+ public void deleteWorkflow(String path, Boolean deleteDefinition) {
+ if (deleteDefinition) {
+ try {
+ hdfsFileUtils.deleteFile(path);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ workflowsRepository.deleteWorkflow(path);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9bc0b996/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/workflowmanager/WorkflowsManagerResource.java
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/workflowmanager/WorkflowsManagerResource.java b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/workflowmanager/WorkflowsManagerResource.java
new file mode 100644
index 0000000..17a3296
--- /dev/null
+++ b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/workflowmanager/WorkflowsManagerResource.java
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.oozie.ambari.view.workflowmanager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.QueryParam;
+
+import org.apache.ambari.view.ViewContext;
+
+public class WorkflowsManagerResource {
+ private WorkflowManagerService workflowManagerService;
+
+ public WorkflowsManagerResource(ViewContext viewContext) {
+ super();
+ this.workflowManagerService=new WorkflowManagerService(viewContext);
+ }
+
+ @GET
+ public Map<String,Object> getWorkflows(){
+ HashMap<String,Object> result=new HashMap<>();
+ result.put("wfprojects", workflowManagerService.getAllWorkflows());
+ return result;
+ }
+
+
+ @DELETE
+ public void deleteWorkflow( @QueryParam("worfkflowPath") String path,
+ @DefaultValue("false") @QueryParam("deleteDefinition") Boolean deleteDefinition){
+ workflowManagerService.deleteWorkflow(path,deleteDefinition);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9bc0b996/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/workflowmanager/WorkflowsRepo.java
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/workflowmanager/WorkflowsRepo.java b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/workflowmanager/WorkflowsRepo.java
new file mode 100644
index 0000000..978c059
--- /dev/null
+++ b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/workflowmanager/WorkflowsRepo.java
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.oozie.ambari.view.workflowmanager;
+
+import java.util.Collection;
+
+import org.apache.ambari.view.DataStore;
+import org.apache.ambari.view.PersistenceException;
+import org.apache.oozie.ambari.view.workflowmanager.model.Workflow;
+
+public class WorkflowsRepo {
+ private final DataStore dataStore;
+
+ public WorkflowsRepo(DataStore dataStore) {
+ super();
+ this.dataStore=dataStore;
+ }
+ public Collection<Workflow> getAllWorkflows(){
+ try {
+ return dataStore.findAll(Workflow.class,null);
+ } catch (PersistenceException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ public void deleteWorkflow(String workflowPath){
+ try {
+ Workflow workflow = this.getWorkflow(workflowPath);
+ this.dataStore.remove(workflow);
+ } catch (PersistenceException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ public void createWorkflow(Workflow wf){
+ try {
+ this.dataStore.store(wf);
+ } catch (PersistenceException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ public void updateWorkflow(Workflow wf){
+ try {
+ this.dataStore.store(wf);
+ } catch (PersistenceException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ public Workflow getWorkflow(String path) {
+ try {
+ return this.dataStore.find(Workflow.class, "workflowDefinitionPath='"+path+"'");
+ } catch (PersistenceException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9bc0b996/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/workflowmanager/model/Workflow.java
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/workflowmanager/model/Workflow.java b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/workflowmanager/model/Workflow.java
new file mode 100644
index 0000000..ad5f48b
--- /dev/null
+++ b/contrib/views/wfmanager/src/main/java/org/apache/oozie/ambari/view/workflowmanager/model/Workflow.java
@@ -0,0 +1,88 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.oozie.ambari.view.workflowmanager.model;
+
+import org.apache.oozie.ambari.view.model.BaseModel;
+
+public class Workflow extends BaseModel{
+ private static final long serialVersionUID = 1L;
+ private String id = null;
+ private String name;
+ private String desciption;
+ private String workflowDefinitionPath;
+ private String type;
+ private String isDraft;
+ private String definitionMissing;//true or not if path is fine.
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getWorkflowDefinitionPath() {
+ return workflowDefinitionPath;
+ }
+
+ public void setWorkflowDefinitionPath(String workflowDefinitionPath) {
+ this.workflowDefinitionPath = workflowDefinitionPath;
+ }
+
+ public String getIsDraft() {
+ return isDraft;
+ }
+
+ public void setIsDraft(String isDraft) {
+ this.isDraft = isDraft;
+ }
+
+ public String getDesciption() {
+ return desciption;
+ }
+
+ public void setDesciption(String desciption) {
+ this.desciption = desciption;
+ }
+
+ public String getDefinitionMissing() {
+ return definitionMissing;
+ }
+
+ public void setDefinitionMissing(String definitionMissing) {
+ this.definitionMissing = definitionMissing;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9bc0b996/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 2799db5..4f409a1 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
@@ -20,6 +20,7 @@ import {BundleGenerator} from '../domain/bundle/bundle-xml-generator';
import {BundleXmlImporter} from '../domain/bundle/bundle-xml-importer';
import { validator, buildValidations } from 'ember-cp-validations';
import Constants from '../utils/constants';
+import SchemaVersions from '../domain/schema-versions';
const Validations = buildValidations({
'bundle.name': validator('presence', {
@@ -41,6 +42,8 @@ const Validations = buildValidations({
export default Ember.Component.extend(Ember.Evented, Validations, {
bundle : null,
+ errors: Ember.A([]),
+ schemaVersions : SchemaVersions.create({}),
propertyExtractor : Ember.inject.service('property-extractor'),
fileBrowser : Ember.inject.service('file-browser'),
workspaceManager : Ember.inject.service('workspace-manager'),
@@ -107,7 +110,8 @@ export default Ember.Component.extend(Ember.Evented, Validations, {
displayValue : '',
type : 'date'
},
- coordinators : null
+ coordinators : null,
+ schemaVersions : this.get("schemaVersions")
});
},
importSampleBundle (){
@@ -156,9 +160,11 @@ export default Ember.Component.extend(Ember.Evented, Validations, {
return deferred;
},
getBundleFromXml(bundleXml){
- var bundleXmlImporter = BundleXmlImporter.create({});
- var bundle = bundleXmlImporter.importBundle(bundleXml);
- this.set("bundle", bundle);
+ var bundleXmlImporter = BundleXmlImporter.create({schemaVersions: this.get("schemaVersions")});
+ var bundleObj = bundleXmlImporter.importBundle(bundleXml, this.get("errors"));
+ this.set("bundle", bundleObj.bundle);
+ this.get("errors").clear();
+ this.get("errors").pushObjects(bundleObj.errors);
},
actions : {
closeFileBrowser(){
@@ -220,6 +226,7 @@ export default Ember.Component.extend(Ember.Evented, Validations, {
},
resetBundle(){
this.set('bundle', this.createBundle());
+ this.set('errors').clear();
},
closeBundleSubmitConfig(){
this.set("showingJobConfig", false);
@@ -257,6 +264,9 @@ export default Ember.Component.extend(Ember.Evented, Validations, {
},
openTab(type, path){
this.sendAction('openTab', type, path);
+ },
+ showVersionSettings(value){
+ this.set('showVersionSettings', value);
}
}
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/9bc0b996/contrib/views/wfmanager/src/main/resources/ui/app/components/bundle-coord-config.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/bundle-coord-config.js b/contrib/views/wfmanager/src/main/resources/ui/app/components/bundle-coord-config.js
index 229b2cc..2280f82 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/components/bundle-coord-config.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/bundle-coord-config.js
@@ -99,7 +99,7 @@ export default Ember.Component.extend(Validations, {
deferred.promise.then(function(data){
var x2js = new X2JS();
var coordJson = x2js.xml_str2json(data);
- this.set('coordinatorName', coordJson["coordinator-app"]._name);
+ this.set('coordinator.name', coordJson["coordinator-app"]._name);
}.bind(this)).catch(function(){
this.set('coordinatorName', null);
}.bind(this));
http://git-wip-us.apache.org/repos/asf/ambari/blob/9bc0b996/contrib/views/wfmanager/src/main/resources/ui/app/components/bundle-version-settings.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/bundle-version-settings.js b/contrib/views/wfmanager/src/main/resources/ui/app/components/bundle-version-settings.js
new file mode 100644
index 0000000..3bd6653
--- /dev/null
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/bundle-version-settings.js
@@ -0,0 +1,49 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+import Ember from 'ember';
+import Constants from '../utils/constants';
+
+export default Ember.Component.extend({
+ initialize : function(){
+ this.set('currentBundleVersion', this.get('schemaVersions').getCurrentBundleVersion());
+ this.set('bundleSchemaVersions', this.get('schemaVersions').getBundleVersions());
+ this.get('schemaVersions').createCopy();
+ }.on('init'),
+ BundleVersionObserver : Ember.observer('currentBundleVersion',function(){
+ this.get('schemaVersions').setCurrentBundleVersion(this.get('currentBundleVersion'));
+ }),
+ rendered : function(){
+ this.$('#version-settings-dialog').modal({
+ backdrop: 'static',
+ keyboard: false
+ });
+ this.$('#version-settings-dialog').modal('show');
+ this.$('#version-settings-dialog').modal().on('hidden.bs.modal', function() {
+ this.sendAction('showVersionSettings', false);
+ }.bind(this));
+ }.on('didInsertElement'),
+ actions : {
+ save (){
+ this.$('#version-settings-dialog').modal('hide');
+ },
+ cancel (){
+ this.get('schemaVersions').rollBack();
+ this.$('#version-settings-dialog').modal('hide');
+ }
+ }
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/9bc0b996/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 57fcdf8..23d1955 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
@@ -19,6 +19,7 @@ import {Coordinator} from '../domain/coordinator/coordinator';
import {CoordinatorGenerator} from '../domain/coordinator/coordinator-xml-generator';
import {CoordinatorXmlImporter} from '../domain/coordinator/coordinator-xml-importer';
import {SlaInfo} from '../domain/sla-info';
+import SchemaVersions from '../domain/schema-versions';
import Constants from '../utils/constants';
import { validator, buildValidations } from 'ember-cp-validations';
@@ -42,6 +43,8 @@ const Validations = buildValidations({
export default Ember.Component.extend(Validations, Ember.Evented, {
coordinator : null,
+ errors: Ember.A([]),
+ schemaVersions : SchemaVersions.create({}),
childComponents : new Map(),
fileBrowser : Ember.inject.service('file-browser'),
propertyExtractor : Ember.inject.service('property-extractor'),
@@ -204,18 +207,20 @@ export default Ember.Component.extend(Validations, Ember.Evented, {
}
},
controls : Ember.A([]),
- slainfo : SlaInfo.create({})
+ slainfo : SlaInfo.create({}),
+ schemaVersions : this.get("schemaVersions")
});
},
importSampleCoordinator (){
+ var self = this;
var deferred = Ember.RSVP.defer();
Ember.$.ajax({
url: "/sampledata/coordinator.xml",
dataType: "text",
cache:false,
success: function(data) {
- var coordinatorXmlImporter = CoordinatorXmlImporter.create({});
- var coordinator = coordinatorXmlImporter.importCoordinator(data);
+ var coordinatorXmlImporter = CoordinatorXmlImporter.create({schemaVersions: self.schemaVersions});
+ var coordinator = coordinatorXmlImporter.importCoordinator(data, self.errors);
deferred.resolve(coordinator);
}.bind(this),
failure : function(data){
@@ -270,9 +275,12 @@ export default Ember.Component.extend(Validations, Ember.Evented, {
return deferred;
},
getCoordinatorFromXml(coordinatorXml){
- var coordinatorXmlImporter = CoordinatorXmlImporter.create({});
- var coordinator = coordinatorXmlImporter.importCoordinator(coordinatorXml);
+ var coordinatorXmlImporter = CoordinatorXmlImporter.create({schemaVersions: this.get("schemaVersions")});
+ var coordinatorObj = coordinatorXmlImporter.importCoordinator(coordinatorXml, this.errors);
+ var coordinator = coordinatorObj.coordinator;
this.set("coordinator", coordinator);
+ this.get("errors").clear();
+ this.get("errors").pushObjects(coordinatorObj.errors);
this.$('input[name="dataInputType"][value="'+ coordinator.get('dataInputType')+'"]').prop('checked', true);
if(coordinator.get('dataInputType') === 'logical'){
this.set('conditionalDataInExists', true);
@@ -450,13 +458,16 @@ export default Ember.Component.extend(Validations, Ember.Evented, {
},
resetCoordinator(){
this.set('coordinator', this.createNewCoordinator());
+ this.get("errors").clear();
},
importCoordinatorTest(){
var deferred = this.importSampleCoordinator();
deferred.promise.then(function(data){
- this.set("coordinator", data);
- this.$('input[name="dataInputType"][value="'+ data.get('dataInputType')+'"]').prop('checked', true);
- if(data.get('dataInputType') === 'logical'){
+ this.set("coordinator", data.coordinator);
+ this.get("errors").clear();
+ this.get("errors").pushObjects(data.errors);
+ this.$('input[name="dataInputType"][value="'+ data.coordinator.get('dataInputType')+'"]').prop('checked', true);
+ if(data.coordinator.get('dataInputType') === 'logical'){
this.set('conditionalDataInExists', true);
}
console.error(this.get('coordinator'));
@@ -516,6 +527,9 @@ export default Ember.Component.extend(Validations, Ember.Evented, {
}.bind(this)).catch(function(){
this.set('workflowName', null);
}.bind(this));
+ },
+ showVersionSettings(value){
+ this.set('showVersionSettings', value);
}
}
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/9bc0b996/contrib/views/wfmanager/src/main/resources/ui/app/components/coord-version-settings.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/coord-version-settings.js b/contrib/views/wfmanager/src/main/resources/ui/app/components/coord-version-settings.js
new file mode 100644
index 0000000..6385a44
--- /dev/null
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/coord-version-settings.js
@@ -0,0 +1,49 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+import Ember from 'ember';
+import Constants from '../utils/constants';
+
+export default Ember.Component.extend({
+ initialize : function(){
+ this.set('currentCoordinatorVersion', this.get('schemaVersions').getCurrentCoordinatorVersion());
+ this.set('coordinatorSchemaVersions', this.get('schemaVersions').getCoordinatorVersions());
+ this.get('schemaVersions').createCopy();
+ }.on('init'),
+ CoordinatorVersionObserver : Ember.observer('currentCoordinatorVersion',function(){
+ this.get('schemaVersions').setCurrentCoordinatorVersion(this.get('currentCoordinatorVersion'));
+ }),
+ rendered : function(){
+ this.$('#version-settings-dialog').modal({
+ backdrop: 'static',
+ keyboard: false
+ });
+ this.$('#version-settings-dialog').modal('show');
+ this.$('#version-settings-dialog').modal().on('hidden.bs.modal', function() {
+ this.sendAction('showVersionSettings', false);
+ }.bind(this));
+ }.on('didInsertElement'),
+ actions : {
+ save (){
+ this.$('#version-settings-dialog').modal('hide');
+ },
+ cancel (){
+ this.get('schemaVersions').rollBack();
+ this.$('#version-settings-dialog').modal('hide');
+ }
+ }
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/9bc0b996/contrib/views/wfmanager/src/main/resources/ui/app/components/date-with-expr.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/date-with-expr.js b/contrib/views/wfmanager/src/main/resources/ui/app/components/date-with-expr.js
index dd9a9ae..541104d 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/components/date-with-expr.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/date-with-expr.js
@@ -55,7 +55,6 @@ export default Ember.Component.extend(Validations, {
useCurrent: false,
showClose : true
});
- this.set('dateField.displayValue', undefined);
}else{
var dateTimePicker = this.$('input[name="'+this.get('inputName')+'"]').data("DateTimePicker");
if(dateTimePicker){
http://git-wip-us.apache.org/repos/asf/ambari/blob/9bc0b996/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 a3d64b0..6cbc3dd 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
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import Ember from 'ember';
-
+import CommonUtils from "../utils/common-utils";
export default Ember.Component.extend({
workspaceManager : Ember.inject.service('workspace-manager'),
xmlAppPath : null,
@@ -42,10 +42,22 @@ export default Ember.Component.extend({
this.get('tabs').forEach((tab)=>{
this.get('tabCounter').set(tab.type, (this.get('tabCounter').get(tab.type)) + 1);
}, this);
+
+ Ember.getOwner(this).lookup('route:design').on('openNewTab', function(path){
+ this.createNewTab('wf', path);
+ }.bind(this));
+
}.on('init'),
elementsInserted : function(){
this.$('.nav-tabs a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
- this.get('workspaceManager').setLastActiveTab((this.$(e.target).attr('href').slice(1)));
+ var id = this.$(e.target).attr('href').slice(1);
+ this.get('workspaceManager').setLastActiveTab(id);
+ var tab = this.get('tabs').findBy('id', id);
+ if(tab.type === 'dashboard'){
+ this.sendAction('showDashboard');
+ }else{
+ this.sendAction('hideDashboard');
+ }
}.bind(this));
if(this.get('tabs') && this.get('tabs').length > 0){
@@ -54,19 +66,13 @@ export default Ember.Component.extend({
if(!activeTab){
activeTab = this.get('tabs').objectAt(this.get('tabs').length - 1);
}
- this.$('.nav-tabs a[href="#' + activeTab.id + '"]').tab('show');
- }else{
- if(this.get('hasMultitabSupport')){
- this.createNewTab(this.get('type'), this.get('xmlAppPath'));
+ if(activeTab.type === 'dashboard'){
+ this.createOrshowDashboard();
}else{
- var tab = this.get('tabs').findBy('type', this.get('type'));
- if(!tab){
- this.createNewTab(this.get('type'), this.get('xmlAppPath'));
- }else{
- Ember.set(tab,'path', this.get('xmlAppPath'));
- this.$('.nav-tabs a[href="#' + tab.id + '"]').tab('show');
- }
+ this.$('.nav-tabs a[href="#' + activeTab.id + '"]').tab('show');
}
+ }else{
+ this.createOrshowDashboard();
}
}.on('didInsertElement'),
onDestroy : function(){
@@ -100,6 +106,23 @@ export default Ember.Component.extend({
this.get('tabCounter').set(type, ++count);
return count;
},
+ createOrshowDashboard(){
+ var dashboardTab = this.get('tabs').findBy('type', 'dashboard');
+ if(dashboardTab && dashboardTab.type === 'dashboard'){
+ this.$('.nav-tabs a[href="#' + dashboardTab.id + '"]').tab('show');
+ }else{
+ var tab = {
+ type : 'dashboard',
+ id : this.generateTabId(),
+ name : 'Dashboard'
+ };
+ this.$('.nav-tabs li').removeClass('active');
+ this.$('.tab-content .tab-pane').removeClass('active');
+ this.get('tabs').pushObject(tab);
+ this.$('.nav-tabs a[href="#' + tab.id + '"]').tab('show');
+ }
+ this.sendAction('showDashboard');
+ },
generateTabId(){
return 'tab-'+ Math.ceil(Math.random() * 100000);
},
@@ -109,6 +132,7 @@ export default Ember.Component.extend({
Ember.set(tab, 'context', context);
},
show(type){
+ this.sendAction('hideDashboard');
if(this.get('hasMultitabSupport')){
this.createNewTab(type);
}else{
@@ -120,6 +144,9 @@ export default Ember.Component.extend({
}
}
},
+ showDashboard(){
+ this.createOrshowDashboard();
+ },
closeTab(index){
if(index < this.get('tabs').length - 1){
var previousTab = this.get('tabs').objectAt(index + 1);
@@ -127,6 +154,13 @@ export default Ember.Component.extend({
}
this.get('workspaceManager').deleteWorkInProgress(this.get('tabs').objectAt(index).id);
this.get('tabs').removeAt(index);
+ Ember.run.later(()=>{
+ var type = this.$('.nav-tabs').find('.active').attr('data-type');
+ console.error(type);
+ if(type === 'dashboard'){
+ this.createOrshowDashboard();
+ }
+ }.bind(this));
},
openTab(type, path){
if(this.get('hasMultitabSupport')){
@@ -151,7 +185,10 @@ export default Ember.Component.extend({
},
interceptShow(tab){
if(tab.type === 'wf' && tab.context){
+ CommonUtils.setTestContext(tab.context);
tab.context.resize();
+ }else if(tab.type === 'dashboard'){
+ this.sendAction('showDashboard');
}
}
}