Commit OODT-563 to the repo: Initial cut at Task editing and Workflow execution contributed by varun.
Project: http://git-wip-us.apache.org/repos/asf/oodt/repo Commit: http://git-wip-us.apache.org/repos/asf/oodt/commit/708a836a Tree: http://git-wip-us.apache.org/repos/asf/oodt/tree/708a836a Diff: http://git-wip-us.apache.org/repos/asf/oodt/diff/708a836a Branch: refs/heads/feature/zookeeper-config Commit: 708a836a6b58e0cd9fefd7b33b1e75897bb0d7e2 Parents: 1bf6f66 Author: Chris Mattmann <[email protected]> Authored: Sun Jul 16 13:40:56 2017 -0700 Committer: Chris Mattmann <[email protected]> Committed: Sun Jul 16 13:40:56 2017 -0700 ---------------------------------------------------------------------- CHANGES.txt | 2 + webapp/wmservices/pom.xml | 92 +++++++ .../cas/wmservices/client/WmServicesClient.java | 132 +++++++++ .../repository/PackagedWorkflowManager.java | 275 +++++++++++++++++++ .../AbstractWorkflowServiceResource.java | 88 ++++++ .../wmservices/resources/WorkflowResource.java | 108 ++++++++ .../wmservices/servlets/WmServicesServlet.java | 114 ++++++++ .../src/main/webapp/META-INF/context.xml | 21 ++ .../wmservices/src/main/webapp/WEB-INF/web.xml | 48 ++++ 9 files changed, 880 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/oodt/blob/708a836a/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 2a614e5..7ceb353 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -3,6 +3,8 @@ Apache OODT Change Log Release 1.1 - Current Development +* OODT-563 Task editing and Workflow execution (varun, mattmann) + * OODT-212 Rollback capability for Workflows (sherylj via mattmann) * OODT-836, OODT-837 Remove Non-Essential Components (mattmann, mdstarch, magicaltrout) http://git-wip-us.apache.org/repos/asf/oodt/blob/708a836a/webapp/wmservices/pom.xml ---------------------------------------------------------------------- diff --git a/webapp/wmservices/pom.xml b/webapp/wmservices/pom.xml new file mode 100644 index 0000000..054bb02 --- /dev/null +++ b/webapp/wmservices/pom.xml @@ -0,0 +1,92 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor + license agreements. See the NOTICE.txt 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. --> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 + http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.apache.oodt</groupId> + <artifactId>oodt-core</artifactId> + <version>1.1-SNAPSHOT</version> + <relativePath>../../core/pom.xml</relativePath> + </parent> + <artifactId>workflow-services</artifactId> + <packaging>war</packaging> + <name>CAS Workflow REST Services</name> + <description> + A set of REST-ful services for the Workflow Manager. + </description> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <executions> + <execution> + <id>make-a-jar</id> + <phase>compile</phase> + <goals> + <goal>jar</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <executions> + <execution> + <phase>install</phase> + <goals> + <goal>install-file</goal> + </goals> + <configuration> + <packaging>jar</packaging> + <artifactId>${project.artifactId}</artifactId> + <groupId>${project.groupId}</groupId> + <version>${project.version}</version> + <file> + ${project.build.directory}/${project.artifactId}-${project.version}.jar + </file> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + <dependencies> + <dependency> + <groupId>org.apache.oodt</groupId> + <artifactId>cas-workflow</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-frontend-jaxrs</artifactId> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-transports-local</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + </dependencies> +</project> http://git-wip-us.apache.org/repos/asf/oodt/blob/708a836a/webapp/wmservices/src/main/java/org/apache/oodt/cas/wmservices/client/WmServicesClient.java ---------------------------------------------------------------------- diff --git a/webapp/wmservices/src/main/java/org/apache/oodt/cas/wmservices/client/WmServicesClient.java b/webapp/wmservices/src/main/java/org/apache/oodt/cas/wmservices/client/WmServicesClient.java new file mode 100644 index 0000000..c18f734 --- /dev/null +++ b/webapp/wmservices/src/main/java/org/apache/oodt/cas/wmservices/client/WmServicesClient.java @@ -0,0 +1,132 @@ +/* + * 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.oodt.cas.wmservices.client; + +import java.io.DataOutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; + +import org.apache.commons.io.IOUtils; +import org.apache.oodt.cas.wmservices.repository.PackagedWorkflowManager; +import org.apache.oodt.cas.workflow.structs.Workflow; +import org.apache.oodt.cas.workflow.structs.exceptions.RepositoryException; + +/** + * Client class to connect to cas-wm-services + * + * @author vratnakar + */ +public class WmServicesClient { + String serverurl; + String service = "/service/"; + + /** + * Constructor + * + * @param workflowDir + * the directory where workflow files exist + */ + public WmServicesClient(String serverurl) { + this.serverurl = serverurl; + } + + /** + * Add a Packaged workflow + * + * @param workflowId + * id of the workflow + * @param workflow + * the workflow to be added + * @return true if operation successful + * @throws RepositoryException + */ + public boolean addPackagedWorkflow(String workflowId, Workflow workflow) + throws RepositoryException { + + try { + PackagedWorkflowManager editor = new PackagedWorkflowManager(); + String xml = editor.serializeWorkflow(workflow); + + // Now Make a POST call to the servlet with this xml + String result = this.query("POST", "addPackagedRepositoryWorkflow", "workflowID", + workflowId, "workflowXML", xml); + return Boolean.parseBoolean(result); + } catch (Exception e) { + throw new RepositoryException("Could not add packaged workflow: " + + e.getMessage()); + } + } + + /** + * Delete a Packaged workflow + * + * @param workflowId + * id of the workflow to be deleted + * @return true if operation successful + * @throws RepositoryException + */ + public boolean deletePackagedWorkflow(String workflowId) + throws RepositoryException { + try { + // Now Make a POST call to the servlet with this xml + String result = this.query("POST", "deletePackagedRepositoryWorkflow", "workflowID", + workflowId); + return Boolean.parseBoolean(result); + } catch (Exception e) { + throw new RepositoryException("Could not delete packaged workflow: " + + e.getMessage()); + } + } + + // Private functions + + private String query(String method, String op, Object... args) { + String url = this.serverurl + this.service + op; + try { + String params = ""; + for (int i = 0; i < args.length; i += 2) { + if (i > 0) + params += "&"; + params += args[i] + "=" + + URLEncoder.encode(args[i + 1].toString(), "UTF-8"); + } + if ("GET".equals(method)) { + URL urlobj = new URL(url + "?" + params); + return IOUtils.toString(urlobj.openStream()); + } else { + URL urlobj = new URL(url); + HttpURLConnection con = (HttpURLConnection) urlobj.openConnection(); + con.setRequestMethod(method); + con.setDoOutput(true); + DataOutputStream out = new DataOutputStream(con.getOutputStream()); + out.writeBytes(params); + out.flush(); + out.close(); + + String result = IOUtils.toString(con.getInputStream()); + con.disconnect(); + return result; + } + + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } +} http://git-wip-us.apache.org/repos/asf/oodt/blob/708a836a/webapp/wmservices/src/main/java/org/apache/oodt/cas/wmservices/repository/PackagedWorkflowManager.java ---------------------------------------------------------------------- diff --git a/webapp/wmservices/src/main/java/org/apache/oodt/cas/wmservices/repository/PackagedWorkflowManager.java b/webapp/wmservices/src/main/java/org/apache/oodt/cas/wmservices/repository/PackagedWorkflowManager.java new file mode 100644 index 0000000..688eebc --- /dev/null +++ b/webapp/wmservices/src/main/java/org/apache/oodt/cas/wmservices/repository/PackagedWorkflowManager.java @@ -0,0 +1,275 @@ +/* + * 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.oodt.cas.wmservices.repository; + +import java.io.File; +import java.io.FileOutputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import org.apache.commons.io.FileUtils; +import org.apache.oodt.cas.workflow.repository.PackagedWorkflowRepository; +import org.apache.oodt.cas.workflow.structs.Graph; +import org.apache.oodt.cas.workflow.structs.ParentChildWorkflow; +import org.apache.oodt.cas.workflow.structs.Workflow; +import org.apache.oodt.cas.workflow.structs.WorkflowCondition; +import org.apache.oodt.cas.workflow.structs.WorkflowTask; +import org.apache.oodt.cas.workflow.structs.WorkflowTaskConfiguration; +import org.apache.oodt.cas.workflow.structs.exceptions.RepositoryException; +import org.apache.oodt.commons.xml.XMLUtils; + +/** + * Helper class to handle PackagedWorkflowRepository workflows + * + * @author vratnakar + */ +public class PackagedWorkflowManager { + private PackagedWorkflowRepository repo; + + /** + * Constructor + * + * @param workflowDir + * directory where packaged workflows exist + * @throws InstantiationException + */ + public PackagedWorkflowManager() + throws InstantiationException { + this.repo = new PackagedWorkflowRepository(Collections.EMPTY_LIST); + } + + /** + * Add a workflow to the repository + * + * @param workflow + * a {@Link Workflow} to add into the repository + * @throws RepositoryException + */ + public void addWorkflow(Workflow workflow, String workflowDir) throws RepositoryException { + this.loadTasksToRepo(workflow); + String workflowId = this.repo.addWorkflow(workflow); + String filePath = workflowDir + File.separator + workflowId + ".xml"; + this.saveWorkflow(workflowId, filePath); + } + + /** + * Serialize a workflow + * + * @param workflow + * @return XML representation of the workflow + * @throws RepositoryException + */ + public String serializeWorkflow(Workflow workflow) throws RepositoryException { + try { + this.loadTasksToRepo(workflow); + String workflowId = this.repo.addWorkflow(workflow); + File f = File.createTempFile("tempworkflow-", "-packaged"); + this.saveWorkflow(workflowId, f.getAbsolutePath()); + String workflowXML = FileUtils.readFileToString(f); + f.delete(); + return workflowXML; + } catch (Exception e) { + throw new RepositoryException("Failed to serialize workflow: " + + e.getMessage()); + } + } + + /** + * Parse a workflow + * + * @param workflowID + * workflow id + * @param workflowXML + * xml representation of the workflow including all tasks + * @return a workflow + * @throws RepositoryException + */ + public Workflow parsePackagedWorkflow(String workflowID, String workflowXML) + throws RepositoryException { + try { + File tmpfile = File.createTempFile("tempworkflow-", "-packaged"); + FileUtils.writeStringToFile(tmpfile, workflowXML); + PackagedWorkflowRepository tmprepo = new PackagedWorkflowRepository( + Collections.singletonList(tmpfile)); + tmpfile.delete(); + return tmprepo.getWorkflowById(workflowID); + } catch (Exception e) { + throw new RepositoryException("Failed to parse workflow xml: " + + e.getMessage()); + } + } + + // Private helper functions + + private void loadTasksToRepo(Workflow workflow) throws RepositoryException { + for (WorkflowTask task : workflow.getTasks()) { + if (this.repo.getTaskById(task.getTaskId()) == null) + this.repo.addTask(task); + } + } + + private void saveWorkflow(String workflowId, String filePath) + throws RepositoryException { + List<ParentChildWorkflow> pcwlist = new ArrayList<ParentChildWorkflow>(); + // Check if the workflow exists + ParentChildWorkflow pcw = (ParentChildWorkflow) repo + .getWorkflowById(workflowId); + if (pcw == null) { + // Else check if this workflow Id is found in the event map + // - It would be here if the top task is a parallel task + pcwlist = repo.getWorkflowsForEvent(workflowId); + } + + if (pcw != null) + pcwlist.add(pcw); + + if (pcwlist.isEmpty()) + throw new RepositoryException("Cannot find " + workflowId + + " in the repository"); + + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document document = builder.newDocument(); + String casns = "http://oodt.jpl.nasa.gov/2.0/cas"; + Element rootElem = document.createElement("cas:workflows"); + rootElem.setAttribute("xmlns:cas", casns); + rootElem.setAttribute("xmlns", casns); + document.appendChild(rootElem); + + // Create the workflow itself + if (pcwlist.size() == 1) { + Element elem = this.addGraphToDocument(document, pcwlist.get(0) + .getGraph()); + if (elem != null) + rootElem.appendChild(elem); + } else { + Element parallelElem = document.createElement("parallel"); + parallelElem.setAttribute("id", workflowId); + for (ParentChildWorkflow cpcw : pcwlist) { + Element elem = this.addGraphToDocument(document, cpcw.getGraph()); + if (elem != null) + parallelElem.appendChild(elem); + } + rootElem.appendChild(parallelElem); + } + + for (Object obj : repo.getTasksByWorkflowId(workflowId)) { + WorkflowTask task = (WorkflowTask) obj; + Element elem = this.createTaskElement(document, task); + if (elem != null) + rootElem.appendChild(elem); + } + XMLUtils.writeXmlToStream(document, new FileOutputStream(new File( + filePath))); + } catch (Exception e) { + e.printStackTrace(); + throw new RepositoryException("Could not save workflow. " + + e.getMessage()); + } + } + + private Element addGraphToDocument(Document document, Graph g) { + String exetype = g.getExecutionType(); + Element elem = null; + if ("parallel".equals(exetype) || "sequential".equals(exetype)) { + elem = document.createElement(exetype); + if (g.getModelId() != null && !g.getModelId().equals("")) + elem.setAttribute("id", g.getModelId()); + if (g.getModelName() != null && !g.getModelName().equals("")) + elem.setAttribute("name", g.getModelName()); + } else if ("task".equals(exetype) || "condition".equals(exetype)) { + elem = document.createElement(exetype); + if (g.getModelIdRef() != null && !g.getModelIdRef().equals("")) { + elem.setAttribute("id-ref", g.getModelIdRef()); + } + } + + if (elem != null) { + Element condElem = null; + for (Graph cg : g.getChildren()) { + Element celem = addGraphToDocument(document, cg); + if (celem != null) { + // Wrap condition child elements inside "conditions" tag + if ("condition".equals(cg.getExecutionType())) { + if (condElem == null) { + condElem = document.createElement("conditions"); + elem.appendChild(condElem); + } + condElem.appendChild(celem); + } else { + elem.appendChild(celem); + } + } + } + } + return elem; + } + + private Element createTaskElement(Document document, WorkflowTask task) { + Element taskElem = document.createElement("task"); + taskElem.setAttribute("id", task.getTaskId()); + taskElem.setAttribute("name", task.getTaskName()); + taskElem.setAttribute("class", task.getTaskInstanceClassName()); + + if (task.getConditions() != null && task.getConditions().size() > 0) { + Element conditionsElem = document.createElement("conditions"); + for (Object obj : task.getConditions()) { + WorkflowCondition cond = (WorkflowCondition) obj; + Element condElem = document.createElement("condition"); + condElem.setAttribute("id", cond.getConditionId()); + conditionsElem.appendChild(condElem); + } + + taskElem.appendChild(conditionsElem); + } + + if (task.getRequiredMetFields() != null + && task.getRequiredMetFields().size() > 0) { + Element reqMetFieldsElem = document.createElement("requiredMetFields"); + for (Object obj : task.getRequiredMetFields()) { + String metField = (String) obj; + Element reqMetFieldElem = document.createElement("metfield"); + reqMetFieldElem.setAttribute("name", metField); + reqMetFieldsElem.appendChild(reqMetFieldElem); + } + taskElem.appendChild(reqMetFieldsElem); + } + + WorkflowTaskConfiguration config = task.getTaskConfig(); + if (config != null && config.getProperties().keySet().size() > 0) { + Element taskConfigElem = document.createElement("configuration"); + for (Object obj : config.getProperties().keySet()) { + String propName = (String) obj; + String propVal = config.getProperty(propName); + Element configPropElem = document.createElement("property"); + configPropElem.setAttribute("name", propName); + configPropElem.setAttribute("value", propVal); + taskConfigElem.appendChild(configPropElem); + } + taskElem.appendChild(taskConfigElem); + } + return taskElem; + } +} http://git-wip-us.apache.org/repos/asf/oodt/blob/708a836a/webapp/wmservices/src/main/java/org/apache/oodt/cas/wmservices/resources/AbstractWorkflowServiceResource.java ---------------------------------------------------------------------- diff --git a/webapp/wmservices/src/main/java/org/apache/oodt/cas/wmservices/resources/AbstractWorkflowServiceResource.java b/webapp/wmservices/src/main/java/org/apache/oodt/cas/wmservices/resources/AbstractWorkflowServiceResource.java new file mode 100644 index 0000000..3d28238 --- /dev/null +++ b/webapp/wmservices/src/main/java/org/apache/oodt/cas/wmservices/resources/AbstractWorkflowServiceResource.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 + * + * 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.oodt.cas.wmservices.resources; + +import java.io.File; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.servlet.ServletContext; +import javax.ws.rs.core.Context; + +import org.apache.oodt.cas.wmservices.servlets.WmServicesServlet; +import org.apache.oodt.cas.workflow.system.XmlRpcWorkflowManagerClient; + +public abstract class AbstractWorkflowServiceResource { + private static final Logger LOGGER = Logger.getLogger(AbstractWorkflowServiceResource.class + .getName()); + + // Servlet context + @Context + private ServletContext context; + + /** + * Gets the packaged repository directory from servlet context. + * @return the packaged repository directory + * @throws Exception + * if an object cannot be retrieved from the context attribute + */ + public File getContextPkgReposDir() throws Exception { + Object repositoryDirObject = context + .getAttribute(WmServicesServlet.ATTR_NAME_PKG_REPO_DIR); + if (repositoryDirObject != null + && repositoryDirObject instanceof File) { + return (File) repositoryDirObject; + } + String message = "Unable to retrieve packaged repository directory from the servlet context."; + LOGGER.log(Level.WARNING, message); + throw new Exception(message); + } + + /** + * Gets the servlet's workflow manager client instance from the servlet + * context. + * @return the workflow manager client instance from the servlet context + * attribute + * @throws Exception + * if an object cannot be retrieved from the context attribute + */ + public XmlRpcWorkflowManagerClient getContextClient() throws Exception { + // Get the workflow manager client from the servlet context. + Object clientObject = context + .getAttribute(WmServicesServlet.ATTR_NAME_CLIENT); + if (clientObject != null + && clientObject instanceof XmlRpcWorkflowManagerClient) { + return (XmlRpcWorkflowManagerClient) clientObject; + } + + String message = "Unable to retrieve workflow manager client from the " + + "servlet context."; + LOGGER.log(Level.WARNING, message); + throw new Exception(message); + } + + + /** + * Sets the servlet context. + * @param context + * the servlet context to set. + */ + public void setServletContext(ServletContext context) { + this.context = context; + } +} http://git-wip-us.apache.org/repos/asf/oodt/blob/708a836a/webapp/wmservices/src/main/java/org/apache/oodt/cas/wmservices/resources/WorkflowResource.java ---------------------------------------------------------------------- diff --git a/webapp/wmservices/src/main/java/org/apache/oodt/cas/wmservices/resources/WorkflowResource.java b/webapp/wmservices/src/main/java/org/apache/oodt/cas/wmservices/resources/WorkflowResource.java new file mode 100644 index 0000000..683a152 --- /dev/null +++ b/webapp/wmservices/src/main/java/org/apache/oodt/cas/wmservices/resources/WorkflowResource.java @@ -0,0 +1,108 @@ +/* + * 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.oodt.cas.wmservices.resources; + +import java.io.File; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.ws.rs.DELETE; +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; + +import org.apache.oodt.cas.wmservices.repository.PackagedWorkflowManager; +import org.apache.oodt.cas.workflow.structs.Workflow; + +/** + * Jax-RS server functions for adding/deleting workflows + * + * @author vratnakar + */ +public class WorkflowResource extends AbstractWorkflowServiceResource { + private static final Logger LOGGER = Logger.getLogger(WorkflowResource.class + .getName()); + + /** + * Default constructor. + */ + public WorkflowResource() { + } + + /** + * Add Packaged Repository Workflow + * + * @param workflowID + * id of the workflow + * @param workflowXML + * xml representation of the workflow + * @return true if addition successful + */ + @POST + @Path("/addPackagedRepositoryWorkflow") + public boolean addPackagedRepositoryWorkflow( + @FormParam("workflowID") String workflowID, + @FormParam("workflowXML") String workflowXML) throws Exception { + try { + PackagedWorkflowManager pwmanager = new PackagedWorkflowManager(); + Workflow workflow = pwmanager.parsePackagedWorkflow(workflowID, workflowXML); + if(workflow == null) + return false; + String workflowDir = this.getContextPkgReposDir().getAbsolutePath(); + pwmanager.addWorkflow(workflow, workflowDir); + return getContextClient().refreshRepository(); + } catch (Exception e) { + String message = "Unable to add workflow. "; + message += e.getMessage(); + LOGGER.log(Level.SEVERE, message); + throw e; + } + } + + /** + * Delete Packaged Repository Workflow + * + * @param workflowID + * id of the workflow to delete + * @return true if deletion successful + */ + @DELETE + @Path("/deletePackagedRepositoryWorkflow") + public boolean deletePackagedRepositoryWorkflow( + @FormParam("workflowID") String workflowID) throws Exception { + try { + File wflowFile = getPackagedRepositoryWorkflowFile(workflowID); + if (wflowFile.delete()) + return getContextClient().refreshRepository(); + else + return false; + } catch (Exception e) { + String message = "Unable to delete workflow. "; + message += e.getMessage(); + LOGGER.log(Level.SEVERE, message); + throw e; + } + } + + // Private functions + private File getPackagedRepositoryWorkflowFile(String workflowID) + throws Exception { + return new File(this.getContextPkgReposDir().getAbsolutePath() + + File.separator + workflowID + ".xml"); + } +} http://git-wip-us.apache.org/repos/asf/oodt/blob/708a836a/webapp/wmservices/src/main/java/org/apache/oodt/cas/wmservices/servlets/WmServicesServlet.java ---------------------------------------------------------------------- diff --git a/webapp/wmservices/src/main/java/org/apache/oodt/cas/wmservices/servlets/WmServicesServlet.java b/webapp/wmservices/src/main/java/org/apache/oodt/cas/wmservices/servlets/WmServicesServlet.java new file mode 100644 index 0000000..1884d22 --- /dev/null +++ b/webapp/wmservices/src/main/java/org/apache/oodt/cas/wmservices/servlets/WmServicesServlet.java @@ -0,0 +1,114 @@ +/* + * 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.oodt.cas.wmservices.servlets; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; + +import org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet; +import org.apache.oodt.cas.metadata.util.PathUtils; +import org.apache.oodt.cas.workflow.system.XmlRpcWorkflowManagerClient; + +/** + * Initialize workflow manager services servlet + * + * Set the following Parameters in context.xml for the webapp: + * <ul> + * <li>workflow.url + * <li>packagedRepo.dir.path + * </ul> + * + * @author vratnakar + */ +public class WmServicesServlet extends CXFNonSpringJaxrsServlet { + private static final Logger LOGGER = Logger + .getLogger(WmServicesServlet.class.getName()); + + private static final long serialVersionUID = -7830210280506307805L; + + // Default URL for the workflow manager + private static final String DEFAULT_WM_URL = "http://localhost:9001"; + + // Servlet context parameter names. + private static final String PARAM_NAME_URL = "workflow.url"; + private static final String PARAM_NAME_PKGREPO_DIR = "packagedRepo.dir.path"; // For Packaged Repo + + /** + * The name of the servlet context attribute that holds a client for the + * workflow manager, a {@link XmlRpcWorkflowManagerClient} object. + */ + public static final String ATTR_NAME_CLIENT = "client"; + + /** + * The name of the servlet context attribute that holds the workflow manager's + * packaged repository directory: a {@link File} object. + */ + public static final String ATTR_NAME_PKG_REPO_DIR = "pkgRepoFilesDir"; + + + @Override + public void init(ServletConfig configuration) throws ServletException { + super.init(configuration); + ServletContext context = configuration.getServletContext(); + + // Initialize the workflow manager client. + try { + URL url = null; + String urlParameter = context.getInitParameter(PARAM_NAME_URL); + if (urlParameter != null) { + // Get the workflow manager URL from the context parameter. + url = new URL(PathUtils.replaceEnvVariables(urlParameter)); + } else { + // Try the default URL for the workflow manager. + LOGGER.log(Level.WARNING, + "Unable to find the servlet context parameter" + " (\"" + + PARAM_NAME_URL + "\") for the workflow manager's URL."); + url = new URL(DEFAULT_WM_URL); + } + // Attempt to connect the client to the workflow manager and if successful + // store the client as a context attribute for other objects to access. + XmlRpcWorkflowManagerClient client = new XmlRpcWorkflowManagerClient(url); + context.setAttribute(ATTR_NAME_CLIENT, client); + } catch (MalformedURLException e) { + LOGGER.log(Level.SEVERE, + "Encountered a malformed URL for the workflow manager.", e); + throw new ServletException(e); + } + + // Initialize the repository directory + String pkgRepoDirPath = context.getInitParameter(PARAM_NAME_PKGREPO_DIR); + if (pkgRepoDirPath != null) { + pkgRepoDirPath = PathUtils.replaceEnvVariables(pkgRepoDirPath); + File workflowDir = new File(pkgRepoDirPath); + if (workflowDir.exists() && workflowDir.isDirectory()) { + context.setAttribute(ATTR_NAME_PKG_REPO_DIR, workflowDir); + } else { + LOGGER.log(Level.SEVERE, + "Unable to locate the Packaged repository directory (" + + workflowDir.getAbsolutePath()); + } + } + } +} http://git-wip-us.apache.org/repos/asf/oodt/blob/708a836a/webapp/wmservices/src/main/webapp/META-INF/context.xml ---------------------------------------------------------------------- diff --git a/webapp/wmservices/src/main/webapp/META-INF/context.xml b/webapp/wmservices/src/main/webapp/META-INF/context.xml new file mode 100644 index 0000000..eac2c3c --- /dev/null +++ b/webapp/wmservices/src/main/webapp/META-INF/context.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor + license agreements. See the NOTICE.txt 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. --> + +<Context path="/cas-wm-services" reloadable="true" crossContext="true"> + + <Parameter name="workflow.url" value="[WORKFLOW_URL]" + override="false" /> + + <Parameter name="packagedRepo.dir.path" value="[WORKFLOW_HOME]/policy/wengine" + override="false" /> + +</Context> http://git-wip-us.apache.org/repos/asf/oodt/blob/708a836a/webapp/wmservices/src/main/webapp/WEB-INF/web.xml ---------------------------------------------------------------------- diff --git a/webapp/wmservices/src/main/webapp/WEB-INF/web.xml b/webapp/wmservices/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..100e108 --- /dev/null +++ b/webapp/wmservices/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more contributor + license agreements. See the NOTICE.txt 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. +--> +<web-app version="2.5" + xmlns="http://java.sun.com/xml/ns/javaee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee + http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> + + <display-name>CAS Workflow Manager Services</display-name> + + <servlet> + <servlet-name>WmServicesServlet</servlet-name> + <servlet-class> + org.apache.oodt.cas.wmservices.servlets.WmServicesServlet + </servlet-class> + <init-param> + <param-name>jaxrs.serviceClasses</param-name> + <param-value> + org.apache.oodt.cas.wmservices.resources.WorkflowResource + </param-value> + </init-param> + <init-param> + <param-name>jaxrs.scope</param-name> + <param-value>prototype</param-value> + </init-param> + <load-on-startup>1</load-on-startup> + </servlet> + + <servlet-mapping> + <servlet-name>WmServicesServlet</servlet-name> + <url-pattern>/service/*</url-pattern> + </servlet-mapping> +</web-app>
