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:43 UTC
[43/49] incubator-taverna-server git commit: taverna-* module names
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/server-webapp/src/main/java/org/taverna/server/master/TavernaServer.java
----------------------------------------------------------------------
diff --git a/server-webapp/src/main/java/org/taverna/server/master/TavernaServer.java b/server-webapp/src/main/java/org/taverna/server/master/TavernaServer.java
deleted file mode 100644
index 0f98da6..0000000
--- a/server-webapp/src/main/java/org/taverna/server/master/TavernaServer.java
+++ /dev/null
@@ -1,1425 +0,0 @@
-/*
- * Copyright (C) 2010-2011 The University of Manchester
- *
- * See the file "LICENSE" for license terms.
- */
-package org.taverna.server.master;
-
-import static java.lang.Math.min;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.sort;
-import static java.util.UUID.randomUUID;
-import static javax.ws.rs.core.Response.created;
-import static javax.ws.rs.core.UriBuilder.fromUri;
-import static javax.xml.ws.handler.MessageContext.HTTP_REQUEST_HEADERS;
-import static javax.xml.ws.handler.MessageContext.PATH_INFO;
-import static org.apache.commons.io.IOUtils.toByteArray;
-import static org.apache.commons.logging.LogFactory.getLog;
-import static org.taverna.server.master.TavernaServerSupport.PROV_BUNDLE;
-import static org.taverna.server.master.common.DirEntryReference.newInstance;
-import static org.taverna.server.master.common.Namespaces.SERVER_SOAP;
-import static org.taverna.server.master.common.Roles.ADMIN;
-import static org.taverna.server.master.common.Roles.SELF;
-import static org.taverna.server.master.common.Roles.USER;
-import static org.taverna.server.master.common.Status.Initialized;
-import static org.taverna.server.master.common.Uri.secure;
-import static org.taverna.server.master.soap.DirEntry.convert;
-import static org.taverna.server.master.utils.RestUtils.opt;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.annotation.PreDestroy;
-import javax.annotation.Resource;
-import javax.annotation.security.DeclareRoles;
-import javax.annotation.security.RolesAllowed;
-import javax.jws.WebService;
-import javax.ws.rs.Path;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriBuilder;
-import javax.ws.rs.core.UriInfo;
-import javax.xml.bind.JAXBException;
-import javax.xml.ws.WebServiceContext;
-
-import org.apache.commons.logging.Log;
-import org.apache.cxf.annotations.WSDLDocumentation;
-import org.ogf.usage.JobUsageRecord;
-import org.springframework.beans.factory.annotation.Required;
-import org.taverna.server.master.api.SupportAware;
-import org.taverna.server.master.api.TavernaServerBean;
-import org.taverna.server.master.common.Capability;
-import org.taverna.server.master.common.Credential;
-import org.taverna.server.master.common.DirEntryReference;
-import org.taverna.server.master.common.InputDescription;
-import org.taverna.server.master.common.Permission;
-import org.taverna.server.master.common.ProfileList;
-import org.taverna.server.master.common.RunReference;
-import org.taverna.server.master.common.Status;
-import org.taverna.server.master.common.Trust;
-import org.taverna.server.master.common.Workflow;
-import org.taverna.server.master.common.version.Version;
-import org.taverna.server.master.exceptions.BadPropertyValueException;
-import org.taverna.server.master.exceptions.BadStateChangeException;
-import org.taverna.server.master.exceptions.FilesystemAccessException;
-import org.taverna.server.master.exceptions.InvalidCredentialException;
-import org.taverna.server.master.exceptions.NoCreateException;
-import org.taverna.server.master.exceptions.NoCredentialException;
-import org.taverna.server.master.exceptions.NoDirectoryEntryException;
-import org.taverna.server.master.exceptions.NoListenerException;
-import org.taverna.server.master.exceptions.NoUpdateException;
-import org.taverna.server.master.exceptions.NotOwnerException;
-import org.taverna.server.master.exceptions.OverloadedException;
-import org.taverna.server.master.exceptions.UnknownRunException;
-import org.taverna.server.master.factories.ListenerFactory;
-import org.taverna.server.master.interfaces.Directory;
-import org.taverna.server.master.interfaces.DirectoryEntry;
-import org.taverna.server.master.interfaces.File;
-import org.taverna.server.master.interfaces.Input;
-import org.taverna.server.master.interfaces.Listener;
-import org.taverna.server.master.interfaces.Policy;
-import org.taverna.server.master.interfaces.RunStore;
-import org.taverna.server.master.interfaces.TavernaRun;
-import org.taverna.server.master.interfaces.TavernaSecurityContext;
-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.rest.TavernaServerREST.EnabledNotificationFabrics;
-import org.taverna.server.master.rest.TavernaServerREST.PermittedListeners;
-import org.taverna.server.master.rest.TavernaServerREST.PermittedWorkflows;
-import org.taverna.server.master.rest.TavernaServerREST.PolicyView;
-import org.taverna.server.master.rest.TavernaServerRunREST;
-import org.taverna.server.master.soap.DirEntry;
-import org.taverna.server.master.soap.FileContents;
-import org.taverna.server.master.soap.PermissionList;
-import org.taverna.server.master.soap.TavernaServerSOAP;
-import org.taverna.server.master.soap.WrappedWorkflow;
-import org.taverna.server.master.soap.ZippedDirectory;
-import org.taverna.server.master.utils.CallTimeLogger.PerfLogged;
-import org.taverna.server.master.utils.FilenameUtils;
-import org.taverna.server.master.utils.InvocationCounter.CallCounted;
-import org.taverna.server.port_description.OutputDescription;
-
-/**
- * The core implementation of the web application.
- *
- * @author Donal Fellows
- */
-@Path("/")
-@DeclareRoles({ USER, ADMIN })
-@WebService(endpointInterface = "org.taverna.server.master.soap.TavernaServerSOAP", serviceName = "TavernaServer", targetNamespace = SERVER_SOAP)
-@WSDLDocumentation("An instance of Taverna " + Version.JAVA + " Server.")
-public abstract class TavernaServer implements TavernaServerSOAP,
- TavernaServerREST, TavernaServerBean {
- /**
- * The root of descriptions of the server in JMX.
- */
- public static final String JMX_ROOT = "Taverna:group=Server-"
- + Version.JAVA + ",name=";
-
- /** The logger for the server framework. */
- public Log log = getLog("Taverna.Server.Webapp");
-
- @PreDestroy
- void closeLog() {
- log = null;
- }
-
- // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- // CONNECTIONS TO JMX, SPRING AND CXF
-
- @Resource
- WebServiceContext jaxws;
- @Context
- private HttpHeaders jaxrsHeaders;
-
- // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- // STATE VARIABLES AND SPRING SETTERS
-
- /**
- * For building descriptions of the expected inputs and actual outputs of a
- * workflow.
- */
- private ContentsDescriptorBuilder cdBuilder;
- /**
- * Utilities for accessing files on the local-worker.
- */
- private FilenameUtils fileUtils;
- /** How notifications are dispatched. */
- private NotificationEngine notificationEngine;
- /** Main support class. */
- private TavernaServerSupport support;
- /** A storage facility for workflow runs. */
- private RunStore runStore;
- /** Encapsulates the policies applied by this server. */
- private Policy policy;
- /** Where Atom events come from. */
- EventDAO eventSource;
- /** Reference to the main interaction feed. */
- private String interactionFeed;
-
- @Override
- @Required
- public void setFileUtils(FilenameUtils converter) {
- this.fileUtils = converter;
- }
-
- @Override
- @Required
- public void setContentsDescriptorBuilder(ContentsDescriptorBuilder cdBuilder) {
- this.cdBuilder = cdBuilder;
- }
-
- @Override
- @Required
- public void setNotificationEngine(NotificationEngine notificationEngine) {
- this.notificationEngine = notificationEngine;
- }
-
- /**
- * @param support
- * the support to set
- */
- @Override
- @Required
- public void setSupport(TavernaServerSupport support) {
- this.support = support;
- }
-
- @Override
- @Required
- public void setRunStore(RunStore runStore) {
- this.runStore = runStore;
- }
-
- @Override
- @Required
- public void setPolicy(Policy policy) {
- this.policy = policy;
- }
-
- @Override
- @Required
- public void setEventSource(EventDAO eventSource) {
- this.eventSource = eventSource;
- }
-
- /**
- * The location of a service-wide interaction feed, derived from a
- * properties file. Expected to be <i>actually</i> not set (to a real
- * value).
- *
- * @param interactionFeed
- * The URL, which will be resolved relative to the location of
- * the webapp, or the string "<tt>none</tt>" (which corresponds
- * to a <tt>null</tt>).
- */
- public void setInteractionFeed(String interactionFeed) {
- if ("none".equals(interactionFeed))
- interactionFeed = null;
- else if (interactionFeed != null && interactionFeed.startsWith("${"))
- interactionFeed = null;
- this.interactionFeed = interactionFeed;
- }
-
- // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- // REST INTERFACE
-
- @Override
- @CallCounted
- @PerfLogged
- public ServerDescription describeService(UriInfo ui) {
- jaxrsUriInfo.set(new WeakReference<>(ui));
- return new ServerDescription(ui, resolve(interactionFeed));
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public RunList listUsersRuns(UriInfo ui) {
- jaxrsUriInfo.set(new WeakReference<>(ui));
- return new RunList(runs(), secure(ui).path("{name}"));
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public Response submitWorkflow(Workflow workflow, UriInfo ui)
- throws NoUpdateException {
- jaxrsUriInfo.set(new WeakReference<>(ui));
- checkCreatePolicy(workflow);
- String name = support.buildWorkflow(workflow);
- return created(secure(ui).path("{uuid}").build(name)).build();
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public Response submitWorkflowByURL(List<URI> referenceList, UriInfo ui)
- throws NoCreateException {
- jaxrsUriInfo.set(new WeakReference<>(ui));
- if (referenceList == null || referenceList.size() == 0)
- throw new NoCreateException("no workflow URI supplied");
- URI workflowURI = referenceList.get(0);
- checkCreatePolicy(workflowURI);
- Workflow workflow;
- try {
- workflow = support.getWorkflowDocumentFromURI(workflowURI);
- } catch (IOException e) {
- throw new NoCreateException("could not read workflow", e);
- }
- String name = support.buildWorkflow(workflow);
- return created(secure(ui).path("{uuid}").build(name)).build();
- }
-
- @Override
- @CallCounted
- @PerfLogged
- public int getServerMaxRuns() {
- return support.getMaxSimultaneousRuns();
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed({ USER, SELF })
- public TavernaServerRunREST getRunResource(String runName, UriInfo ui)
- throws UnknownRunException {
- jaxrsUriInfo.set(new WeakReference<>(ui));
- RunREST rr = makeRunInterface();
- rr.setRun(support.getRun(runName));
- rr.setRunName(runName);
- return rr;
- }
-
- private ThreadLocal<Reference<UriInfo>> jaxrsUriInfo = new InheritableThreadLocal<>();
-
- private UriInfo getUriInfo() {
- if (jaxrsUriInfo.get() == null)
- return null;
- return jaxrsUriInfo.get().get();
- }
-
- @Override
- @CallCounted
- public abstract PolicyView getPolicyDescription();
-
- @Override
- @CallCounted
- public Response serviceOptions() {
- return opt();
- }
-
- @Override
- @CallCounted
- public Response runsOptions() {
- return opt("POST");
- }
-
- /**
- * Construct a RESTful interface to a run.
- *
- * @return The handle to the interface, as decorated by Spring.
- */
- protected abstract RunREST makeRunInterface();
-
- // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- // SOAP INTERFACE
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public RunReference[] listRuns() {
- ArrayList<RunReference> ws = new ArrayList<>();
- UriBuilder ub = getRunUriBuilder();
- for (String runName : runs().keySet())
- ws.add(new RunReference(runName, ub));
- return ws.toArray(new RunReference[ws.size()]);
- }
-
- private void checkCreatePolicy(Workflow workflow) throws NoCreateException {
- List<URI> pwu = policy
- .listPermittedWorkflowURIs(support.getPrincipal());
- if (pwu == null || pwu.size() == 0)
- return;
- throw new NoCreateException("server policy: will only start "
- + "workflows sourced from permitted URI list");
- }
-
- private void checkCreatePolicy(URI workflowURI) throws NoCreateException {
- List<URI> pwu = policy
- .listPermittedWorkflowURIs(support.getPrincipal());
- if (pwu == null || pwu.size() == 0 || pwu.contains(workflowURI))
- return;
- throw new NoCreateException("workflow URI not on permitted list");
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public RunReference submitWorkflow(Workflow workflow)
- throws NoUpdateException {
- checkCreatePolicy(workflow);
- String name = support.buildWorkflow(workflow);
- return new RunReference(name, getRunUriBuilder());
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public RunReference submitWorkflowMTOM(WrappedWorkflow workflow)
- throws NoUpdateException {
- Workflow wf;
- try {
- wf = workflow.getWorkflow();
- } catch (IOException e) {
- throw new NoCreateException(e.getMessage(), e);
- }
- checkCreatePolicy(wf);
- String name = support.buildWorkflow(wf);
- return new RunReference(name, getRunUriBuilder());
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public RunReference submitWorkflowByURI(URI workflowURI)
- throws NoCreateException {
- checkCreatePolicy(workflowURI);
- Workflow workflow;
- try {
- workflow = support.getWorkflowDocumentFromURI(workflowURI);
- } catch (IOException e) {
- throw new NoCreateException("could not read workflow", e);
- }
- String name = support.buildWorkflow(workflow);
- return new RunReference(name, getRunUriBuilder());
- }
-
- @Override
- @CallCounted
- @PerfLogged
- public URI[] getServerWorkflows() {
- return support.getPermittedWorkflowURIs();
- }
-
- @Override
- @CallCounted
- @PerfLogged
- public String[] getServerListeners() {
- List<String> types = support.getListenerTypes();
- return types.toArray(new String[types.size()]);
- }
-
- @Override
- @CallCounted
- @PerfLogged
- public String[] getServerNotifiers() {
- List<String> dispatchers = notificationEngine
- .listAvailableDispatchers();
- return dispatchers.toArray(new String[dispatchers.size()]);
- }
-
- @Override
- @CallCounted
- @PerfLogged
- public List<Capability> getServerCapabilities() {
- return support.getCapabilities();
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public void destroyRun(String runName) throws UnknownRunException,
- NoUpdateException {
- support.unregisterRun(runName, null);
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public String getRunDescriptiveName(String runName)
- throws UnknownRunException {
- return support.getRun(runName).getName();
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public void setRunDescriptiveName(String runName, String descriptiveName)
- throws UnknownRunException, NoUpdateException {
- TavernaRun run = support.getRun(runName);
- support.permitUpdate(run);
- run.setName(descriptiveName);
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public Workflow getRunWorkflow(String runName) throws UnknownRunException {
- return support.getRun(runName).getWorkflow();
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public WrappedWorkflow getRunWorkflowMTOM(String runName)
- throws UnknownRunException {
- WrappedWorkflow ww = new WrappedWorkflow();
- ww.setWorkflow(support.getRun(runName).getWorkflow());
- return ww;
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public ProfileList getRunWorkflowProfiles(String runName)
- throws UnknownRunException {
- return support.getProfileDescriptor(support.getRun(runName)
- .getWorkflow());
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public Date getRunExpiry(String runName) throws UnknownRunException {
- return support.getRun(runName).getExpiry();
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public void setRunExpiry(String runName, Date d)
- throws UnknownRunException, NoUpdateException {
- support.updateExpiry(support.getRun(runName), d);
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public Date getRunCreationTime(String runName) throws UnknownRunException {
- return support.getRun(runName).getCreationTimestamp();
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public Date getRunFinishTime(String runName) throws UnknownRunException {
- return support.getRun(runName).getFinishTimestamp();
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public Date getRunStartTime(String runName) throws UnknownRunException {
- return support.getRun(runName).getStartTimestamp();
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public Status getRunStatus(String runName) throws UnknownRunException {
- return support.getRun(runName).getStatus();
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public String setRunStatus(String runName, Status s)
- throws UnknownRunException, NoUpdateException {
- TavernaRun w = support.getRun(runName);
- support.permitUpdate(w);
- if (s == Status.Operating && w.getStatus() == Status.Initialized) {
- if (!support.getAllowStartWorkflowRuns())
- throw new OverloadedException();
- try {
- String issue = w.setStatus(s);
- if (issue == null)
- return "";
- if (issue.isEmpty())
- return "unknown reason for partial change";
- return issue;
- } catch (RuntimeException | NoUpdateException e) {
- log.info("failed to start run " + runName, e);
- throw e;
- }
- } else {
- w.setStatus(s);
- return "";
- }
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public String getRunStdout(String runName) throws UnknownRunException {
- try {
- return support.getProperty(runName, "io", "stdout");
- } catch (NoListenerException e) {
- return "";
- }
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public String getRunStderr(String runName) throws UnknownRunException {
- try {
- return support.getProperty(runName, "io", "stderr");
- } catch (NoListenerException e) {
- return "";
- }
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public JobUsageRecord getRunUsageRecord(String runName)
- throws UnknownRunException {
- try {
- String ur = support.getProperty(runName, "io", "usageRecord");
- if (ur.isEmpty())
- return null;
- return JobUsageRecord.unmarshal(ur);
- } catch (NoListenerException e) {
- return null;
- } catch (JAXBException e) {
- log.info("failed to deserialize non-empty usage record", e);
- return null;
- }
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public String getRunLog(String runName) throws UnknownRunException {
- try {
- return support.getLogs(support.getRun(runName)).get("UTF-8");
- } catch (UnsupportedEncodingException e) {
- log.warn("unexpected encoding problem", e);
- return "";
- }
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public FileContents getRunBundle(String runName)
- throws UnknownRunException, FilesystemAccessException,
- NoDirectoryEntryException {
- File f = fileUtils.getFile(support.getRun(runName), PROV_BUNDLE);
- FileContents fc = new FileContents();
- // We *know* the content type, by definition
- fc.setFile(f, "application/vnd.wf4ever.robundle+zip");
- return fc;
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public boolean getRunGenerateProvenance(String runName)
- throws UnknownRunException {
- return support.getRun(runName).getGenerateProvenance();
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public void setRunGenerateProvenance(String runName, boolean generate)
- throws UnknownRunException, NoUpdateException {
- TavernaRun run = support.getRun(runName);
- support.permitUpdate(run);
- run.setGenerateProvenance(generate);
- }
-
- // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- // SOAP INTERFACE - Security
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public String getRunOwner(String runName) throws UnknownRunException {
- return support.getRun(runName).getSecurityContext().getOwner()
- .getName();
- }
-
- /**
- * Look up a security context, applying access control rules for access to
- * the parts of the context that are only open to the owner.
- *
- * @param runName
- * The name of the workflow run.
- * @param initialOnly
- * Whether to check if we're in the initial state.
- * @return The security context. Never <tt>null</tt>.
- * @throws UnknownRunException
- * @throws NotOwnerException
- * @throws BadStateChangeException
- */
- private TavernaSecurityContext getRunSecurityContext(String runName,
- boolean initialOnly) throws UnknownRunException, NotOwnerException,
- BadStateChangeException {
- TavernaRun run = support.getRun(runName);
- TavernaSecurityContext c = run.getSecurityContext();
- if (!c.getOwner().equals(support.getPrincipal()))
- throw new NotOwnerException();
- if (initialOnly && run.getStatus() != Initialized)
- throw new BadStateChangeException();
- return c;
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public Credential[] getRunCredentials(String runName)
- throws UnknownRunException, NotOwnerException {
- try {
- return getRunSecurityContext(runName, false).getCredentials();
- } catch (BadStateChangeException e) {
- Error e2 = new Error("impossible");
- e2.initCause(e);
- throw e2;
- }
- }
-
- private Credential findCredential(TavernaSecurityContext c, String id)
- throws NoCredentialException {
- for (Credential t : c.getCredentials())
- if (t.id.equals(id))
- return t;
- throw new NoCredentialException();
- }
-
- private Trust findTrust(TavernaSecurityContext c, String id)
- throws NoCredentialException {
- for (Trust t : c.getTrusted())
- if (t.id.equals(id))
- return t;
- throw new NoCredentialException();
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public String setRunCredential(String runName, String credentialID,
- Credential credential) throws UnknownRunException,
- NotOwnerException, InvalidCredentialException,
- NoCredentialException, BadStateChangeException {
- TavernaSecurityContext c = getRunSecurityContext(runName, true);
- if (credentialID == null || credentialID.isEmpty()) {
- credential.id = randomUUID().toString();
- } else {
- credential.id = findCredential(c, credentialID).id;
- }
- URI uri = getRunUriBuilder().path("security/credentials/{credid}")
- .build(runName, credential.id);
- credential.href = uri.toString();
- c.validateCredential(credential);
- c.addCredential(credential);
- return credential.id;
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public void deleteRunCredential(String runName, String credentialID)
- throws UnknownRunException, NotOwnerException,
- NoCredentialException, BadStateChangeException {
- getRunSecurityContext(runName, true).deleteCredential(
- new Credential.Dummy(credentialID));
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public Trust[] getRunCertificates(String runName)
- throws UnknownRunException, NotOwnerException {
- try {
- return getRunSecurityContext(runName, false).getTrusted();
- } catch (BadStateChangeException e) {
- Error e2 = new Error("impossible");
- e2.initCause(e);
- throw e2;
- }
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public String setRunCertificates(String runName, String certificateID,
- Trust certificate) throws UnknownRunException, NotOwnerException,
- InvalidCredentialException, NoCredentialException,
- BadStateChangeException {
- TavernaSecurityContext c = getRunSecurityContext(runName, true);
- if (certificateID == null || certificateID.isEmpty()) {
- certificate.id = randomUUID().toString();
- } else {
- certificate.id = findTrust(c, certificateID).id;
- }
- URI uri = getRunUriBuilder().path("security/trusts/{certid}").build(
- runName, certificate.id);
- certificate.href = uri.toString();
- c.validateTrusted(certificate);
- c.addTrusted(certificate);
- return certificate.id;
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public void deleteRunCertificates(String runName, String certificateID)
- throws UnknownRunException, NotOwnerException,
- NoCredentialException, BadStateChangeException {
- TavernaSecurityContext c = getRunSecurityContext(runName, true);
- Trust toDelete = new Trust();
- toDelete.id = certificateID;
- c.deleteTrusted(toDelete);
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public PermissionList listRunPermissions(String runName)
- throws UnknownRunException, NotOwnerException {
- PermissionList pl = new PermissionList();
- pl.permission = new ArrayList<>();
- Map<String, Permission> perm;
- try {
- perm = support.getPermissionMap(getRunSecurityContext(runName,
- false));
- } catch (BadStateChangeException e) {
- log.error("unexpected error from internal API", e);
- perm = emptyMap();
- }
- List<String> users = new ArrayList<>(perm.keySet());
- sort(users);
- for (String user : users)
- pl.permission.add(new PermissionList.SinglePermissionMapping(user,
- perm.get(user)));
- return pl;
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public void setRunPermission(String runName, String userName,
- Permission permission) throws UnknownRunException,
- NotOwnerException {
- try {
- support.setPermission(getRunSecurityContext(runName, false),
- userName, permission);
- } catch (BadStateChangeException e) {
- log.error("unexpected error from internal API", e);
- }
- }
-
- // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- // SOAP INTERFACE - Filesystem connection
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public OutputDescription getRunOutputDescription(String runName)
- throws UnknownRunException, BadStateChangeException,
- FilesystemAccessException, NoDirectoryEntryException {
- TavernaRun run = support.getRun(runName);
- if (run.getStatus() == Initialized)
- throw new BadStateChangeException(
- "may not get output description in initial state");
- return cdBuilder.makeOutputDescriptor(run, null);
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public DirEntry[] getRunDirectoryContents(String runName, DirEntry d)
- throws UnknownRunException, FilesystemAccessException,
- NoDirectoryEntryException {
- List<DirEntry> result = new ArrayList<>();
- for (DirectoryEntry e : fileUtils.getDirectory(support.getRun(runName),
- convert(d)).getContents())
- result.add(convert(newInstance(null, e)));
- return result.toArray(new DirEntry[result.size()]);
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public byte[] getRunDirectoryAsZip(String runName, DirEntry d)
- throws UnknownRunException, FilesystemAccessException,
- NoDirectoryEntryException {
- try {
- return toByteArray(fileUtils.getDirectory(support.getRun(runName),
- convert(d)).getContentsAsZip());
- } catch (IOException e) {
- throw new FilesystemAccessException("problem serializing ZIP data",
- e);
- }
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public ZippedDirectory getRunDirectoryAsZipMTOM(String runName, DirEntry d)
- throws UnknownRunException, FilesystemAccessException,
- NoDirectoryEntryException {
- return new ZippedDirectory(fileUtils.getDirectory(
- support.getRun(runName), convert(d)));
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public DirEntry makeRunDirectory(String runName, DirEntry parent,
- String name) throws UnknownRunException, NoUpdateException,
- FilesystemAccessException, NoDirectoryEntryException {
- TavernaRun w = support.getRun(runName);
- support.permitUpdate(w);
- Directory dir = fileUtils.getDirectory(w, convert(parent))
- .makeSubdirectory(support.getPrincipal(), name);
- return convert(newInstance(null, dir));
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public DirEntry makeRunFile(String runName, DirEntry parent, String name)
- throws UnknownRunException, NoUpdateException,
- FilesystemAccessException, NoDirectoryEntryException {
- TavernaRun w = support.getRun(runName);
- support.permitUpdate(w);
- File f = fileUtils.getDirectory(w, convert(parent)).makeEmptyFile(
- support.getPrincipal(), name);
- return convert(newInstance(null, f));
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public void destroyRunDirectoryEntry(String runName, DirEntry d)
- throws UnknownRunException, NoUpdateException,
- FilesystemAccessException, NoDirectoryEntryException {
- TavernaRun w = support.getRun(runName);
- support.permitUpdate(w);
- fileUtils.getDirEntry(w, convert(d)).destroy();
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public byte[] getRunFileContents(String runName, DirEntry d)
- throws UnknownRunException, FilesystemAccessException,
- NoDirectoryEntryException {
- File f = fileUtils.getFile(support.getRun(runName), convert(d));
- return f.getContents(0, -1);
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public void setRunFileContents(String runName, DirEntry d,
- byte[] newContents) throws UnknownRunException, NoUpdateException,
- FilesystemAccessException, NoDirectoryEntryException {
- TavernaRun w = support.getRun(runName);
- support.permitUpdate(w);
- fileUtils.getFile(w, convert(d)).setContents(newContents);
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public FileContents getRunFileContentsMTOM(String runName, DirEntry d)
- throws UnknownRunException, FilesystemAccessException,
- NoDirectoryEntryException {
- File f = fileUtils.getFile(support.getRun(runName), convert(d));
- FileContents fc = new FileContents();
- fc.setFile(f, support.getEstimatedContentType(f));
- return fc;
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public void setRunFileContentsFromURI(String runName,
- DirEntryReference file, URI reference)
- throws UnknownRunException, NoUpdateException,
- FilesystemAccessException, NoDirectoryEntryException {
- TavernaRun run = support.getRun(runName);
- support.permitUpdate(run);
- File f = fileUtils.getFile(run, file);
- try {
- support.copyDataToFile(reference, f);
- } catch (IOException e) {
- throw new FilesystemAccessException(
- "problem transferring data from URI", e);
- }
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public void setRunFileContentsMTOM(String runName, FileContents newContents)
- throws UnknownRunException, NoUpdateException,
- FilesystemAccessException, NoDirectoryEntryException {
- TavernaRun run = support.getRun(runName);
- support.permitUpdate(run);
- File f = fileUtils.getFile(run, newContents.name);
- f.setContents(new byte[0]);
- support.copyDataToFile(newContents.fileData, f);
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public String getRunFileType(String runName, DirEntry d)
- throws UnknownRunException, FilesystemAccessException,
- NoDirectoryEntryException {
- return support.getEstimatedContentType(fileUtils.getFile(
- support.getRun(runName), convert(d)));
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public long getRunFileLength(String runName, DirEntry d)
- throws UnknownRunException, FilesystemAccessException,
- NoDirectoryEntryException {
- return fileUtils.getFile(support.getRun(runName), convert(d)).getSize();
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public Date getRunFileModified(String runName, DirEntry d)
- throws UnknownRunException, FilesystemAccessException,
- NoDirectoryEntryException {
- return fileUtils.getFile(support.getRun(runName), convert(d))
- .getModificationDate();
- }
-
- // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- // SOAP INTERFACE - Run listeners
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public String[] getRunListeners(String runName) throws UnknownRunException {
- TavernaRun w = support.getRun(runName);
- List<String> result = new ArrayList<>();
- for (Listener l : w.getListeners())
- result.add(l.getName());
- return result.toArray(new String[result.size()]);
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public String addRunListener(String runName, String listenerType,
- String configuration) throws UnknownRunException,
- NoUpdateException, NoListenerException {
- return support.makeListener(support.getRun(runName), listenerType,
- configuration).getName();
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public String getRunListenerConfiguration(String runName,
- String listenerName) throws UnknownRunException,
- NoListenerException {
- return support.getListener(runName, listenerName).getConfiguration();
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public String[] getRunListenerProperties(String runName, String listenerName)
- throws UnknownRunException, NoListenerException {
- return support.getListener(runName, listenerName).listProperties()
- .clone();
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public String getRunListenerProperty(String runName, String listenerName,
- String propName) throws UnknownRunException, NoListenerException {
- return support.getListener(runName, listenerName).getProperty(propName);
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public void setRunListenerProperty(String runName, String listenerName,
- String propName, String value) throws UnknownRunException,
- NoUpdateException, NoListenerException {
- TavernaRun w = support.getRun(runName);
- support.permitUpdate(w);
- Listener l = support.getListener(w, listenerName);
- try {
- l.getProperty(propName); // sanity check!
- l.setProperty(propName, value);
- } catch (RuntimeException e) {
- throw new NoListenerException("problem setting property: "
- + e.getMessage(), e);
- }
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public InputDescription getRunInputs(String runName)
- throws UnknownRunException {
- return new InputDescription(support.getRun(runName));
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public String getRunOutputBaclavaFile(String runName)
- throws UnknownRunException {
- return support.getRun(runName).getOutputBaclavaFile();
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public void setRunInputBaclavaFile(String runName, String fileName)
- throws UnknownRunException, NoUpdateException,
- FilesystemAccessException, BadStateChangeException {
- TavernaRun w = support.getRun(runName);
- support.permitUpdate(w);
- w.setInputBaclavaFile(fileName);
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public void setRunInputPortFile(String runName, String portName,
- String portFilename) throws UnknownRunException, NoUpdateException,
- FilesystemAccessException, BadStateChangeException {
- TavernaRun w = support.getRun(runName);
- support.permitUpdate(w);
- Input i = support.getInput(w, portName);
- if (i == null)
- i = w.makeInput(portName);
- i.setFile(portFilename);
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public void setRunInputPortValue(String runName, String portName,
- String portValue) throws UnknownRunException, NoUpdateException,
- BadStateChangeException {
- TavernaRun w = support.getRun(runName);
- support.permitUpdate(w);
- Input i = support.getInput(w, portName);
- if (i == null)
- i = w.makeInput(portName);
- i.setValue(portValue);
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public void setRunInputPortListDelimiter(String runName, String portName,
- String delimiter) throws UnknownRunException, NoUpdateException,
- BadStateChangeException, BadPropertyValueException {
- TavernaRun w = support.getRun(runName);
- support.permitUpdate(w);
- Input i = support.getInput(w, portName);
- if (i == null)
- i = w.makeInput(portName);
- if (delimiter != null && delimiter.isEmpty())
- delimiter = null;
- if (delimiter != null) {
- if (delimiter.length() > 1)
- throw new BadPropertyValueException("delimiter too long");
- if (delimiter.charAt(0) < 1 || delimiter.charAt(0) > 127)
- throw new BadPropertyValueException(
- "delimiter character must be non-NUL ASCII");
- }
- i.setDelimiter(delimiter);
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public void setRunOutputBaclavaFile(String runName, String outputFile)
- throws UnknownRunException, NoUpdateException,
- FilesystemAccessException, BadStateChangeException {
- TavernaRun w = support.getRun(runName);
- support.permitUpdate(w);
- w.setOutputBaclavaFile(outputFile);
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public org.taverna.server.port_description.InputDescription getRunInputDescriptor(
- String runName) throws UnknownRunException {
- return cdBuilder.makeInputDescriptor(support.getRun(runName), null);
- }
-
- @Override
- @CallCounted
- @PerfLogged
- @RolesAllowed(USER)
- public String getServerStatus() {
- return support.getAllowNewWorkflowRuns() ? "operational" : "suspended";
- }
-
- // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- // SUPPORT METHODS
-
- @Override
- public boolean initObsoleteSOAPSecurity(TavernaSecurityContext c) {
- try {
- javax.xml.ws.handler.MessageContext msgCtxt = (jaxws == null ? null
- : jaxws.getMessageContext());
- if (msgCtxt == null)
- return true;
- c.initializeSecurityFromSOAPContext(msgCtxt);
- return false;
- } catch (IllegalStateException e) {
- /* ignore; not much we can do */
- return true;
- }
- }
-
- @Override
- public boolean initObsoleteRESTSecurity(TavernaSecurityContext c) {
- if (jaxrsHeaders == null)
- return true;
- c.initializeSecurityFromRESTContext(jaxrsHeaders);
- return false;
- }
-
- /**
- * A creator of substitute {@link URI} builders.
- *
- * @return A URI builder configured so that it takes a path parameter that
- * corresponds to the run ID (but with no such ID applied).
- */
- UriBuilder getRunUriBuilder() {
- return getBaseUriBuilder().path("runs/{uuid}");
- }
-
- @Override
- public UriBuilder getRunUriBuilder(TavernaRun run) {
- return fromUri(getRunUriBuilder().build(run.getId()));
- }
-
- private final String DEFAULT_HOST = "localhost:8080"; // Crappy default
-
- private String getHostLocation() {
- @java.lang.SuppressWarnings("unchecked")
- Map<String, List<String>> headers = (Map<String, List<String>>) jaxws
- .getMessageContext().get(HTTP_REQUEST_HEADERS);
- if (headers != null) {
- List<String> host = headers.get("HOST");
- if (host != null && !host.isEmpty())
- return host.get(0);
- }
- return DEFAULT_HOST;
- }
-
- @Nonnull
- private URI getPossiblyInsecureBaseUri() {
- // See if JAX-RS can supply the info
- UriInfo ui = getUriInfo();
- if (ui != null && ui.getBaseUri() != null)
- return ui.getBaseUri();
- // See if JAX-WS *cannot* supply the info
- if (jaxws == null || jaxws.getMessageContext() == null)
- // Hack to make the test suite work
- return URI.create("http://" + DEFAULT_HOST
- + "/taverna-server/rest/");
- String pathInfo = (String) jaxws.getMessageContext().get(PATH_INFO);
- pathInfo = pathInfo.replaceFirst("/soap$", "/rest/");
- pathInfo = pathInfo.replaceFirst("/rest/.+$", "/rest/");
- return URI.create("http://" + getHostLocation() + pathInfo);
- }
-
- @Override
- public UriBuilder getBaseUriBuilder() {
- return secure(fromUri(getPossiblyInsecureBaseUri()));
- }
-
- @Override
- @Nullable
- public String resolve(@Nullable String uri) {
- if (uri == null)
- return null;
- return secure(getPossiblyInsecureBaseUri(), uri).toString();
- }
-
- private Map<String, TavernaRun> runs() {
- return runStore.listRuns(support.getPrincipal(), policy);
- }
-}
-
-/**
- * RESTful interface to the policies of a Taverna Server installation.
- *
- * @author Donal Fellows
- */
-class PolicyREST implements PolicyView, SupportAware {
- private TavernaServerSupport support;
- private Policy policy;
- private ListenerFactory listenerFactory;
- private NotificationEngine notificationEngine;
-
- @Override
- public void setSupport(TavernaServerSupport support) {
- this.support = support;
- }
-
- @Required
- public void setPolicy(Policy policy) {
- this.policy = policy;
- }
-
- @Required
- public void setListenerFactory(ListenerFactory listenerFactory) {
- this.listenerFactory = listenerFactory;
- }
-
- @Required
- public void setNotificationEngine(NotificationEngine notificationEngine) {
- this.notificationEngine = notificationEngine;
- }
-
- @Override
- @CallCounted
- @PerfLogged
- public PolicyDescription getDescription(UriInfo ui) {
- return new PolicyDescription(ui);
- }
-
- @Override
- @CallCounted
- @PerfLogged
- public int getMaxSimultaneousRuns() {
- Integer limit = policy.getMaxRuns(support.getPrincipal());
- if (limit == null)
- return policy.getMaxRuns();
- return min(limit.intValue(), policy.getMaxRuns());
- }
-
- @Override
- @CallCounted
- @PerfLogged
- public PermittedListeners getPermittedListeners() {
- return new PermittedListeners(
- listenerFactory.getSupportedListenerTypes());
- }
-
- @Override
- @CallCounted
- @PerfLogged
- public PermittedWorkflows getPermittedWorkflows() {
- return new PermittedWorkflows(policy.listPermittedWorkflowURIs(support
- .getPrincipal()));
- }
-
- @Override
- @CallCounted
- @PerfLogged
- public EnabledNotificationFabrics getEnabledNotifiers() {
- return new EnabledNotificationFabrics(
- notificationEngine.listAvailableDispatchers());
- }
-
- @Override
- @CallCounted
- @PerfLogged
- public int getMaxOperatingRuns() {
- return policy.getOperatingLimit();
- }
-
- @Override
- @CallCounted
- @PerfLogged
- public CapabilityList getCapabilities() {
- CapabilityList cl = new CapabilityList();
- cl.capability.addAll(support.getCapabilities());
- return cl;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/server-webapp/src/main/java/org/taverna/server/master/TavernaServerSupport.java
----------------------------------------------------------------------
diff --git a/server-webapp/src/main/java/org/taverna/server/master/TavernaServerSupport.java b/server-webapp/src/main/java/org/taverna/server/master/TavernaServerSupport.java
deleted file mode 100644
index ce36bd3..0000000
--- a/server-webapp/src/main/java/org/taverna/server/master/TavernaServerSupport.java
+++ /dev/null
@@ -1,957 +0,0 @@
-/*
- * Copyright (C) 2010-2011 The University of Manchester
- *
- * See the file "LICENSE" for license terms.
- */
-package org.taverna.server.master;
-
-import static eu.medsea.util.MimeUtil.UNKNOWN_MIME_TYPE;
-import static eu.medsea.util.MimeUtil.getExtensionMimeTypes;
-import static eu.medsea.util.MimeUtil.getMimeType;
-import static java.lang.Math.min;
-import static org.apache.commons.logging.LogFactory.getLog;
-import static org.springframework.jmx.support.MetricType.COUNTER;
-import static org.springframework.jmx.support.MetricType.GAUGE;
-import static org.taverna.server.master.TavernaServer.JMX_ROOT;
-import static org.taverna.server.master.common.Roles.ADMIN;
-import static org.taverna.server.master.rest.handler.T2FlowDocumentHandler.T2FLOW;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URLConnection;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.activation.DataHandler;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.annotation.PreDestroy;
-import javax.ws.rs.WebApplicationException;
-import javax.xml.bind.JAXBException;
-
-import org.apache.commons.logging.Log;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Required;
-import org.springframework.jmx.export.annotation.ManagedAttribute;
-import org.springframework.jmx.export.annotation.ManagedMetric;
-import org.springframework.jmx.export.annotation.ManagedResource;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.taverna.server.master.api.ManagementModel;
-import org.taverna.server.master.api.TavernaServerBean;
-import org.taverna.server.master.common.Capability;
-import org.taverna.server.master.common.Permission;
-import org.taverna.server.master.common.ProfileList;
-import org.taverna.server.master.common.VersionedElement;
-import org.taverna.server.master.common.Workflow;
-import org.taverna.server.master.common.version.Version;
-import org.taverna.server.master.exceptions.FilesystemAccessException;
-import org.taverna.server.master.exceptions.NoCreateException;
-import org.taverna.server.master.exceptions.NoDestroyException;
-import org.taverna.server.master.exceptions.NoDirectoryEntryException;
-import org.taverna.server.master.exceptions.NoListenerException;
-import org.taverna.server.master.exceptions.NoUpdateException;
-import org.taverna.server.master.exceptions.UnknownRunException;
-import org.taverna.server.master.factories.ListenerFactory;
-import org.taverna.server.master.factories.RunFactory;
-import org.taverna.server.master.identity.WorkflowInternalAuthProvider.WorkflowSelfAuthority;
-import org.taverna.server.master.interfaces.File;
-import org.taverna.server.master.interfaces.Input;
-import org.taverna.server.master.interfaces.Listener;
-import org.taverna.server.master.interfaces.LocalIdentityMapper;
-import org.taverna.server.master.interfaces.Policy;
-import org.taverna.server.master.interfaces.RunStore;
-import org.taverna.server.master.interfaces.TavernaRun;
-import org.taverna.server.master.interfaces.TavernaSecurityContext;
-import org.taverna.server.master.rest.handler.T2FlowDocumentHandler;
-import org.taverna.server.master.utils.CapabilityLister;
-import org.taverna.server.master.utils.FilenameUtils;
-import org.taverna.server.master.utils.InvocationCounter;
-import org.taverna.server.master.utils.UsernamePrincipal;
-
-import uk.org.taverna.scufl2.api.profiles.Profile;
-
-/**
- * Web application support utilities.
- *
- * @author Donal Fellows
- */
-@ManagedResource(objectName = JMX_ROOT + "Webapp", description = "The main Taverna Server "
- + Version.JAVA + " web-application interface.")
-public class TavernaServerSupport {
- /** The main webapp log. */
- private Log log = getLog("Taverna.Server.Webapp");
- private Log accessLog = getLog("Taverna.Server.Webapp.Access");;
- /** Bean used to log counts of external calls. */
- private InvocationCounter counter;
- /** A storage facility for workflow runs. */
- private RunStore runStore;
- /** Encapsulates the policies applied by this server. */
- private Policy policy;
- /** Connection to the persistent state of this service. */
- private ManagementModel stateModel;
- /** A factory for event listeners to attach to workflow runs. */
- private ListenerFactory listenerFactory;
- /** A factory for workflow runs. */
- private RunFactory runFactory;
- /** How to map the user ID to who to run as. */
- private LocalIdentityMapper idMapper;
- /** The code that is coupled to CXF. */
- private TavernaServerBean webapp;
- /** How to handle files. */
- private FilenameUtils fileUtils;
- /** How to get the server capabilities. */
- private CapabilityLister capabilitySource;
- /**
- * Whether to log failures during principal retrieval. Should be normally on
- * as it indicates a serious problem, but can be switched off for testing.
- */
- private boolean logGetPrincipalFailures = true;
- private Map<String, String> contentTypeMap;
- /** Number of bytes to read when guessing the MIME type. */
- private static final int SAMPLE_SIZE = 1024;
- /** Number of bytes to ask for when copying a stream to a file. */
- private static final int TRANSFER_SIZE = 32768;
-
- @PreDestroy
- void closeLog() {
- log = null;
- }
-
- /**
- * @return Count of the number of external calls into this webapp.
- */
- @ManagedMetric(description = "Count of the number of external calls into this webapp.", metricType = COUNTER, category = "throughput")
- public int getInvocationCount() {
- return counter.getCount();
- }
-
- /**
- * @return Current number of runs.
- */
- @ManagedMetric(description = "Current number of runs.", metricType = GAUGE, category = "utilization")
- public int getCurrentRunCount() {
- return runStore.listRuns(null, policy).size();
- }
-
- /**
- * @return Whether to write submitted workflows to the log.
- */
- @ManagedAttribute(description = "Whether to write submitted workflows to the log.")
- public boolean getLogIncomingWorkflows() {
- return stateModel.getLogIncomingWorkflows();
- }
-
- /**
- * @param logIncomingWorkflows
- * Whether to write submitted workflows to the log.
- */
- @ManagedAttribute(description = "Whether to write submitted workflows to the log.")
- public void setLogIncomingWorkflows(boolean logIncomingWorkflows) {
- stateModel.setLogIncomingWorkflows(logIncomingWorkflows);
- }
-
- /**
- * @return Whether outgoing exceptions should be logged before being
- * converted to responses.
- */
- @ManagedAttribute(description = "Whether outgoing exceptions should be logged before being converted to responses.")
- public boolean getLogOutgoingExceptions() {
- return stateModel.getLogOutgoingExceptions();
- }
-
- /**
- * @param logOutgoing
- * Whether outgoing exceptions should be logged before being
- * converted to responses.
- */
- @ManagedAttribute(description = "Whether outgoing exceptions should be logged before being converted to responses.")
- public void setLogOutgoingExceptions(boolean logOutgoing) {
- stateModel.setLogOutgoingExceptions(logOutgoing);
- }
-
- /**
- * @return Whether to permit any new workflow runs to be created.
- */
- @ManagedAttribute(description = "Whether to permit any new workflow runs to be created; has no effect on existing runs.")
- public boolean getAllowNewWorkflowRuns() {
- return stateModel.getAllowNewWorkflowRuns();
- }
-
- /**
- * @param allowNewWorkflowRuns
- * Whether to permit any new workflow runs to be created.
- */
- @ManagedAttribute(description = "Whether to permit any new workflow runs to be created; has no effect on existing runs.")
- public void setAllowNewWorkflowRuns(boolean allowNewWorkflowRuns) {
- stateModel.setAllowNewWorkflowRuns(allowNewWorkflowRuns);
- }
-
- /**
- * @return The server's version identifier.
- */
- @ManagedAttribute(description = "The installed version of the server.")
- public String getServerVersion() {
- return VersionedElement.VERSION + " " + VersionedElement.REVISION + " "
- + VersionedElement.TIMESTAMP;
- }
-
- @ManagedAttribute(description = "The URIs of the workfows that this server will allow to be instantiated.")
- public URI[] getPermittedWorkflowURIs() {
- List<URI> pw = policy.listPermittedWorkflowURIs(null);
- if (pw == null)
- return new URI[0];
- return pw.toArray(new URI[pw.size()]);
- }
-
- @ManagedAttribute(description = "The URIs of the workfows that this server will allow to be instantiated.")
- public void setPermittedWorkflowURIs(URI[] pw) {
- if (pw == null)
- policy.setPermittedWorkflowURIs(null, new ArrayList<URI>());
- else
- policy.setPermittedWorkflowURIs(null, Arrays.asList(pw));
- }
-
- public int getMaxSimultaneousRuns() {
- Integer limit = policy.getMaxRuns(getPrincipal());
- if (limit == null)
- return policy.getMaxRuns();
- return min(limit.intValue(), policy.getMaxRuns());
- }
-
- @Autowired
- private T2FlowDocumentHandler t2flowHandler;
-
- public Workflow getWorkflowDocumentFromURI(URI uri)
- throws WebApplicationException, IOException {
- URLConnection conn = uri.toURL().openConnection();
- conn.setRequestProperty("Accept", T2FLOW);
- conn.connect();
- // Tricky point: we know the reader part of the handler only cares
- // about the stream argument.
- return t2flowHandler.readFrom(null, null, null, null, null,
- conn.getInputStream());
- }
-
- public List<String> getListenerTypes() {
- return listenerFactory.getSupportedListenerTypes();
- }
-
- /**
- * @param policy
- * The policy being installed by Spring.
- */
- @Required
- public void setPolicy(Policy policy) {
- this.policy = policy;
- }
-
- /**
- * @param listenerFactory
- * The listener factory being installed by Spring.
- */
- @Required
- public void setListenerFactory(ListenerFactory listenerFactory) {
- this.listenerFactory = listenerFactory;
- }
-
- /**
- * @param runFactory
- * The run factory being installed by Spring.
- */
- @Required
- public void setRunFactory(RunFactory runFactory) {
- this.runFactory = runFactory;
- }
-
- /**
- * @param runStore
- * The run store being installed by Spring.
- */
- @Required
- public void setRunStore(RunStore runStore) {
- this.runStore = runStore;
- }
-
- /**
- * @param stateModel
- * The state model engine being installed by Spring.
- */
- @Required
- public void setStateModel(ManagementModel stateModel) {
- this.stateModel = stateModel;
- }
-
- /**
- * @param mapper
- * The identity mapper being installed by Spring.
- */
- @Required
- public void setIdMapper(LocalIdentityMapper mapper) {
- this.idMapper = mapper;
- }
-
- /**
- * @param counter
- * The object whose job it is to manage the counting of
- * invocations. Installed by Spring.
- */
- @Required
- public void setInvocationCounter(InvocationCounter counter) {
- this.counter = counter;
- }
-
- /**
- * @param webapp
- * The web-app being installed by Spring.
- */
- @Required
- public void setWebapp(TavernaServerBean webapp) {
- this.webapp = webapp;
- }
-
- /**
- * @param fileUtils
- * The file handling utilities.
- */
- @Required
- public void setFileUtils(FilenameUtils fileUtils) {
- this.fileUtils = fileUtils;
- }
-
- /**
- * @param logthem
- * Whether to log failures relating to principals.
- */
- public void setLogGetPrincipalFailures(boolean logthem) {
- logGetPrincipalFailures = logthem;
- }
-
- public Map<String, String> getContentTypeMap() {
- return contentTypeMap;
- }
-
- /**
- * Mapping from filename suffixes (e.g., "baclava") to content types.
- *
- * @param contentTypeMap
- * The mapping to install.
- */
- @Required
- public void setContentTypeMap(Map<String, String> contentTypeMap) {
- this.contentTypeMap = contentTypeMap;
- }
-
- @Required
- public void setCapabilitySource(CapabilityLister capabilitySource) {
- this.capabilitySource = capabilitySource;
- }
-
- /**
- * Test whether the current user can do updates to the given run.
- *
- * @param run
- * The workflow run to do the test on.
- * @throws NoUpdateException
- * If the current user is not permitted to update the run.
- */
- public void permitUpdate(@Nonnull TavernaRun run) throws NoUpdateException {
- if (isSuperUser()) {
- accessLog
- .warn("check for admin powers passed; elevated access rights granted for update");
- return; // Superusers are fully authorized to access others things
- }
- if (getSelfAuthority() != null) {
- // At this point, must already be accessing self as that is checked
- // in getRun().
- return;
- }
- policy.permitUpdate(getPrincipal(), run);
- }
-
- /**
- * Test whether the current user can destroy or control the lifespan of the
- * given run.
- *
- * @param run
- * The workflow run to do the test on.
- * @throws NoDestroyException
- * If the current user is not permitted to destroy the run.
- */
- public void permitDestroy(TavernaRun run) throws NoDestroyException {
- if (isSuperUser()) {
- accessLog
- .warn("check for admin powers passed; elevated access rights granted for destroy");
- return; // Superusers are fully authorized to access others things
- }
- if (getSelfAuthority() != null)
- throw new NoDestroyException();
- policy.permitDestroy(getPrincipal(), run);
- }
-
- /**
- * Gets the identity of the user currently accessing the webapp, which is
- * stored in a thread-safe way in the webapp's container's context.
- *
- * @return The identity of the user accessing the webapp.
- */
- @Nonnull
- public UsernamePrincipal getPrincipal() {
- try {
- Authentication auth = SecurityContextHolder.getContext()
- .getAuthentication();
- if (auth == null || !auth.isAuthenticated()) {
- if (logGetPrincipalFailures)
- log.warn("failed to get auth; going with <NOBODY>");
- return new UsernamePrincipal("<NOBODY>");
- }
- return new UsernamePrincipal(auth);
- } catch (RuntimeException e) {
- if (logGetPrincipalFailures)
- log.info("failed to map principal", e);
- throw e;
- }
- }
-
- private WorkflowSelfAuthority getSelfAuthority() {
- try {
- Authentication a = SecurityContextHolder.getContext()
- .getAuthentication();
- for (GrantedAuthority ga : a.getAuthorities())
- if (ga instanceof WorkflowSelfAuthority)
- return (WorkflowSelfAuthority) ga;
- } catch (RuntimeException e) {
- }
- return null;
- }
-
- /**
- * Obtain the workflow run with a particular name.
- *
- * @param name
- * The name of the run to look up.
- * @return A workflow run handle that the current user has at least
- * permission to read.
- * @throws UnknownRunException
- * If the workflow run doesn't exist or the current user doesn't
- * have permission to see it.
- */
- @Nonnull
- public TavernaRun getRun(@Nonnull String name) throws UnknownRunException {
- if (isSuperUser()) {
- accessLog
- .info("check for admin powers passed; elevated access rights granted for read");
- return runStore.getRun(name);
- }
- WorkflowSelfAuthority wsa = getSelfAuthority();
- if (wsa != null) {
- if (wsa.getWorkflowID().equals(name))
- return runStore.getRun(name);
- throw new UnknownRunException();
- }
- return runStore.getRun(getPrincipal(), policy, name);
- }
-
- /**
- * Construct a listener attached to the given run.
- *
- * @param run
- * The workflow run to attach the listener to.
- * @param type
- * The name of the type of run to create.
- * @param configuration
- * The configuration description to pass into the listener. The
- * format of this string is up to the listener to define.
- * @return A handle to the listener which can be used to further configure
- * any properties.
- * @throws NoListenerException
- * If the listener type is unrecognized or the configuration is
- * invalid.
- * @throws NoUpdateException
- * If the run does not permit the current user to add listeners
- * (or perform other types of update).
- */
- @Nonnull
- public Listener makeListener(@Nonnull TavernaRun run, @Nonnull String type,
- @Nonnull String configuration) throws NoListenerException,
- NoUpdateException {
- permitUpdate(run);
- return listenerFactory.makeListener(run, type, configuration);
- }
-
- /**
- * Obtain a listener that is already attached to a workflow run.
- *
- * @param run
- * The workflow run to search.
- * @param listenerName
- * The name of the listener to look up.
- * @return The listener instance interface.
- * @throws NoListenerException
- * If no listener with that name exists.
- */
- @Nonnull
- public Listener getListener(TavernaRun run, String listenerName)
- throws NoListenerException {
- for (Listener l : run.getListeners())
- if (l.getName().equals(listenerName))
- return l;
- throw new NoListenerException();
- }
-
- /**
- * Obtain a property from a listener that is already attached to a workflow
- * run.
- *
- * @param runName
- * The ID of the workflow run to search.
- * @param listenerName
- * The name of the listener to look up in.
- * @param propertyName
- * The name of the property to fetch.
- * @return The property value.
- * @throws NoListenerException
- * If no listener with that name exists, or no property with
- * that name exists.
- * @throws UnknownRunException
- * If no run with that name exists.
- */
- @Nonnull
- public String getProperty(String runName, String listenerName,
- String propertyName) throws NoListenerException,
- UnknownRunException {
- return getListener(runName, listenerName).getProperty(propertyName);
- }
-
- /**
- * Obtain a property from a listener that is already attached to a workflow
- * run.
- *
- * @param run
- * The workflow run to search.
- * @param listenerName
- * The name of the listener to look up in.
- * @param propertyName
- * The name of the property to fetch.
- * @return The property value.
- * @throws NoListenerException
- * If no listener with that name exists, or no property with
- * that name exists.
- */
- @Nonnull
- public String getProperty(TavernaRun run, String listenerName,
- String propertyName) throws NoListenerException {
- return getListener(run, listenerName).getProperty(propertyName);
- }
-
- /**
- * Get the permission description for the given user.
- *
- * @param context
- * A security context associated with a particular workflow run.
- * Note that only the owner of a workflow run may get the
- * security context in the first place.
- * @param userName
- * The name of the user to look up the permission for.
- * @return A permission description.
- */
- @Nonnull
- public Permission getPermission(@Nonnull TavernaSecurityContext context,
- @Nonnull String userName) {
- if (context.getPermittedDestroyers().contains(userName))
- return Permission.Destroy;
- if (context.getPermittedUpdaters().contains(userName))
- return Permission.Update;
- if (context.getPermittedReaders().contains(userName))
- return Permission.Read;
- return Permission.None;
- }
-
- /**
- * Set the permissions for the given user.
- *
- * @param context
- * A security context associated with a particular workflow run.
- * Note that only the owner of a workflow run may get the
- * security context in the first place.
- * @param userName
- * The name of the user to set the permission for.
- * @param permission
- * The description of the permission to grant. Note that the
- * owner of a workflow run always has the equivalent of
- * {@link Permission#Destroy}; this is always enforced before
- * checking for other permissions.
- */
- public void setPermission(TavernaSecurityContext context, String userName,
- Permission permission) {
- Set<String> permSet;
- boolean doRead = false, doWrite = false, doKill = false;
-
- switch (permission) {
- case Destroy:
- doKill = true;
- case Update:
- doWrite = true;
- case Read:
- doRead = true;
- default:
- break;
- }
-
- permSet = context.getPermittedReaders();
- if (doRead) {
- if (!permSet.contains(userName)) {
- permSet = new HashSet<>(permSet);
- permSet.add(userName);
- context.setPermittedReaders(permSet);
- }
- } else if (permSet.contains(userName)) {
- permSet = new HashSet<>(permSet);
- permSet.remove(userName);
- context.setPermittedReaders(permSet);
- }
-
- permSet = context.getPermittedUpdaters();
- if (doWrite) {
- if (!permSet.contains(userName)) {
- permSet = new HashSet<>(permSet);
- permSet.add(userName);
- context.setPermittedUpdaters(permSet);
- }
- } else if (permSet.contains(userName)) {
- permSet = new HashSet<>(permSet);
- permSet.remove(userName);
- context.setPermittedUpdaters(permSet);
- }
-
- permSet = context.getPermittedDestroyers();
- if (doKill) {
- if (!permSet.contains(userName)) {
- permSet = new HashSet<>(permSet);
- permSet.add(userName);
- context.setPermittedDestroyers(permSet);
- }
- } else if (permSet.contains(userName)) {
- permSet = new HashSet<>(permSet);
- permSet.remove(userName);
- context.setPermittedDestroyers(permSet);
- }
- }
-
- public Map<String, Permission> getPermissionMap(
- TavernaSecurityContext context) {
- Map<String, Permission> perm = new HashMap<>();
- for (String u : context.getPermittedReaders())
- perm.put(u, Permission.Read);
- for (String u : context.getPermittedUpdaters())
- perm.put(u, Permission.Update);
- for (String u : context.getPermittedDestroyers())
- perm.put(u, Permission.Destroy);
- return perm;
- }
-
- /**
- * Stops a run from being possible to be looked up and destroys it.
- *
- * @param runName
- * The name of the run.
- * @param run
- * The workflow run. <i>Must</i> correspond to the name.
- * @throws NoDestroyException
- * If the user is not permitted to destroy the workflow run.
- * @throws UnknownRunException
- * If the run is unknown (e.g., because it is already
- * destroyed).
- */
- public void unregisterRun(@Nonnull String runName, @Nonnull TavernaRun run)
- throws NoDestroyException, UnknownRunException {
- if (run == null)
- run = getRun(runName);
- permitDestroy(run);
- runStore.unregisterRun(runName);
- run.destroy();
- }
-
- /**
- * Changes the expiry date of a workflow run. The expiry date is when the
- * workflow run becomes eligible for automated destruction.
- *
- * @param run
- * The handle to the workflow run.
- * @param date
- * When the workflow run should be expired.
- * @return When the workflow run will actually be expired.
- * @throws NoDestroyException
- * If the user is not permitted to destroy the workflow run.
- * (Note that lifespan management requires the ability to
- * destroy.)
- */
- @Nonnull
- public Date updateExpiry(@Nonnull TavernaRun run, @Nonnull Date date)
- throws NoDestroyException {
- permitDestroy(run);
- run.setExpiry(date);
- return run.getExpiry();
- }
-
- /**
- * Manufacture a workflow run instance.
- *
- * @param workflow
- * The workflow document (t2flow, scufl2?) to instantiate.
- * @return The ID of the created workflow run.
- * @throws NoCreateException
- * If the user is not permitted to create workflows.
- */
- public String buildWorkflow(Workflow workflow) throws NoCreateException {
- UsernamePrincipal p = getPrincipal();
- if (getSelfAuthority() != null)
- throw new NoCreateException(
- "runs may not create workflows on their host server");
- if (!stateModel.getAllowNewWorkflowRuns())
- throw new NoCreateException("run creation not currently enabled");
- try {
- if (stateModel.getLogIncomingWorkflows()) {
- log.info(workflow.marshal());
- }
- } catch (JAXBException e) {
- log.warn("problem when logging workflow", e);
- }
-
- // Security checks
- policy.permitCreate(p, workflow);
- if (idMapper != null && idMapper.getUsernameForPrincipal(p) == null) {
- log.error("cannot map principal to local user id");
- throw new NoCreateException(
- "failed to map security token to local user id");
- }
-
- TavernaRun run;
- try {
- run = runFactory.create(p, workflow);
- TavernaSecurityContext c = run.getSecurityContext();
- c.initializeSecurityFromContext(SecurityContextHolder.getContext());
- /*
- * These next pieces of security initialisation are (hopefully)
- * obsolete now that we use Spring Security, but we keep them Just
- * In Case.
- */
- boolean doRESTinit = webapp.initObsoleteSOAPSecurity(c);
- if (doRESTinit)
- webapp.initObsoleteRESTSecurity(c);
- } catch (Exception e) {
- log.error("failed to build workflow run worker", e);
- throw new NoCreateException("failed to build workflow run worker");
- }
-
- return runStore.registerRun(run);
- }
-
- private boolean isSuperUser() {
- try {
- Authentication auth = SecurityContextHolder.getContext()
- .getAuthentication();
- if (auth == null || !auth.isAuthenticated())
- return false;
- UserDetails details = (UserDetails) auth.getPrincipal();
- if (log.isDebugEnabled())
- log.debug("checking for admin role for user <" + auth.getName()
- + "> in collection " + details.getAuthorities());
- return details.getAuthorities().contains(ADMIN);
- } catch (ClassCastException e) {
- return false;
- }
- }
-
- /**
- * Get a particular input to a workflow run.
- *
- * @param run
- * The workflow run to search.
- * @param portName
- * The name of the input.
- * @return The handle of the input, or <tt>null</tt> if no such handle
- * exists.
- */
- @Nullable
- public Input getInput(TavernaRun run, String portName) {
- for (Input i : run.getInputs())
- if (i.getName().equals(portName))
- return i;
- return null;
- }
-
- /**
- * Get a listener attached to a run.
- *
- * @param runName
- * The name of the run to look up
- * @param listenerName
- * The name of the listener.
- * @return The handle of the listener.
- * @throws NoListenerException
- * If no such listener exists.
- * @throws UnknownRunException
- * If no such workflow run exists, or if the user does not have
- * permission to access it.
- */
- public Listener getListener(String runName, String listenerName)
- throws NoListenerException, UnknownRunException {
- return getListener(getRun(runName), listenerName);
- }
-
- /**
- * Given a file, produce a guess at its content type. This uses the content
- * type map property, and if that search fails it falls back on the Medsea
- * mime type library.
- *
- * @param f
- * The file handle.
- * @return The content type. If all else fails, produces good old
- * "application/octet-stream".
- */
- @Nonnull
- public String getEstimatedContentType(@Nonnull File f) {
- String name = f.getName();
- for (int idx = name.indexOf('.'); idx != -1; idx = name.indexOf('.',
- idx + 1)) {
- String mt = contentTypeMap.get(name.substring(idx + 1));
- if (mt != null)
- return mt;
- }
- @Nonnull
- String type = getExtensionMimeTypes(name);
- if (!type.equals(UNKNOWN_MIME_TYPE))
- return type;
- try {
- return getMimeType(new ByteArrayInputStream(f.getContents(0,
- SAMPLE_SIZE)));
- } catch (FilesystemAccessException e) {
- return type;
- }
- }
-
- public void copyDataToFile(DataHandler handler, File file)
- throws FilesystemAccessException {
- try {
- copyStreamToFile(handler.getInputStream(), file);
- } catch (IOException e) {
- throw new FilesystemAccessException(
- "problem constructing stream from data source", e);
- }
- }
-
- public void copyDataToFile(URI uri, File file)
- throws MalformedURLException, FilesystemAccessException,
- IOException {
- copyStreamToFile(uri.toURL().openStream(), file);
- }
-
- public void copyStreamToFile(InputStream stream, File file)
- throws FilesystemAccessException {
- String name = file.getFullName();
- long total = 0;
- try {
- byte[] buffer = new byte[TRANSFER_SIZE];
- boolean first = true;
- while (true) {
- int len = stream.read(buffer);
- if (len < 0)
- break;
- total += len;
- if (log.isDebugEnabled())
- log.debug("read " + len
- + " bytes from source stream (total: " + total
- + ") bound for " + name);
- if (len == buffer.length) {
- if (first)
- file.setContents(buffer);
- else
- file.appendContents(buffer);
- } else {
- byte[] newBuf = new byte[len];
- System.arraycopy(buffer, 0, newBuf, 0, len);
- if (first)
- file.setContents(newBuf);
- else
- file.appendContents(newBuf);
- }
- first = false;
- }
- } catch (IOException exn) {
- throw new FilesystemAccessException("failed to transfer bytes", exn);
- }
- }
-
- /**
- * Build a description of the profiles supported by a workflow. Note that we
- * expect the set of profiles to be fairly small.
- *
- * @param workflow
- * The workflow to describe the profiles of.
- * @return The descriptor (which might be empty).
- */
- public ProfileList getProfileDescriptor(Workflow workflow) {
- ProfileList result = new ProfileList();
- String main = workflow.getMainProfileName();
- for (Profile p : workflow.getProfiles()) {
- ProfileList.Info i = new ProfileList.Info();
- i.name = p.getName();
- if (main != null && main.equals(i.name))
- i.main = true;
- result.profile.add(i);
- }
- return result;
- }
-
- public boolean getAllowStartWorkflowRuns() {
- return runFactory.isAllowingRunsToStart();
- }
-
- /**
- * The list of filenames that logs may occupy.
- */
- private static final String[] LOGS = { "logs/detail.log.4",
- "logs/detail.log.3", "logs/detail.log.2", "logs/detail.log.1",
- "logs/detail.log" };
-
- public FileConcatenation getLogs(TavernaRun run) {
- FileConcatenation fc = new FileConcatenation();
- for (String name : LOGS) {
- try {
- fc.add(fileUtils.getFile(run, name));
- } catch (FilesystemAccessException | NoDirectoryEntryException e) {
- // Ignore
- }
- }
- return fc;
- }
-
- @Nonnull
- public List<Capability> getCapabilities() {
- return capabilitySource.getCapabilities();
- }
-
- static final String PROV_BUNDLE = "out.bundle.zip";
-
- public FileConcatenation getProv(TavernaRun run) {
- FileConcatenation fc = new FileConcatenation();
- try {
- fc.add(fileUtils.getFile(run, PROV_BUNDLE));
- } catch (FilesystemAccessException | NoDirectoryEntryException e) {
- // Ignore
- }
- return fc;
- }
-}