You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@taverna.apache.org by st...@apache.org on 2015/02/23 16:37:18 UTC
[18/49] incubator-taverna-server git commit: taverna-* module names
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/admin/Admin.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/admin/Admin.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/admin/Admin.java
new file mode 100644
index 0000000..184c7b5
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/admin/Admin.java
@@ -0,0 +1,1100 @@
+/*
+ * Copyright (C) 2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.admin;
+
+import static org.taverna.server.master.admin.Paths.ALLOW_NEW;
+import static org.taverna.server.master.admin.Paths.ARGS;
+import static org.taverna.server.master.admin.Paths.EXEC_WF;
+import static org.taverna.server.master.admin.Paths.EXITCODE;
+import static org.taverna.server.master.admin.Paths.FACTORIES;
+import static org.taverna.server.master.admin.Paths.GEN_PROV;
+import static org.taverna.server.master.admin.Paths.INVOKES;
+import static org.taverna.server.master.admin.Paths.JAR_FORKER;
+import static org.taverna.server.master.admin.Paths.JAR_WORKER;
+import static org.taverna.server.master.admin.Paths.JAVA;
+import static org.taverna.server.master.admin.Paths.LIFE;
+import static org.taverna.server.master.admin.Paths.LOG_EXN;
+import static org.taverna.server.master.admin.Paths.LOG_WFS;
+import static org.taverna.server.master.admin.Paths.OPERATING;
+import static org.taverna.server.master.admin.Paths.OP_LIMIT;
+import static org.taverna.server.master.admin.Paths.PASSFILE;
+import static org.taverna.server.master.admin.Paths.PERM_WF;
+import static org.taverna.server.master.admin.Paths.REG_HOST;
+import static org.taverna.server.master.admin.Paths.REG_JAR;
+import static org.taverna.server.master.admin.Paths.REG_POLL;
+import static org.taverna.server.master.admin.Paths.REG_PORT;
+import static org.taverna.server.master.admin.Paths.REG_WAIT;
+import static org.taverna.server.master.admin.Paths.ROOT;
+import static org.taverna.server.master.admin.Paths.RUNS;
+import static org.taverna.server.master.admin.Paths.RUN_LIMIT;
+import static org.taverna.server.master.admin.Paths.STARTUP;
+import static org.taverna.server.master.admin.Paths.TOTAL_RUNS;
+import static org.taverna.server.master.admin.Paths.URS;
+import static org.taverna.server.master.admin.Paths.UR_FILE;
+import static org.taverna.server.master.admin.Paths.USER;
+import static org.taverna.server.master.admin.Paths.USERS;
+import static org.taverna.server.master.admin.Types.JSON;
+import static org.taverna.server.master.admin.Types.PLAIN;
+import static org.taverna.server.master.admin.Types.XML;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.OPTIONS;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.apache.cxf.jaxrs.model.wadl.Description;
+import org.ogf.usage.JobUsageRecord;
+import org.taverna.server.master.common.Uri;
+import org.taverna.server.master.common.VersionedElement;
+
+/**
+ * The administration interface for Taverna Server.
+ *
+ * @author Donal Fellows
+ */
+@Description("Administration interface for Taverna Server.")
+public interface Admin {
+ /**
+ * Get a simple administration user interface.
+ *
+ * @return The description document in a response.
+ * @throws IOException
+ */
+ @GET
+ @Path(ROOT)
+ @Produces("text/html")
+ @Nonnull
+ Response getUserInterface() throws IOException;
+
+ /**
+ * Gets support resources for the administration user interface.
+ *
+ * @param file
+ * The name of the static resource to provide.
+ * @return The requested document in a response.
+ * @throws IOException
+ */
+ @GET
+ @Path("static/{file}")
+ @Produces("*/*")
+ Response getStaticResource(@PathParam("file") String file)
+ throws IOException;
+
+ /**
+ * Get a description of the administration interface.
+ *
+ * @param ui
+ * What URI was used to access this resource?
+ * @return The description document.
+ */
+ @GET
+ @Path(ROOT)
+ @Produces({ XML, JSON })
+ @Nonnull
+ AdminDescription getDescription(@Context UriInfo ui);
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(ROOT)
+ Response optionsRoot();
+
+ /**
+ * Get whether to allow new workflow runs to be created.
+ *
+ * @return The current setting.
+ */
+ @GET
+ @Path(ALLOW_NEW)
+ @Produces(PLAIN)
+ @Description("Whether to allow new workflow runs to be created.")
+ boolean getAllowNew();
+
+ /**
+ * Set whether to allow new workflow runs to be created.
+ *
+ * @param newValue
+ * What to set it to.
+ * @return The new setting.
+ */
+ @PUT
+ @Path(ALLOW_NEW)
+ @Consumes(PLAIN)
+ @Produces(PLAIN)
+ @Description("Whether to allow new workflow runs to be created.")
+ boolean setAllowNew(boolean newValue);
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(ALLOW_NEW)
+ @Description("Whether to allow new workflow runs to be created.")
+ Response optionsAllowNew();
+
+ /**
+ * Get whether to log the workflows submitted.
+ *
+ * @return The current setting.
+ */
+ @GET
+ @Path(LOG_WFS)
+ @Produces(PLAIN)
+ @Description("Whether to log the workflows submitted.")
+ boolean getLogWorkflows();
+
+ /**
+ * Set whether to log the workflows submitted.
+ *
+ * @param logWorkflows
+ * What to set it to.
+ * @return The new setting.
+ */
+ @PUT
+ @Path(LOG_WFS)
+ @Consumes(PLAIN)
+ @Produces(PLAIN)
+ @Description("Whether to log the workflows submitted.")
+ boolean setLogWorkflows(boolean logWorkflows);
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(LOG_WFS)
+ @Description("Whether to log the workflows submitted.")
+ Response optionsLogWorkflows();
+
+ /**
+ * Get whether to log the user-directed faults.
+ *
+ * @return The current setting.
+ */
+ @GET
+ @Path(LOG_EXN)
+ @Produces(PLAIN)
+ @Description("Whether to log the user-directed faults.")
+ boolean getLogFaults();
+
+ /**
+ * Set whether to log the user-directed faults.
+ *
+ * @param logFaults
+ * What to set it to.
+ * @return The new setting.
+ */
+ @PUT
+ @Path(LOG_EXN)
+ @Consumes(PLAIN)
+ @Produces(PLAIN)
+ @Description("Whether to log the user-directed faults.")
+ boolean setLogFaults(boolean logFaults);
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(LOG_EXN)
+ @Description("Whether to log the user-directed faults.")
+ Response optionsLogFaults();
+
+ /**
+ * Get what file to dump usage records to.
+ *
+ * @return The current setting.
+ */
+ @GET
+ @Path(UR_FILE)
+ @Produces(PLAIN)
+ @Description("What file to dump usage records to.")
+ @Nonnull
+ String getURFile();
+
+ /**
+ * Set what file to dump usage records to.
+ *
+ * @param urFile
+ * What to set it to.
+ * @return The new setting.
+ */
+ @PUT
+ @Path(UR_FILE)
+ @Consumes(PLAIN)
+ @Produces(PLAIN)
+ @Description("What file to dump usage records to.")
+ @Nonnull
+ String setURFile(@Nonnull String urFile);
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(UR_FILE)
+ @Description("What file to dump usage records to.")
+ Response optionsURFile();
+
+ /**
+ * The property for the number of times the service methods have been
+ * invoked.
+ *
+ * @return The property value (read-only).
+ */
+ @GET
+ @Path(INVOKES)
+ @Produces(PLAIN)
+ @Description("How many times have the service methods been invoked.")
+ int invokeCount();
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(INVOKES)
+ @Description("How many times have the service methods been invoked.")
+ Response optionsInvokationCount();
+
+ /**
+ * The property for the number of runs that are currently in existence.
+ *
+ * @return The property value (read-only).
+ */
+ @GET
+ @Path(TOTAL_RUNS)
+ @Produces(PLAIN)
+ @Description("How many runs are currently in existence.")
+ int runCount();
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(TOTAL_RUNS)
+ @Description("How many runs are currently in existence.")
+ Response optionsRunCount();
+
+ /**
+ * The property for the number of runs that are currently running.
+ *
+ * @return The property value (read-only).
+ */
+ @GET
+ @Path(OPERATING)
+ @Produces(PLAIN)
+ @Description("How many runs are currently actually running.")
+ int operatingCount();
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(OPERATING)
+ @Description("How many runs are currently actually running.")
+ Response optionsOperatingCount();
+
+ /**
+ * Get the full pathname of the RMI registry's JAR.
+ *
+ * @return The current setting.
+ */
+ @GET
+ @Path(REG_JAR)
+ @Produces(PLAIN)
+ @Description("What is the full pathname of the server's custom RMI registry executable JAR file?")
+ @Nonnull
+ String getRegistryJar();
+
+ /**
+ * Set the full pathname of the RMI registry's JAR.
+ *
+ * @param registryJar
+ * What to set it to.
+ * @return The new setting.
+ */
+ @PUT
+ @Path(REG_JAR)
+ @Consumes(PLAIN)
+ @Produces(PLAIN)
+ @Description("What is the full pathname of the server's custom RMI registry executable JAR file?")
+ @Nonnull
+ String setRegistryJar(@Nonnull String registryJar);
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(REG_JAR)
+ @Description("What is the full pathname of the server's special custom RMI registry executable JAR file?")
+ Response optionsRegistryJar();
+
+ /**
+ * Get the location of the RMI registry.
+ *
+ * @return The current setting.
+ */
+ @GET
+ @Path(REG_HOST)
+ @Produces(PLAIN)
+ @Description("Where is the RMI registry?")
+ @Nonnull
+ String getRegistryHost();
+
+ /**
+ * Set the location of the RMI registry.
+ *
+ * @param registryHost
+ * What to set it to.
+ * @return The new setting.
+ */
+ @PUT
+ @Path(REG_HOST)
+ @Consumes(PLAIN)
+ @Produces(PLAIN)
+ @Description("Where is the RMI registry?")
+ @Nonnull
+ String setRegistryHost(@Nonnull String registryHost);
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(REG_HOST)
+ @Description("Where is the RMI registry?")
+ Response optionsRegistryHost();
+
+ /**
+ * Get the port of the RMI registry.
+ *
+ * @return The current setting.
+ */
+ @GET
+ @Path(REG_PORT)
+ @Produces(PLAIN)
+ @Description("On what port is the RMI registry?")
+ int getRegistryPort();
+
+ /**
+ * Set the port of the RMI registry.
+ *
+ * @param registryPort
+ * What to set it to.
+ * @return The new setting.
+ */
+ @PUT
+ @Path(REG_PORT)
+ @Consumes(PLAIN)
+ @Produces(PLAIN)
+ @Description("On what port is the RMI registry?")
+ int setRegistryPort(int registryPort);
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(REG_PORT)
+ @Description("On what port is the RMI registry?")
+ Response optionsRegistryPort();
+
+ /**
+ * Get the maximum number of simultaneous runs.
+ *
+ * @return The current setting.
+ */
+ @GET
+ @Path(RUN_LIMIT)
+ @Produces(PLAIN)
+ @Description("What is the maximum number of simultaneous runs?")
+ int getRunLimit();
+
+ /**
+ * Set the maximum number of simultaneous runs.
+ *
+ * @param runLimit
+ * What to set it to.
+ * @return The new setting.
+ */
+ @PUT
+ @Path(RUN_LIMIT)
+ @Consumes(PLAIN)
+ @Produces(PLAIN)
+ @Description("What is the maximum number of simultaneous runs?")
+ int setRunLimit(int runLimit);
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(RUN_LIMIT)
+ @Description("What is the maximum number of simultaneous runs?")
+ Response optionsRunLimit();
+
+ /**
+ * Get the maximum number of simultaneous executing runs.
+ *
+ * @return The current setting.
+ */
+ @GET
+ @Path(OP_LIMIT)
+ @Produces(PLAIN)
+ @Description("What is the maximum number of simultaneous executing runs?")
+ int getOperatingLimit();
+
+ /**
+ * Set the maximum number of simultaneous executing runs.
+ *
+ * @param operatingLimit
+ * What to set it to.
+ * @return The new setting.
+ */
+ @PUT
+ @Path(OP_LIMIT)
+ @Consumes(PLAIN)
+ @Produces(PLAIN)
+ @Description("What is the maximum number of simultaneous executing runs?")
+ int setOperatingLimit(int operatingLimit);
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(OP_LIMIT)
+ @Description("What is the maximum number of simultaneous executing runs?")
+ Response optionsOperatingLimit();
+
+ /**
+ * Get the default lifetime of workflow runs.
+ *
+ * @return The current setting.
+ */
+ @GET
+ @Path(LIFE)
+ @Produces(PLAIN)
+ @Description("What is the default lifetime of workflow runs, in seconds?")
+ int getDefaultLifetime();
+
+ /**
+ * Set the default lifetime of workflow runs.
+ *
+ * @param defaultLifetime
+ * What to set it to.
+ * @return The new setting.
+ */
+ @PUT
+ @Path(LIFE)
+ @Consumes(PLAIN)
+ @Produces(PLAIN)
+ @Description("What is the default lifetime of workflow runs, in seconds?")
+ int setDefaultLifetime(int defaultLifetime);
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(LIFE)
+ @Description("What is the default lifetime of workflow runs, in seconds?")
+ Response optionsDefaultLifetime();
+
+ /**
+ * The property for the list of IDs of current runs.
+ *
+ * @return The property value (read-only).
+ */
+ @GET
+ @Path(RUNS)
+ @Produces({ XML, JSON })
+ @Description("List the IDs of all current runs.")
+ StringList currentRuns();
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(RUNS)
+ @Description("List the IDs of all current runs.")
+ Response optionsCurrentRuns();
+
+ /**
+ * Get the Java binary to be used for execution of subprocesses.
+ *
+ * @return The current setting.
+ */
+ @GET
+ @Path(JAVA)
+ @Produces(PLAIN)
+ @Description("Which Java binary should be used for execution of subprocesses?")
+ @Nonnull
+ String getJavaBinary();
+
+ /**
+ * Set the Java binary to be used for execution of subprocesses.
+ *
+ * @param javaBinary
+ * What to set it to.
+ * @return The new setting.
+ */
+ @PUT
+ @Path(JAVA)
+ @Consumes(PLAIN)
+ @Produces(PLAIN)
+ @Description("Which Java binary should be used for execution of subprocesses?")
+ @Nonnull
+ String setJavaBinary(@Nonnull String javaBinary);
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(JAVA)
+ @Description("Which Java binary should be used for execution of subprocesses?")
+ Response optionsJavaBinary();
+
+ /**
+ * Get the extra arguments to be supplied to Java subprocesses.
+ *
+ * @return The current setting.
+ */
+ @GET
+ @Path(ARGS)
+ @Produces({ XML, JSON })
+ @Description("What extra arguments should be supplied to Java subprocesses?")
+ @Nonnull
+ StringList getExtraArguments();
+
+ /**
+ * Set the extra arguments to be supplied to Java subprocesses.
+ *
+ * @param extraArguments
+ * What to set it to.
+ * @return The new setting.
+ */
+ @PUT
+ @Path(ARGS)
+ @Consumes(XML)
+ @Produces({ XML, JSON })
+ @Description("What extra arguments should be supplied to Java subprocesses?")
+ @Nonnull
+ StringList setExtraArguments(@Nonnull StringList extraArguments);
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(ARGS)
+ @Description("What extra arguments should be supplied to Java subprocesses?")
+ Response optionsExtraArguments();
+
+ /**
+ * Get the full pathname of the worker JAR file.
+ *
+ * @return The current setting.
+ */
+ @GET
+ @Path(JAR_WORKER)
+ @Produces(PLAIN)
+ @Description("What is the full pathname of the server's per-user worker executable JAR file?")
+ @Nonnull
+ String getServerWorkerJar();
+
+ /**
+ * Set the full pathname of the worker JAR file.
+ *
+ * @param serverWorkerJar
+ * What to set it to.
+ * @return The new setting.
+ */
+ @PUT
+ @Path(JAR_WORKER)
+ @Consumes(PLAIN)
+ @Produces(PLAIN)
+ @Description("What is the full pathname of the server's per-user worker executable JAR file?")
+ @Nonnull
+ String setServerWorkerJar(@Nonnull String serverWorkerJar);
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(JAR_WORKER)
+ @Description("What is the full pathname of the server's per-user worker executable JAR file?")
+ Response optionsServerWorkerJar();
+
+ /**
+ * Get the full pathname of the executeWorkflow.sh file.
+ *
+ * @return The current setting.
+ */
+ @GET
+ @Path(EXEC_WF)
+ @Produces(PLAIN)
+ @Description("What is the full pathname of the core Taverna executeWorkflow script?")
+ @Nonnull
+ String getExecuteWorkflowScript();
+
+ /**
+ * Set the full pathname of the executeWorkflow.sh file.
+ *
+ * @param executeWorkflowScript
+ * What to set it to.
+ * @return The new setting.
+ */
+ @PUT
+ @Path(EXEC_WF)
+ @Consumes(PLAIN)
+ @Produces(PLAIN)
+ @Description("What is the full pathname of the core Taverna executeWorkflow script?")
+ @Nonnull
+ String setExecuteWorkflowScript(@Nonnull String executeWorkflowScript);
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(EXEC_WF)
+ @Description("What is the full pathname of the core Taverna executeWorkflow script?")
+ Response optionsExecuteWorkflowScript();
+
+ /**
+ * Get the total duration of time to wait for the start of the forker
+ * process.
+ *
+ * @return The current setting.
+ */
+ @GET
+ @Path(REG_WAIT)
+ @Produces(PLAIN)
+ @Description("How long in total should the core wait for registration of the \"forker\" process, in seconds.")
+ int getRegistrationWaitSeconds();
+
+ /**
+ * Set the total duration of time to wait for the start of the forker
+ * process.
+ *
+ * @param registrationWaitSeconds
+ * What to set it to.
+ * @return The new setting.
+ */
+ @PUT
+ @Path(REG_WAIT)
+ @Consumes(PLAIN)
+ @Produces(PLAIN)
+ @Description("How long in total should the core wait for registration of the \"forker\" process, in seconds.")
+ int setRegistrationWaitSeconds(int registrationWaitSeconds);
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(REG_WAIT)
+ @Description("How long in total should the core wait for registration of the \"forker\" process, in seconds.")
+ Response optionsRegistrationWaitSeconds();
+
+ /**
+ * Get the interval between checks for registration of the forker process.
+ *
+ * @return The current setting.
+ */
+ @GET
+ @Path(REG_POLL)
+ @Produces(PLAIN)
+ @Description("What is the interval between checks for registration of the \"forker\" process, in milliseconds.")
+ int getRegistrationPollMillis();
+
+ /**
+ * Set the interval between checks for registration of the forker process.
+ *
+ * @param registrationPollMillis
+ * What to set it to.
+ * @return The new setting.
+ */
+ @PUT
+ @Path(REG_POLL)
+ @Consumes(PLAIN)
+ @Produces(PLAIN)
+ @Description("What is the interval between checks for registration of the \"forker\" process, in milliseconds.")
+ int setRegistrationPollMillis(int registrationPollMillis);
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(REG_POLL)
+ @Description("What is the interval between checks for registration of the \"forker\" process, in milliseconds.")
+ Response optionsRegistrationPollMillis();
+
+ /**
+ * Get the full pathname of the file containing the impersonation
+ * credentials for the forker process.
+ *
+ * @return The current setting.
+ */
+ @GET
+ @Path(PASSFILE)
+ @Produces(PLAIN)
+ @Description("What is the full pathname of the file containing the password used for impersonating other users? (On Unix, this is the password for the deployment user to use \"sudo\".)")
+ @Nonnull
+ String getRunasPasswordFile();
+
+ /**
+ * Set the full pathname of the file containing the impersonation
+ * credentials for the forker process.
+ *
+ * @param runasPasswordFile
+ * What to set it to.
+ * @return The new setting.
+ */
+ @PUT
+ @Path(PASSFILE)
+ @Consumes(PLAIN)
+ @Produces(PLAIN)
+ @Description("What is the full pathname of the file containing the password used for impersonating other users? (On Unix, this is the password for the deployment user to use \"sudo\".)")
+ @Nonnull
+ String setRunasPasswordFile(@Nonnull String runasPasswordFile);
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(PASSFILE)
+ @Description("What is the full pathname of the file containing the password used for impersonating other users? (On Unix, this is the password for the deployment user to use \"sudo\".)")
+ Response optionsRunasPasswordFile();
+
+ /**
+ * Get the full pathname of the forker's JAR.
+ *
+ * @return The current setting.
+ */
+ @GET
+ @Path(JAR_FORKER)
+ @Produces(PLAIN)
+ @Description("What is the full pathname of the server's special authorized \"forker\" executable JAR file?")
+ @Nonnull
+ String getServerForkerJar();
+
+ /**
+ * Set the full pathname of the forker's JAR.
+ *
+ * @param serverForkerJar
+ * What to set it to.
+ * @return The new setting.
+ */
+ @PUT
+ @Path(JAR_FORKER)
+ @Consumes(PLAIN)
+ @Produces(PLAIN)
+ @Description("What is the full pathname of the server's special authorized \"forker\" executable JAR file?")
+ @Nonnull
+ String setServerForkerJar(@Nonnull String serverForkerJar);
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(JAR_FORKER)
+ @Description("What is the full pathname of the server's special authorized \"forker\" executable JAR file?")
+ Response optionsServerForkerJar();
+
+ /**
+ * The property for the length of time it took to start the forker.
+ *
+ * @return The property value (read-only).
+ */
+ @GET
+ @Path(STARTUP)
+ @Produces(PLAIN)
+ @Description("How long did it take for the back-end \"forker\" to set itself up, in seconds.")
+ int startupTime();
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(STARTUP)
+ @Description("How long did it take for the back-end \"forker\" to set itself up, in seconds.")
+ Response optionsStartupTime();
+
+ /**
+ * The property for the last exit code of the forker process.
+ *
+ * @return The property value (read-only).
+ */
+ @GET
+ @Path(EXITCODE)
+ @Produces(PLAIN)
+ @Description("What was the last exit code of the \"forker\"? If null, no exit has ever been recorded.")
+ Integer lastExitCode();
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(EXITCODE)
+ @Description("What was the last exit code of the \"forker\"? If null, no exit has ever been recorded.")
+ Response optionsLastExitCode();
+
+ /**
+ * The property for the mapping of usernames to factory process handles.
+ *
+ * @return The property value (read-only).
+ */
+ @GET
+ @Path(FACTORIES)
+ @Produces({ XML, JSON })
+ @Description("What is the mapping of local usernames to factory process RMI IDs?")
+ StringList factoryProcessMapping();
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(FACTORIES)
+ @Description("What is the mapping of local usernames to factory process RMI IDs?")
+ Response optionsFactoryProcessMapping();
+
+ /**
+ * The property for the list of usage records collected.
+ *
+ * @return The property value (read-only).
+ */
+ @GET
+ @Path(URS)
+ @Produces(XML)
+ @Description("What is the list of usage records that have been collected?")
+ URList usageRecords();
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(URS)
+ @Description("What is the list of usage records that have been collected?")
+ Response optionsUsageRecords();
+
+ /**
+ * What are the current list of workflow URIs that may be started? Empty
+ * means allow any, including user-supplied workflows.
+ *
+ * @return List of URIs, encoded as strings.
+ */
+ @GET
+ @Path(PERM_WF)
+ @Produces({ XML, JSON })
+ @Description("What are the current list of workflow URIs that may be started? Empty means allow any, including user-supplied workflows.")
+ StringList getPermittedWorkflowURIs();
+
+ /** Do we turn on the generate provenance option by default? */
+ @GET
+ @Path(GEN_PROV)
+ @Produces(PLAIN)
+ @Description("Do we turn on the generate provenance option by default? (boolean)")
+ String getGenerateProvenance();
+
+ /** Do we turn on the generate provenance option by default? */
+ @PUT
+ @Path(GEN_PROV)
+ @Consumes(PLAIN)
+ @Produces(PLAIN)
+ @Description("Do we turn on the generate provenance option by default? (boolean)")
+ String setGenerateProvenance(String newValue);
+
+ /** Do we turn on the generate provenance option by default? */
+ @OPTIONS
+ @Path(GEN_PROV)
+ @Description("Do we turn on the generate provenance option by default? (boolean)")
+ Response optionsGenerateProvenance();
+
+ /**
+ * What are the current list of workflow URIs that may be started? Empty
+ * means allow any, including user-supplied workflows.
+ *
+ * @param permitted
+ * List of URIs, encoded as strings.
+ * @return List of URIs, encoded as strings.
+ */
+ @PUT
+ @Path(PERM_WF)
+ @Consumes(XML)
+ @Produces({ XML, JSON })
+ @Description("What are the current list of workflow URIs that may be started? Empty means allow any, including user-supplied workflows.")
+ StringList setPermittedWorkflowURIs(@Nonnull StringList permitted);
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(PERM_WF)
+ @Description("What are the current list of workflow URIs that may be started? Empty means allow any, including user-supplied workflows.")
+ Response optionsPermittedWorkflowURIs();
+
+ @GET
+ @Path(USERS)
+ @Produces({ XML, JSON })
+ @Description("What users are known to the server?")
+ UserList users(@Context UriInfo ui);
+
+ @GET
+ @Path(USER)
+ @Produces({ XML, JSON })
+ @Description("What do we know about a particular user?")
+ UserDesc user(@PathParam("id") String username);
+
+ @POST
+ @Path(USERS)
+ @Consumes(XML)
+ @Description("Create a user.")
+ Response useradd(UserDesc userdesc, @Nonnull @Context UriInfo ui);
+
+ @PUT
+ @Path(USER)
+ @Produces({ XML, JSON })
+ @Consumes(XML)
+ @Description("Update a user.")
+ UserDesc userset(@PathParam("id") String username, UserDesc userdesc);
+
+ @DELETE
+ @Path(USER)
+ @Produces({ XML, JSON })
+ @Description("What do we know about a particular user?")
+ Response userdel(@PathParam("id") String username);
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(USERS)
+ @Description("What users are known to the server?")
+ Response optionsUsers();
+
+ /** What HTTP methods may we use? */
+ @OPTIONS
+ @Path(USER)
+ @Description("What do we know about a particular user?")
+ Response optionsUser(@PathParam("id") String username);
+
+ // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+ /**
+ * The description of what properties are supported by the administration
+ * interface.
+ *
+ * @author Donal Fellows
+ */
+ @XmlRootElement(name = "description")
+ @XmlType(name = "Description")
+ public static class AdminDescription extends VersionedElement {
+ public Uri allowNew;
+ public Uri logWorkflows;
+ public Uri logFaults;
+ public Uri usageRecordDumpFile;
+ public Uri invokationCount;
+ public Uri runCount;
+ public Uri registryHost;
+ public Uri registryPort;
+ public Uri runLimit;
+ public Uri defaultLifetime;
+ public Uri currentRuns;
+ public Uri javaBinary;
+ public Uri extraArguments;
+ public Uri serverWorkerJar;
+ public Uri serverForkerJar;
+ public Uri executeWorkflowScript;
+ public Uri registrationWaitSeconds;
+ public Uri registrationPollMillis;
+ public Uri runasPasswordFile;
+ public Uri startupTime;
+ public Uri lastExitCode;
+ public Uri factoryProcessMapping;
+ public Uri usageRecords;
+ public Uri users;
+ public Uri operatingLimit;
+ public Uri operatingCount;
+ public Uri permittedWorkflowURIs;
+ public Uri generateProvenance;
+
+ public AdminDescription() {
+ }
+
+ public AdminDescription(UriInfo ui) {
+ allowNew = new Uri(ui, ALLOW_NEW);
+ logWorkflows = new Uri(ui, LOG_WFS);
+ logFaults = new Uri(ui, LOG_EXN);
+ usageRecordDumpFile = new Uri(ui, UR_FILE);
+ invokationCount = new Uri(ui, INVOKES);
+ runCount = new Uri(ui, TOTAL_RUNS);
+ registryHost = new Uri(ui, REG_HOST);
+ registryPort = new Uri(ui, REG_PORT);
+ runLimit = new Uri(ui, RUN_LIMIT);
+ defaultLifetime = new Uri(ui, LIFE);
+ currentRuns = new Uri(ui, RUNS);
+ javaBinary = new Uri(ui, JAVA);
+ extraArguments = new Uri(ui, ARGS);
+ serverWorkerJar = new Uri(ui, JAR_WORKER);
+ serverForkerJar = new Uri(ui, JAR_FORKER);
+ executeWorkflowScript = new Uri(ui, EXEC_WF);
+ registrationWaitSeconds = new Uri(ui, REG_WAIT);
+ registrationPollMillis = new Uri(ui, REG_POLL);
+ runasPasswordFile = new Uri(ui, PASSFILE);
+ startupTime = new Uri(ui, STARTUP);
+ lastExitCode = new Uri(ui, EXITCODE);
+ factoryProcessMapping = new Uri(ui, FACTORIES);
+ usageRecords = new Uri(ui, URS);
+ users = new Uri(ui, USERS);
+ operatingLimit = new Uri(ui, OP_LIMIT);
+ operatingCount = new Uri(ui, OPERATING);
+ permittedWorkflowURIs = new Uri(ui, PERM_WF);
+ generateProvenance = new Uri(ui, GEN_PROV);
+ }
+ }
+
+ /**
+ * A list of strings, as XML.
+ *
+ * @author Donal Fellows
+ */
+ @XmlRootElement(name = "stringList")
+ @XmlType(name = "StringList")
+ public static class StringList {
+ @XmlElement
+ public List<String> string = new ArrayList<>();
+ }
+
+ /**
+ * A list of users, as XML.
+ *
+ * @author Donal Fellows
+ */
+ @XmlRootElement(name = "userList")
+ @XmlType(name = "UserList")
+ public static class UserList {
+ @XmlElement
+ public List<URI> user = new ArrayList<>();
+ }
+
+ @XmlRootElement(name = "userDesc")
+ @XmlType(name = "UserDesc")
+ public static class UserDesc {
+ @XmlElement
+ public String username;
+ @XmlElement
+ public String password;
+ @XmlElement
+ public String localUserId;
+ @XmlElement
+ public Boolean enabled;
+ @XmlElement
+ public Boolean admin;
+ }
+
+ /**
+ * A list of usage records, as XML.
+ *
+ * @author Donal Fellows
+ */
+ @XmlRootElement(name = "usageRecordList")
+ @XmlType(name = "UsageRecords")
+ public static class URList {
+ @XmlElement
+ public List<JobUsageRecord> usageRecord;
+ }
+}
+
+interface Paths {
+ static final String ROOT = "/";
+ static final String ALLOW_NEW = "allowNew";
+ static final String LOG_WFS = "logWorkflows";
+ static final String LOG_EXN = "logFaults";
+ static final String UR_FILE = "usageRecordDumpFile";
+ static final String INVOKES = "invokationCount";
+ static final String TOTAL_RUNS = "runCount";
+ static final String OPERATING = "operatingCount";
+ static final String REG_HOST = "registryHost";
+ static final String REG_PORT = "registryPort";
+ static final String REG_JAR = "registryJar";
+ static final String RUN_LIMIT = "runLimit";
+ static final String OP_LIMIT = "operatingLimit";
+ static final String LIFE = "defaultLifetime";
+ static final String RUNS = "currentRuns";
+ static final String JAVA = "javaBinary";
+ static final String ARGS = "extraArguments";
+ static final String JAR_WORKER = "serverWorkerJar";
+ static final String JAR_FORKER = "serverForkerJar";
+ static final String EXEC_WF = "executeWorkflowScript";
+ static final String REG_WAIT = "registrationWaitSeconds";
+ static final String REG_POLL = "registrationPollMillis";
+ static final String PASSFILE = "runasPasswordFile";
+ static final String STARTUP = "startupTime";
+ static final String EXITCODE = "lastExitCode";
+ static final String FACTORIES = "factoryProcessMapping";
+ static final String URS = "usageRecords";
+ static final String PERM_WF = "permittedWorkflowURIs";
+ static final String GEN_PROV = "generateProvenance";
+ static final String USERS = "users";
+ static final String USER = USERS + "/{id}";
+}
+
+interface Types {
+ static final String PLAIN = "text/plain";
+ static final String XML = "application/xml";
+ static final String JSON = "application/json";
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/admin/AdminBean.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/admin/AdminBean.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/admin/AdminBean.java
new file mode 100644
index 0000000..b83d88f
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/admin/AdminBean.java
@@ -0,0 +1,794 @@
+/*
+ * Copyright (C) 2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.admin;
+
+import static java.util.Arrays.asList;
+import static java.util.UUID.randomUUID;
+import static javax.ws.rs.core.Response.created;
+import static javax.ws.rs.core.Response.noContent;
+import static javax.ws.rs.core.Response.Status.NOT_FOUND;
+import static org.taverna.server.master.common.Roles.ADMIN;
+import static org.taverna.server.master.common.Uri.secure;
+import static org.taverna.server.master.utils.RestUtils.opt;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.security.RolesAllowed;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.commons.io.IOUtils;
+import org.springframework.beans.factory.annotation.Required;
+import org.taverna.server.master.api.ManagementModel;
+import org.taverna.server.master.exceptions.GeneralFailureException;
+import org.taverna.server.master.factories.ConfigurableRunFactory;
+import org.taverna.server.master.identity.User;
+import org.taverna.server.master.identity.UserStoreAPI;
+import org.taverna.server.master.usage.UsageRecordRecorder;
+import org.taverna.server.master.utils.InvocationCounter;
+import org.taverna.server.master.worker.RunDBSupport;
+import org.taverna.server.master.worker.WorkerModel;
+
+/**
+ * The administration interface to Taverna Server.
+ *
+ * @author Donal Fellows
+ */
+public class AdminBean implements Admin {
+ @Required
+ public void setState(ManagementModel state) {
+ this.state = state;
+ }
+
+ @Required
+ public void setCounter(InvocationCounter counter) {
+ this.counter = counter;
+ }
+
+ @Required
+ public void setRunDB(RunDBSupport runDB) {
+ this.runDB = runDB;
+ }
+
+ @Required
+ public void setFactory(ConfigurableRunFactory factory) {
+ this.factory = factory;
+ }
+
+ @Required
+ public void setUsageRecords(UsageRecordRecorder usageRecords) {
+ this.usageRecords = usageRecords;
+ }
+
+ @Required
+ public void setUserStore(UserStoreAPI userStore) {
+ this.userStore = userStore;
+ }
+
+ @Required
+ public void setLocalWorkerModel(WorkerModel worker) {
+ localWorker = worker;
+ }
+
+ public void setAdminHtmlFile(String filename) {
+ this.adminHtmlFile = filename;
+ }
+
+ public void setResourceRoot(String root) {
+ this.resourceRoot = root;
+ }
+
+ protected byte[] getResource(String name) throws IOException {
+ if (AdminBean.class.getResource(name) == null)
+ throw new FileNotFoundException(name);
+ return IOUtils.toByteArray(AdminBean.class.getResourceAsStream(name));
+ }
+
+ private ManagementModel state;
+ private InvocationCounter counter;
+ private RunDBSupport runDB;
+ private ConfigurableRunFactory factory;
+ private UsageRecordRecorder usageRecords;
+ private UserStoreAPI userStore;
+ private WorkerModel localWorker;
+ private String adminHtmlFile = "/admin.html";
+ private String resourceRoot = "/static/";
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response getUserInterface() throws IOException {
+ return Response.ok(getResource(adminHtmlFile), "text/html").build();
+ }
+
+ @Override
+ @RolesAllowed(ADMIN)
+ public Response getStaticResource(String file) throws IOException {
+ if (file.matches("^[-_.a-zA-Z0-9]+$")) {
+ String type = "application/octet-stream";
+ if (file.endsWith(".html"))
+ type = "text/html";
+ else if (file.endsWith(".js"))
+ type = "text/javascript";
+ else if (file.endsWith(".jpg"))
+ type = "image/jpeg";
+ else if (file.endsWith(".gif"))
+ type = "image/gif";
+ else if (file.endsWith(".png"))
+ type = "image/png";
+ else if (file.endsWith(".svg"))
+ type = "image/svg+xml";
+ else if (file.endsWith(".css"))
+ type = "text/css";
+ try {
+ return Response.ok(getResource(resourceRoot + file), type)
+ .build();
+ } catch (IOException e) {
+ // ignore; we just treat as 404
+ }
+ }
+ return Response.status(NOT_FOUND).entity("no such resource").build();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public AdminDescription getDescription(UriInfo ui) {
+ return new AdminDescription(ui);
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsRoot() {
+ return opt();
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public boolean getAllowNew() {
+ return state.getAllowNewWorkflowRuns();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public boolean setAllowNew(boolean newValue) {
+ state.setAllowNewWorkflowRuns(newValue);
+ return state.getAllowNewWorkflowRuns();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsAllowNew() {
+ return opt("PUT");
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public boolean getLogWorkflows() {
+ return state.getLogIncomingWorkflows();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public boolean setLogWorkflows(boolean newValue) {
+ state.setLogIncomingWorkflows(newValue);
+ return state.getLogIncomingWorkflows();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsLogWorkflows() {
+ return opt("PUT");
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public boolean getLogFaults() {
+ return state.getLogOutgoingExceptions();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public boolean setLogFaults(boolean newValue) {
+ state.setLogOutgoingExceptions(newValue);
+ return state.getLogOutgoingExceptions();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsLogFaults() {
+ return opt("PUT");
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public String getURFile() {
+ return state.getUsageRecordLogFile();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public String setURFile(String newValue) {
+ state.setUsageRecordLogFile(newValue);
+ return state.getUsageRecordLogFile();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsURFile() {
+ return opt("PUT");
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public int invokeCount() {
+ return counter.getCount();
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsInvokationCount() {
+ return opt();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public int runCount() {
+ return runDB.countRuns();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsRunCount() {
+ return opt();
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public String getRegistryHost() {
+ return factory.getRegistryHost();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public String setRegistryHost(String newValue) {
+ factory.setRegistryHost(newValue);
+ return factory.getRegistryHost();
+ }
+
+ @Override
+ public Response optionsRegistryHost() {
+ return opt("PUT");
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public int getRegistryPort() {
+ return factory.getRegistryPort();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public int setRegistryPort(int newValue) {
+ factory.setRegistryPort(newValue);
+ return factory.getRegistryPort();
+ }
+
+ @Override
+ public Response optionsRegistryPort() {
+ return opt("PUT");
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public String getRegistryJar() {
+ return factory.getRmiRegistryJar();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public String setRegistryJar(String registryJar) {
+ factory.setRmiRegistryJar(registryJar);
+ return factory.getRmiRegistryJar();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsRegistryJar() {
+ return opt("PUT");
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public int getRunLimit() {
+ return factory.getMaxRuns();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public int setRunLimit(int newValue) {
+ factory.setMaxRuns(newValue);
+ return factory.getMaxRuns();
+ }
+
+ @Override
+ public Response optionsRunLimit() {
+ return opt("PUT");
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public int getDefaultLifetime() {
+ return factory.getDefaultLifetime();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public int setDefaultLifetime(int newValue) {
+ factory.setDefaultLifetime(newValue);
+ return factory.getDefaultLifetime();
+ }
+
+ @Override
+ public Response optionsDefaultLifetime() {
+ return opt("PUT");
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public StringList currentRuns() {
+ StringList result = new StringList();
+ result.string = runDB.listRunNames();
+ return result;
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsCurrentRuns() {
+ return opt();
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public String getJavaBinary() {
+ return factory.getJavaBinary();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public String setJavaBinary(String newValue) {
+ factory.setJavaBinary(newValue);
+ return factory.getJavaBinary();
+ }
+
+ @Override
+ public Response optionsJavaBinary() {
+ return opt("PUT");
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public StringList getExtraArguments() {
+ String[] xargs = factory.getExtraArguments();
+ StringList result = new StringList();
+ result.string = asList(xargs == null ? new String[0] : xargs);
+ return result;
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public StringList setExtraArguments(StringList newValue) {
+ if (newValue == null || newValue.string == null)
+ factory.setExtraArguments(new String[0]);
+ else
+ factory.setExtraArguments(newValue.string
+ .toArray(new String[newValue.string.size()]));
+ StringList result = new StringList();
+ result.string = asList(factory.getExtraArguments());
+ return result;
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsExtraArguments() {
+ return opt("PUT");
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public String getServerWorkerJar() {
+ return factory.getServerWorkerJar();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public String setServerWorkerJar(String newValue) {
+ factory.setServerWorkerJar(newValue);
+ return factory.getServerWorkerJar();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsServerWorkerJar() {
+ return opt("PUT");
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public String getExecuteWorkflowScript() {
+ return factory.getExecuteWorkflowScript();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public String setExecuteWorkflowScript(String newValue) {
+ factory.setExecuteWorkflowScript(newValue);
+ return factory.getExecuteWorkflowScript();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsExecuteWorkflowScript() {
+ return opt("PUT");
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public int getRegistrationWaitSeconds() {
+ return factory.getWaitSeconds();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public int setRegistrationWaitSeconds(int newValue) {
+ factory.setWaitSeconds(newValue);
+ return factory.getWaitSeconds();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsRegistrationWaitSeconds() {
+ return opt("PUT");
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public int getRegistrationPollMillis() {
+ return factory.getSleepTime();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public int setRegistrationPollMillis(int newValue) {
+ factory.setSleepTime(newValue);
+ return factory.getSleepTime();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsRegistrationPollMillis() {
+ return opt("PUT");
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public String getRunasPasswordFile() {
+ return factory.getPasswordFile();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public String setRunasPasswordFile(String newValue) {
+ factory.setPasswordFile(newValue);
+ return factory.getPasswordFile();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsRunasPasswordFile() {
+ return opt("PUT");
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public String getServerForkerJar() {
+ return factory.getServerForkerJar();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public String setServerForkerJar(String newValue) {
+ factory.setServerForkerJar(newValue);
+ return factory.getServerForkerJar();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsServerForkerJar() {
+ return opt("PUT");
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public int startupTime() {
+ return factory.getLastStartupCheckCount();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsStartupTime() {
+ return opt();
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Integer lastExitCode() {
+ return factory.getLastExitCode();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsLastExitCode() {
+ return opt();
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public StringList factoryProcessMapping() {
+ StringList result = new StringList();
+ result.string = asList(factory.getFactoryProcessMapping());
+ return result;
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsFactoryProcessMapping() {
+ return opt();
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public URList usageRecords() {
+ URList result = new URList();
+ result.usageRecord = usageRecords.getUsageRecords();
+ return result;
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsUsageRecords() {
+ return opt();
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public UserList users(UriInfo ui) {
+ UserList ul = new UserList();
+ UriBuilder ub = secure(ui).path("{id}");
+ for (String user : userStore.getUserNames())
+ ul.user.add(ub.build(user));
+ return ul;
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsUsers() {
+ return opt("POST");
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public UserDesc user(String username) {
+ UserDesc desc = new UserDesc();
+ User u = userStore.getUser(username);
+ desc.username = u.getUsername();
+ desc.localUserId = u.getLocalUsername();
+ desc.admin = u.isAdmin();
+ desc.enabled = u.isEnabled();
+ return desc;
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsUser(String username) {
+ return opt("PUT", "DELETE");
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response useradd(UserDesc userdesc, UriInfo ui) {
+ if (userdesc.username == null)
+ throw new IllegalArgumentException("no user name supplied");
+ if (userdesc.password == null)
+ userdesc.password = randomUUID().toString();
+ userStore.addUser(userdesc.username, userdesc.password, false);
+ if (userdesc.localUserId != null)
+ userStore.setUserLocalUser(userdesc.username, userdesc.localUserId);
+ if (userdesc.admin != null && userdesc.admin)
+ userStore.setUserAdmin(userdesc.username, true);
+ if (userdesc.enabled != null && userdesc.enabled)
+ userStore.setUserEnabled(userdesc.username, true);
+ return created(secure(ui).path("{id}").build(userdesc.username))
+ .build();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public UserDesc userset(String username, UserDesc userdesc) {
+ if (userdesc.password != null)
+ userStore.setUserPassword(username, userdesc.password);
+ if (userdesc.localUserId != null)
+ userStore.setUserLocalUser(username, userdesc.localUserId);
+ if (userdesc.admin != null)
+ userStore.setUserAdmin(username, userdesc.admin);
+ if (userdesc.enabled != null)
+ userStore.setUserEnabled(username, userdesc.enabled);
+ userdesc = null; // Stop reuse!
+
+ UserDesc desc = new UserDesc();
+ User u = userStore.getUser(username);
+ desc.username = u.getUsername();
+ desc.localUserId = u.getLocalUsername();
+ desc.admin = u.isAdmin();
+ desc.enabled = u.isEnabled();
+ return desc;
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response userdel(String username) {
+ userStore.deleteUser(username);
+ return noContent().build();
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public int operatingCount() {
+ try {
+ return factory.getOperatingCount();
+ } catch (Exception e) {
+ throw new GeneralFailureException(e);
+ }
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsOperatingCount() {
+ return opt();
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public int getOperatingLimit() {
+ return factory.getOperatingLimit();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public int setOperatingLimit(int operatingLimit) {
+ factory.setOperatingLimit(operatingLimit);
+ return factory.getOperatingLimit();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsOperatingLimit() {
+ return opt("PUT");
+ }
+
+ // /////////////////////////////////////////////////////
+ @RolesAllowed(ADMIN)
+ @Override
+ public StringList getPermittedWorkflowURIs() {
+ StringList sl = new StringList();
+ List<URI> uris = localWorker.getPermittedWorkflowURIs();
+ if (uris != null)
+ for (URI uri : uris)
+ sl.string.add(uri.toString());
+ return sl;
+ }
+
+ private static final URI myExp = URI.create("http://www.myexperment.org/");
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public StringList setPermittedWorkflowURIs(StringList permitted) {
+ List<URI> uris = new ArrayList<>();
+ for (String uri : permitted.string)
+ try {
+ uris.add(myExp.resolve(uri));
+ } catch (Exception e) {
+ // Ignore
+ }
+ localWorker.setPermittedWorkflowURIs(uris);
+ return getPermittedWorkflowURIs();
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsPermittedWorkflowURIs() {
+ return opt("PUT");
+ }
+
+ // /////////////////////////////////////////////////////
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public String getGenerateProvenance() {
+ return Boolean.toString(localWorker.getGenerateProvenance());
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public String setGenerateProvenance(String newValue) {
+ boolean b = Boolean.parseBoolean(newValue);
+ localWorker.setGenerateProvenance(b);
+ return Boolean.toString(localWorker.getGenerateProvenance());
+ }
+
+ @RolesAllowed(ADMIN)
+ @Override
+ public Response optionsGenerateProvenance() {
+ return opt("PUT");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/admin/package-info.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/admin/package-info.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/admin/package-info.java
new file mode 100644
index 0000000..930fd75
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/admin/package-info.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+/**
+ * This package contains the RESTful administration interface to Taverna Server.
+ * @author Donal Fellows
+ */
+@XmlSchema(namespace = ADMIN, elementFormDefault = QUALIFIED, attributeFormDefault = QUALIFIED, xmlns = {
+ @XmlNs(prefix = "xlink", namespaceURI = XLINK),
+ @XmlNs(prefix = "ts", namespaceURI = SERVER),
+ @XmlNs(prefix = "ts-rest", namespaceURI = SERVER_REST),
+ @XmlNs(prefix = "ts-soap", namespaceURI = SERVER_SOAP),
+ @XmlNs(prefix = "feed", namespaceURI = FEED),
+ @XmlNs(prefix = "admin", namespaceURI = ADMIN),
+ @XmlNs(prefix = "ur", namespaceURI = UR),
+ @XmlNs(prefix = "ds", namespaceURI = XSIG) })
+package org.taverna.server.master.admin;
+
+import static javax.xml.bind.annotation.XmlNsForm.QUALIFIED;
+import static org.taverna.server.master.common.Namespaces.ADMIN;
+import static org.taverna.server.master.common.Namespaces.FEED;
+import static org.taverna.server.master.common.Namespaces.SERVER;
+import static org.taverna.server.master.common.Namespaces.SERVER_REST;
+import static org.taverna.server.master.common.Namespaces.SERVER_SOAP;
+import static org.taverna.server.master.common.Namespaces.UR;
+import static org.taverna.server.master.common.Namespaces.XLINK;
+import static org.taverna.server.master.common.Namespaces.XSIG;
+
+import javax.xml.bind.annotation.XmlNs;
+import javax.xml.bind.annotation.XmlSchema;
+
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/api/ContentTypes.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/api/ContentTypes.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/ContentTypes.java
new file mode 100644
index 0000000..1a89b8d
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/ContentTypes.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010-2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.api;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
+import static javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM_TYPE;
+import static javax.ws.rs.core.MediaType.APPLICATION_XML_TYPE;
+
+import java.util.List;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Variant;
+
+/**
+ * The content types supported at various points in the REST interface.
+ *
+ * @author Donal Fellows
+ */
+public interface ContentTypes {
+ /** "application/zip" */
+ public static final MediaType APPLICATION_ZIP_TYPE = new MediaType(
+ "application", "zip");
+
+ /** "application/vnd.taverna.baclava+xml" */
+ public static final MediaType BACLAVA_MEDIA_TYPE = new MediaType(
+ "application", "vnd.taverna.baclava+xml");
+
+ /**
+ * The media types that we are willing to serve up directories as. Note that
+ * we <i>only</i> serve directories up as these.
+ */
+ public static final List<Variant> DIRECTORY_VARIANTS = asList(new Variant(
+ APPLICATION_XML_TYPE, (String) null, "UTF-8"), new Variant(
+ APPLICATION_JSON_TYPE, (String) null, "UTF-8"), new Variant(
+ APPLICATION_ZIP_TYPE, (String) null, null));
+
+ /**
+ * The baseline set of media types that we are willing to serve up files as.
+ * Note that we <i>also</i> serve files up as their auto-detected media
+ * type. In all cases, this means we just shovel the bytes (or characters,
+ * in the case of <tt>text/*</tt> subtypes) back at the client.
+ */
+ public static final List<Variant> INITIAL_FILE_VARIANTS = singletonList(new Variant(
+ APPLICATION_OCTET_STREAM_TYPE, (String) null, null));
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/api/DirectoryBean.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/api/DirectoryBean.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/DirectoryBean.java
new file mode 100644
index 0000000..8fa5c78
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/DirectoryBean.java
@@ -0,0 +1,16 @@
+package org.taverna.server.master.api;
+
+import org.taverna.server.master.rest.TavernaServerDirectoryREST;
+import org.taverna.server.master.interfaces.TavernaRun;
+import org.taverna.server.master.utils.FilenameUtils;
+
+/**
+ * Description of properties supported by {@link DirectoryREST}.
+ *
+ * @author Donal Fellows
+ */
+public interface DirectoryBean extends SupportAware {
+ void setFileUtils(FilenameUtils fileUtils);
+
+ TavernaServerDirectoryREST connect(TavernaRun run);
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/api/FeedBean.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/api/FeedBean.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/FeedBean.java
new file mode 100644
index 0000000..5ace6a3
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/FeedBean.java
@@ -0,0 +1,13 @@
+package org.taverna.server.master.api;
+
+import org.taverna.server.master.InteractionFeed;
+import org.taverna.server.master.interaction.InteractionFeedSupport;
+
+/**
+ * Description of properties supported by {@link InteractionFeed}.
+ *
+ * @author Donal Fellows
+ */
+public interface FeedBean {
+ void setInteractionFeedSupport(InteractionFeedSupport feed);
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/api/InputBean.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/api/InputBean.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/InputBean.java
new file mode 100644
index 0000000..eecea44
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/InputBean.java
@@ -0,0 +1,21 @@
+package org.taverna.server.master.api;
+
+import javax.ws.rs.core.UriInfo;
+
+import org.taverna.server.master.ContentsDescriptorBuilder;
+import org.taverna.server.master.interfaces.TavernaRun;
+import org.taverna.server.master.rest.TavernaServerInputREST;
+import org.taverna.server.master.utils.FilenameUtils;
+
+/**
+ * Description of properties supported by {@link InputREST}.
+ *
+ * @author Donal Fellows
+ */
+public interface InputBean extends SupportAware {
+ TavernaServerInputREST connect(TavernaRun run, UriInfo ui);
+
+ void setCdBuilder(ContentsDescriptorBuilder cd);
+
+ void setFileUtils(FilenameUtils fn);
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/api/ListenerPropertyBean.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/api/ListenerPropertyBean.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/ListenerPropertyBean.java
new file mode 100644
index 0000000..5c480d4
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/ListenerPropertyBean.java
@@ -0,0 +1,15 @@
+package org.taverna.server.master.api;
+
+import org.taverna.server.master.interfaces.Listener;
+import org.taverna.server.master.interfaces.TavernaRun;
+import org.taverna.server.master.rest.TavernaServerListenersREST;
+
+/**
+ * Description of properties supported by {@link ListenerPropertyREST}.
+ *
+ * @author Donal Fellows
+ */
+public interface ListenerPropertyBean extends SupportAware {
+ TavernaServerListenersREST.Property connect(Listener listen,
+ TavernaRun run, String propertyName);
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/api/ListenersBean.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/api/ListenersBean.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/ListenersBean.java
new file mode 100644
index 0000000..c02bf62
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/ListenersBean.java
@@ -0,0 +1,13 @@
+package org.taverna.server.master.api;
+
+import org.taverna.server.master.interfaces.TavernaRun;
+import org.taverna.server.master.rest.TavernaServerListenersREST;
+
+/**
+ * Description of properties supported by {@link ListenersREST}.
+ *
+ * @author Donal Fellows
+ */
+public interface ListenersBean extends SupportAware {
+ TavernaServerListenersREST connect(TavernaRun run);
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/api/ManagementModel.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/api/ManagementModel.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/ManagementModel.java
new file mode 100644
index 0000000..6bc6058
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/ManagementModel.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2010-2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.api;
+
+/**
+ * The model of the webapp's state Java Bean.
+ *
+ * @author Donal Fellows
+ */
+public interface ManagementModel {
+ /**
+ * @return whether we allow the creation of new workflow runs.
+ */
+ boolean getAllowNewWorkflowRuns();
+
+ /**
+ * @return whether we should log all workflows sent to us.
+ */
+ boolean getLogIncomingWorkflows();
+
+ /**
+ * @return whether outgoing exceptions should be logged before being
+ * converted to responses.
+ */
+ boolean getLogOutgoingExceptions();
+
+ /**
+ * @return the file that all usage records should be appended to, or
+ * <tt>null</tt> if they should be just dropped.
+ */
+ String getUsageRecordLogFile();
+
+ /**
+ * @param logIncomingWorkflows
+ * whether we should log all workflows sent to us.
+ */
+ void setLogIncomingWorkflows(boolean logIncomingWorkflows);
+
+ /**
+ * @param allowNewWorkflowRuns
+ * whether we allow the creation of new workflow runs.
+ */
+ void setAllowNewWorkflowRuns(boolean allowNewWorkflowRuns);
+
+ /**
+ * @param logOutgoingExceptions
+ * whether outgoing exceptions should be logged before being
+ * converted to responses.
+ */
+ void setLogOutgoingExceptions(boolean logOutgoingExceptions);
+
+ /**
+ * @param usageRecordLogFile
+ * the file that all usage records should be appended to, or
+ * <tt>null</tt> if they should be just dropped.
+ */
+ void setUsageRecordLogFile(String usageRecordLogFile);
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/api/OneListenerBean.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/api/OneListenerBean.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/OneListenerBean.java
new file mode 100644
index 0000000..9f80a12
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/OneListenerBean.java
@@ -0,0 +1,14 @@
+package org.taverna.server.master.api;
+
+import org.taverna.server.master.interfaces.Listener;
+import org.taverna.server.master.interfaces.TavernaRun;
+import org.taverna.server.master.rest.TavernaServerListenersREST.TavernaServerListenerREST;
+
+/**
+ * Description of properties supported by {@link InputREST}.
+ *
+ * @author Donal Fellows
+ */
+public interface OneListenerBean {
+ TavernaServerListenerREST connect(Listener listen, TavernaRun run);
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/api/RunBean.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/api/RunBean.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/RunBean.java
new file mode 100644
index 0000000..4903ea9
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/RunBean.java
@@ -0,0 +1,17 @@
+package org.taverna.server.master.api;
+
+import org.taverna.server.master.ContentsDescriptorBuilder;
+import org.taverna.server.master.interfaces.TavernaRun;
+
+/**
+ * Description of properties supported by {@link RunREST}.
+ *
+ * @author Donal Fellows
+ */
+public interface RunBean extends SupportAware {
+ void setCdBuilder(ContentsDescriptorBuilder cdBuilder);
+
+ void setRun(TavernaRun run);
+
+ void setRunName(String runName);
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/api/SecurityBean.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/api/SecurityBean.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/SecurityBean.java
new file mode 100644
index 0000000..04fbd6e
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/SecurityBean.java
@@ -0,0 +1,14 @@
+package org.taverna.server.master.api;
+
+import org.taverna.server.master.interfaces.TavernaRun;
+import org.taverna.server.master.interfaces.TavernaSecurityContext;
+import org.taverna.server.master.rest.TavernaServerSecurityREST;
+
+/**
+ * Description of properties supported by {@link RunSecurityREST}.
+ *
+ * @author Donal Fellows
+ */
+public interface SecurityBean extends SupportAware {
+ TavernaServerSecurityREST connect(TavernaSecurityContext context, TavernaRun run);
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/api/SupportAware.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/api/SupportAware.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/SupportAware.java
new file mode 100644
index 0000000..c632657
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/SupportAware.java
@@ -0,0 +1,21 @@
+package org.taverna.server.master.api;
+
+import org.springframework.beans.factory.annotation.Required;
+import org.taverna.server.master.TavernaServerSupport;
+
+/**
+ * Indicates that this is a class that wants to be told by Spring about the
+ * main support bean.
+ *
+ * @author Donal Fellows
+ */
+public interface SupportAware {
+ /**
+ * How to tell the bean about the support bean.
+ *
+ * @param support
+ * Reference to the support bean.
+ */
+ @Required
+ void setSupport(TavernaServerSupport support);
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/api/TavernaServerBean.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/api/TavernaServerBean.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/TavernaServerBean.java
new file mode 100644
index 0000000..5a14fb6
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/TavernaServerBean.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.api;
+
+import javax.annotation.Nonnull;
+
+import org.springframework.beans.factory.annotation.Required;
+import org.taverna.server.master.ContentsDescriptorBuilder;
+import org.taverna.server.master.TavernaServerSupport;
+import org.taverna.server.master.interfaces.Policy;
+import org.taverna.server.master.interfaces.RunStore;
+import org.taverna.server.master.interfaces.TavernaSecurityContext;
+import org.taverna.server.master.interfaces.UriBuilderFactory;
+import org.taverna.server.master.notification.NotificationEngine;
+import org.taverna.server.master.notification.atom.EventDAO;
+import org.taverna.server.master.rest.TavernaServerREST;
+import org.taverna.server.master.soap.TavernaServerSOAP;
+import org.taverna.server.master.utils.FilenameUtils;
+
+/**
+ * The methods of the webapp that are accessed by beans other than itself or
+ * those which are told directly about it. This exists so that an AOP proxy can
+ * be installed around it.
+ *
+ * @author Donal Fellows
+ */
+public interface TavernaServerBean extends TavernaServerSOAP, TavernaServerREST,
+ UriBuilderFactory {
+ /**
+ * @param policy
+ * The policy being installed by Spring.
+ */
+ @Required
+ void setPolicy(@Nonnull Policy policy);
+
+ /**
+ * @param runStore
+ * The run store being installed by Spring.
+ */
+ @Required
+ void setRunStore(@Nonnull RunStore runStore);
+
+ /**
+ * @param converter
+ * The filename converter being installed by Spring.
+ */
+ @Required
+ void setFileUtils(@Nonnull FilenameUtils converter);
+
+ /**
+ * @param cdBuilder
+ * The contents descriptor builder being installed by Spring.
+ */
+ @Required
+ void setContentsDescriptorBuilder(
+ @Nonnull ContentsDescriptorBuilder cdBuilder);
+
+ /**
+ * @param notificationEngine
+ * The notification engine being installed by Spring.
+ */
+ @Required
+ void setNotificationEngine(@Nonnull NotificationEngine notificationEngine);
+
+ /**
+ * @param support
+ * The support bean being installed by Spring.
+ */
+ @Required
+ void setSupport(@Nonnull TavernaServerSupport support);
+
+ /**
+ * @param eventSource
+ * The event source bean being installed by Spring.
+ */
+ @Required
+ void setEventSource(@Nonnull EventDAO eventSource);
+
+ /**
+ * The nastier parts of security initialisation in SOAP calls, which we want
+ * to go away.
+ *
+ * @param context
+ * The context to configure.
+ * @return True if we did <i>not</i> initialise things.
+ */
+ boolean initObsoleteSOAPSecurity(@Nonnull TavernaSecurityContext context);
+
+ /**
+ * The nastier parts of security initialisation in REST calls, which we want
+ * to go away.
+ *
+ * @param context
+ * The context to configure.
+ * @return True if we did <i>not</i> initialise things.
+ */
+ boolean initObsoleteRESTSecurity(@Nonnull TavernaSecurityContext context);
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/api/package-info.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/api/package-info.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/package-info.java
new file mode 100644
index 0000000..fe76a09
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/api/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * API <tt>interface</tt>s for the main service classes.
+ *
+ * @author Donal Fellows
+ */
+package org.taverna.server.master.api;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Capability.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Capability.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Capability.java
new file mode 100644
index 0000000..034d489
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Capability.java
@@ -0,0 +1,22 @@
+package org.taverna.server.master.common;
+
+import java.net.URI;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Describes a single capability supported by Taverna Server's workflow
+ * execution core.
+ *
+ * @author Donal Fellows
+ */
+@XmlType(name = "Capability")
+public class Capability {
+ @XmlAttribute
+ @XmlSchemaType(name = "anyURI")
+ public URI capability;
+ @XmlAttribute
+ public String version;
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Credential.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Credential.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Credential.java
new file mode 100644
index 0000000..5c16e79
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Credential.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2011-2012 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.common;
+
+import static org.taverna.server.master.common.Namespaces.XLINK;
+
+import java.io.Serializable;
+import java.net.URI;
+import java.security.Key;
+import java.security.cert.Certificate;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+
+import javax.annotation.Nonnull;
+
+/**
+ * A description of a private credential. This description is characterised by a
+ * file visible to the workflow run that contains a particular key-pair.
+ *
+ * @author Donal Fellows
+ */
+@XmlType(name = "CredentialDescriptor")
+@XmlSeeAlso({ Credential.KeyPair.class, Credential.Password.class })
+@SuppressWarnings("serial")
+public abstract class Credential implements Serializable {
+ /** The location of this descriptor in the REST world. */
+ @XmlAttribute(namespace = XLINK)
+ public String href;
+ /**
+ * The location of this descriptor in the SOAP world. Must match corrected
+ * with the {@link #href} field.
+ */
+ @XmlTransient
+ public String id;
+ /**
+ * The service URI to use this credential with. If omitted, this represents
+ * the <i>default</i> credential to use.
+ */
+ @XmlElement
+ @XmlSchemaType(name = "anyURI")
+ public URI serviceURI;
+ /** The key extracted from the keystore. */
+ public transient Key loadedKey;
+ /** The trust chain of the key extracted from the keystore. */
+ public transient Certificate[] loadedTrustChain;
+
+ @Override
+ public int hashCode() {
+ return id.hashCode();
+ }
+
+ @Override
+ public final boolean equals(Object o) {
+ if (o == null || !(o instanceof Credential))
+ return false;
+ return equals((Credential) o);
+ }
+
+ protected boolean equals(@Nonnull Credential c) {
+ return id.equals(c.id);
+ }
+
+ /**
+ * A description of a credential that is a public/private key-pair in some
+ * kind of key store.
+ *
+ * @author Donal Fellows
+ */
+ @XmlRootElement(name = "keypair")
+ @XmlType(name = "KeyPairCredential")
+ public static class KeyPair extends Credential {
+ /** The name of the credential within its store, i.e., it's alias. */
+ @XmlElement(required = true)
+ public String credentialName;
+ /**
+ * The keystore file containing the credential. This is resolved with
+ * respect to the workflow run working directory.
+ */
+ @XmlElement
+ public String credentialFile;
+ /**
+ * The type of keystore file. Defaults to <tt>JKS</tt> if unspecified.
+ */
+ @XmlElement
+ public String fileType;
+ /**
+ * The password used to unlock the keystore file. It is assumed that the
+ * same password is used for unlocking the credential within, or that
+ * the inner password is empty.
+ */
+ @XmlElement
+ public String unlockPassword;
+ /**
+ * The encoded serialized keystore containing the credential.
+ */
+ @XmlElement
+ public byte[] credentialBytes;
+
+ @Override
+ public String toString() {
+ return "keypair(id=" + id + ")";
+ }
+ }
+
+ /**
+ * A description of a credential that is a username and password.
+ *
+ * @author Donal Fellows
+ */
+ @XmlRootElement(name = "userpass")
+ @XmlType(name = "PasswordCredential")
+ public static class Password extends Credential {
+ @XmlElement(required = true)
+ public String username;
+ @XmlElement(required = true)
+ public String password;
+
+ @Override
+ public String toString() {
+ return "userpass(id=" + id + ")";
+ }
+ }
+
+ /**
+ * A credential that is just used for deleting credentials by ID. Cannot be
+ * marshalled as XML.
+ *
+ * @author Donal Fellows
+ */
+ public static class Dummy extends Credential {
+ public Dummy(String id) {
+ this.id = id;
+ }
+
+ @Override
+ public String toString() {
+ return "dummy(id=" + id + ")";
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/common/DirEntryReference.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/common/DirEntryReference.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/DirEntryReference.java
new file mode 100644
index 0000000..318ae4f
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/DirEntryReference.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2010 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.common;
+
+import static org.taverna.server.master.common.Namespaces.XLINK;
+
+import java.net.URI;
+
+import javax.ws.rs.core.UriBuilder;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.XmlValue;
+
+import org.taverna.server.master.interfaces.Directory;
+import org.taverna.server.master.interfaces.DirectoryEntry;
+
+/**
+ * A reference to something that is in a directory below the working directory
+ * of a workflow run, described using JAXB. Note that when creating an XML
+ * document containing one of these in a client, it is <i>not</i> necessary to
+ * supply any attribute.
+ *
+ * @author Donal Fellows
+ */
+@XmlType(name = "DirectoryEntry")
+@XmlSeeAlso( { DirEntryReference.DirectoryReference.class,
+ DirEntryReference.FileReference.class })
+public class DirEntryReference {
+ /** A link to the entry. Ignored on input. */
+ @XmlAttribute(name = "href", namespace = XLINK)
+ @XmlSchemaType(name = "anyURI")
+ public URI link;
+ /** The last, user-displayable part of the name. Ignored on input. */
+ @XmlAttribute
+ public String name;
+ /** The path of the entry. */
+ @XmlValue
+ public String path;
+
+ /**
+ * Return the directory entry reference instance subclass suitable for the
+ * given directory entry.
+ *
+ * @param entry
+ * The entry to characterise.
+ * @return An object that describes the directory entry.
+ */
+ public static DirEntryReference newInstance(DirectoryEntry entry) {
+ return newInstance(null, entry);
+ }
+
+ /**
+ * Return the directory entry reference instance subclass suitable for the
+ * given directory entry.
+ *
+ * @param ub
+ * Used for constructing URIs. The {@link #link} field is not
+ * filled in if this is <tt>null</tt>.
+ * @param entry
+ * The entry to characterise.
+ * @return An object that describes the directory entry.
+ */
+ // Really returns a subclass, so cannot be constructor
+ public static DirEntryReference newInstance(UriBuilder ub,
+ DirectoryEntry entry) {
+ DirEntryReference de = (entry instanceof Directory) ? new DirectoryReference()
+ : new FileReference();
+ de.name = entry.getName();
+ String fullname = entry.getFullName();
+ de.path = fullname.startsWith("/") ? fullname.substring(1) : fullname;
+ if (ub != null)
+ de.link = ub.build(entry.getName());
+ return de;
+ }
+
+ /** A reference to a directory, done with JAXB. */
+ @XmlRootElement(name = "dir")
+ @XmlType(name = "DirectoryReference")
+ public static class DirectoryReference extends DirEntryReference {
+ }
+
+ /** A reference to a file, done with JAXB. */
+ @XmlRootElement(name = "file")
+ @XmlType(name = "FileReference")
+ public static class FileReference extends DirEntryReference {
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/common/InputDescription.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/common/InputDescription.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/InputDescription.java
new file mode 100644
index 0000000..bb98d6d
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/InputDescription.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2010 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.common;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.XmlValue;
+
+import org.taverna.server.master.interfaces.Input;
+import org.taverna.server.master.interfaces.TavernaRun;
+
+/**
+ * A description of the inputs to a workflow, described using JAXB.
+ *
+ * @author Donal Fellows
+ */
+@XmlRootElement(name = "inputConfiguration")
+@XmlType(name = "InputConfigurationDescription")
+public class InputDescription extends VersionedElement {
+ /**
+ * The Baclava file handling the description of the elements. May be
+ * omitted/<tt>null</tt>.
+ */
+ @XmlElement(required = false)
+ public String baclavaFile;
+ /**
+ * The port/value assignment.
+ */
+ @XmlElement(nillable = false)
+ public List<Port> port = new ArrayList<>();
+
+ /**
+ * Make a blank input description.
+ */
+ public InputDescription() {
+ }
+
+ /**
+ * Make an input description suitable for the given workflow run.
+ *
+ * @param run
+ */
+ public InputDescription(TavernaRun run) {
+ super(true);
+ baclavaFile = run.getInputBaclavaFile();
+ if (baclavaFile == null)
+ for (Input i : run.getInputs())
+ port.add(new Port(i));
+ }
+
+ /**
+ * The type of a single port description.
+ *
+ * @author Donal Fellows
+ */
+ @XmlType(name = "PortConfigurationDescription")
+ public static class Port {
+ /**
+ * The name of this port.
+ */
+ @XmlAttribute(name = "portName", required = true)
+ public String name;
+ /**
+ * The file assigned to this port.
+ */
+ @XmlAttribute(name = "portFile", required = false)
+ public String file;
+ /**
+ * The file assigned to this port.
+ */
+ @XmlAttribute(name = "listDelimiter", required = false)
+ public String delimiter;
+ /**
+ * The value assigned to this port.
+ */
+ @XmlValue
+ public String value;
+
+ /**
+ * Make a blank port description.
+ */
+ public Port() {
+ }
+
+ /**
+ * Make a port description suitable for the given input.
+ *
+ * @param input
+ */
+ public Port(Input input) {
+ name = input.getName();
+ if (input.getFile() != null) {
+ file = input.getFile();
+ value = "";
+ } else {
+ file = null;
+ value = input.getValue();
+ }
+ delimiter = input.getDelimiter();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Namespaces.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Namespaces.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Namespaces.java
new file mode 100644
index 0000000..1311272
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Namespaces.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2010-2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.common;
+
+/**
+ * A convenient place to keep the names of URIs so that they can be got right
+ * <i>once</i>.
+ *
+ * @author Donal Fellows
+ */
+public interface Namespaces {
+ /**
+ * The XLink specification's namespace name.
+ */
+ public static final String XLINK = "http://www.w3.org/1999/xlink";
+ /**
+ * The XML Digital Signature specification's namespace name.
+ */
+ public static final String XSIG = "http://www.w3.org/2000/09/xmldsig#";
+ /**
+ * The Usage Record specification's namespace name.
+ */
+ public static final String UR = "http://schema.ogf.org/urf/2003/09/urf";
+ /**
+ * The T2flow document format's namespace name.
+ */
+ public static final String T2FLOW = "http://taverna.sf.net/2008/xml/t2flow";
+ /**
+ * The namespace for the server.
+ */
+ public static final String SERVER = "http://ns.taverna.org.uk/2010/xml/server/";
+ public static final String SERVER_REST = SERVER + "rest/";
+ public static final String SERVER_SOAP = SERVER + "soap/";
+ public static final String FEED = SERVER + "feed/";
+ public static final String ADMIN = SERVER + "admin/";
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Permission.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Permission.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Permission.java
new file mode 100644
index 0000000..258bfd0
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Permission.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.common;
+
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlEnumValue;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Description of a permission to access a particular workflow run. Note that
+ * users always have full access to their own runs, as does any user with the "
+ * <tt>{@value org.taverna.server.master.common.Roles#ADMIN}</tt>" ability.
+ *
+ * @author Donal Fellows
+ */
+@XmlType(name = "Permission")
+@XmlEnum
+public enum Permission {
+ /** Indicates that a user cannot see the workflow run at all. */
+ @XmlEnumValue("none")
+ None,
+ /**
+ * Indicates that a user can see the workflow run and its contents, but
+ * can't modify anything.
+ */
+ @XmlEnumValue("read")
+ Read,
+ /**
+ * Indicates that a user can update most aspects of a workflow, but cannot
+ * work with either its security features or its lifetime.
+ */
+ @XmlEnumValue("update")
+ Update,
+ /**
+ * Indicates that a user can update almost all aspects of a workflow, with
+ * only its security features being shrouded.
+ */
+ @XmlEnumValue("destroy")
+ Destroy
+}
\ No newline at end of file