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 11:20:32 UTC
[25/26] incubator-taverna-server git commit: Revert "temporarily
empty repository"
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/0b04b1ab/server-client/pom.xml
----------------------------------------------------------------------
diff --git a/server-client/pom.xml b/server-client/pom.xml
new file mode 100644
index 0000000..e62978a
--- /dev/null
+++ b/server-client/pom.xml
@@ -0,0 +1,123 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>uk.org.taverna.server</groupId>
+ <artifactId>server</artifactId>
+ <version>3.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>server-client</artifactId>
+ <packaging>bundle</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.jvnet.ws.wadl</groupId>
+ <artifactId>wadl-core</artifactId>
+ <version>1.1.6</version>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.jersey</groupId>
+ <artifactId>jersey-client</artifactId>
+ <version>1.8</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tika</groupId>
+ <artifactId>tika-core</artifactId>
+ <version>1.5</version>
+ </dependency>
+ <dependency>
+ <groupId>uk.org.taverna.server</groupId>
+ <artifactId>server-usagerecord</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Export-Package>uk.org.taverna.server.client</Export-Package>
+ <Private-Package>uk.org.taverna.server.client.*</Private-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.7</source>
+ <target>1.7</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.jvnet.ws.wadl</groupId>
+ <artifactId>wadl-client-plugin</artifactId>
+ <version>1.1.6</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>generate</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <packageName>org.taverna.server.client.wadl</packageName>
+ <includes>*.wadl</includes>
+ <customClassNames>
+ <property>
+ <name>http://example.com/taverna/rest</name>
+ <value>TavernaServer</value>
+ </property>
+ </customClassNames>
+ </configuration>
+ </plugin>
+ </plugins>
+ <pluginManagement>
+ <plugins>
+ <!--This plugin's configuration is used to store Eclipse m2e settings
+ only. It has no influence on the Maven build itself. -->
+ <plugin>
+ <groupId>org.eclipse.m2e</groupId>
+ <artifactId>lifecycle-mapping</artifactId>
+ <version>1.0.0</version>
+ <configuration>
+ <lifecycleMappingMetadata>
+ <pluginExecutions>
+ <pluginExecution>
+ <pluginExecutionFilter>
+ <groupId>
+ org.jvnet.ws.wadl
+ </groupId>
+ <artifactId>
+ wadl-client-plugin
+ </artifactId>
+ <versionRange>
+ [1.1.6,)
+ </versionRange>
+ <goals>
+ <goal>generate</goal>
+ </goals>
+ </pluginExecutionFilter>
+ <action>
+ <execute />
+ </action>
+ </pluginExecution>
+ </pluginExecutions>
+ </lifecycleMappingMetadata>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+ <inceptionYear>2014</inceptionYear>
+ <name>Server Client OSGi Module</name>
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/0b04b1ab/server-client/src/main/java/uk/org/taverna/server/client/Connected.java
----------------------------------------------------------------------
diff --git a/server-client/src/main/java/uk/org/taverna/server/client/Connected.java b/server-client/src/main/java/uk/org/taverna/server/client/Connected.java
new file mode 100644
index 0000000..263034c
--- /dev/null
+++ b/server-client/src/main/java/uk/org/taverna/server/client/Connected.java
@@ -0,0 +1,20 @@
+package uk.org.taverna.server.client;
+
+import uk.org.taverna.server.client.TavernaServer.ClientException;
+import uk.org.taverna.server.client.TavernaServer.ServerException;
+
+import com.sun.jersey.api.client.ClientResponse;
+
+abstract class Connected {
+ void checkError(ClientResponse response) throws ClientException,
+ ServerException {
+ ClientResponse.Status s = response.getClientResponseStatus();
+ if (s.getStatusCode() == 401)
+ throw new TavernaServer.AuthorizationException("not authorized",
+ null);
+ if (s.getStatusCode() >= 500)
+ throw new TavernaServer.ServerException(s.getReasonPhrase(), null);
+ if (s.getStatusCode() >= 400)
+ throw new TavernaServer.ClientException(s.getReasonPhrase(), null);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/0b04b1ab/server-client/src/main/java/uk/org/taverna/server/client/DirEntry.java
----------------------------------------------------------------------
diff --git a/server-client/src/main/java/uk/org/taverna/server/client/DirEntry.java b/server-client/src/main/java/uk/org/taverna/server/client/DirEntry.java
new file mode 100644
index 0000000..267707d
--- /dev/null
+++ b/server-client/src/main/java/uk/org/taverna/server/client/DirEntry.java
@@ -0,0 +1,39 @@
+package uk.org.taverna.server.client;
+
+import org.taverna.server.client.wadl.TavernaServer.Root.RunsRunName.Wd.Path2;
+
+import uk.org.taverna.server.client.TavernaServer.ClientException;
+import uk.org.taverna.server.client.TavernaServer.ServerException;
+
+import com.sun.jersey.api.client.ClientResponse;
+
+public abstract class DirEntry extends Connected {
+ final Path2 handle;
+ final String path;
+ final Run run;
+
+ protected DirEntry(Run run, String path) {
+ this.run = run;
+ this.path = path.replaceFirst("/+$", "");
+ this.handle = run.run.wd().path2(this.path);
+ }
+
+ public void delete() throws ClientException, ServerException {
+ checkError(handle.deleteAsXml(ClientResponse.class));
+ }
+
+ String path(ClientResponse response) throws ClientException, ServerException {
+ checkError(response);
+ String[] bits = response.getLocation().getPath().split("/");
+ return concat(bits[bits.length - 1]);
+ }
+
+ String localName() {
+ String[] bits = path.split("/");
+ return bits[bits.length - 1];
+ }
+
+ String concat(String name) {
+ return path + "/" + name.split("/", 2)[0];
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/0b04b1ab/server-client/src/main/java/uk/org/taverna/server/client/Directory.java
----------------------------------------------------------------------
diff --git a/server-client/src/main/java/uk/org/taverna/server/client/Directory.java b/server-client/src/main/java/uk/org/taverna/server/client/Directory.java
new file mode 100644
index 0000000..38dc394
--- /dev/null
+++ b/server-client/src/main/java/uk/org/taverna/server/client/Directory.java
@@ -0,0 +1,94 @@
+package uk.org.taverna.server.client;
+
+import static java.io.File.createTempFile;
+import static javax.ws.rs.client.Entity.entity;
+import static javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM_TYPE;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.zip.ZipFile;
+
+import org.taverna.server.client.wadl.TavernaServer.Root.RunsRunName.Wd;
+
+import uk.org.taverna.server.client.TavernaServer.ClientException;
+import uk.org.taverna.server.client.TavernaServer.ServerException;
+import uk.org.taverna.server.client.generic.DirectoryEntry;
+import uk.org.taverna.server.client.generic.DirectoryReference;
+import uk.org.taverna.server.client.generic.FileReference;
+import uk.org.taverna.server.client.rest.DirectoryContents;
+import uk.org.taverna.server.client.rest.MakeDirectory;
+import uk.org.taverna.server.client.rest.UploadFile;
+
+import com.sun.jersey.api.client.ClientResponse;
+
+public class Directory extends DirEntry {
+ private final Wd wd;
+
+ Directory(Run run) {
+ super(run, "");
+ this.wd = run.run.wd();
+ }
+
+ Directory(Run run, String path) {
+ super(run, path);
+ this.wd = run.run.wd();
+ }
+
+ public List<DirEntry> list() {
+ List<DirEntry> result = new ArrayList<>();
+ for (DirectoryEntry de : wd.path3(path)
+ .getAsXml(DirectoryContents.class).getDirOrFile())
+ if (de instanceof DirectoryReference)
+ result.add(new Directory(run, de.getValue()));
+ else if (de instanceof FileReference)
+ result.add(new File(run, de.getValue()));
+ return result;
+ }
+
+ public File createFile(String name, byte[] content) throws ClientException,
+ ServerException {
+ UploadFile uf = new UploadFile();
+ uf.setName(name);
+ uf.setValue(content);
+ return new File(run, path(wd.path(path).putAsXml(uf,
+ ClientResponse.class)));
+ }
+
+ public File createFile(String name, java.io.File content)
+ throws ClientException, ServerException {
+ return new File(run, path(wd.path(concat(name)).putOctetStreamAsXml(
+ entity(content, APPLICATION_OCTET_STREAM_TYPE),
+ ClientResponse.class)));
+ }
+
+ public File createFile(String name, URI source) throws ClientException,
+ ServerException {
+ return new File(run, path(wd.path(concat(name)).postTextUriListAsXml(
+ source.toString(), ClientResponse.class)));
+ }
+
+ public Directory createDirectory(String name) throws ClientException,
+ ServerException {
+ MakeDirectory mkdir = new MakeDirectory();
+ mkdir.setName(name);
+ return new Directory(run, path(wd.path(path).putAsXml(mkdir,
+ ClientResponse.class)));
+ }
+
+ public byte[] getZippedContents() {
+ return wd.path3(path).getAsZip(byte[].class);
+ }
+
+ public ZipFile getZip() throws IOException {
+ byte[] contents = getZippedContents();
+ java.io.File tmp = createTempFile(localName(), ".zip");
+ try (OutputStream os = new FileOutputStream(tmp)) {
+ os.write(contents);
+ }
+ return new ZipFile(tmp);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/0b04b1ab/server-client/src/main/java/uk/org/taverna/server/client/File.java
----------------------------------------------------------------------
diff --git a/server-client/src/main/java/uk/org/taverna/server/client/File.java b/server-client/src/main/java/uk/org/taverna/server/client/File.java
new file mode 100644
index 0000000..0287afb
--- /dev/null
+++ b/server-client/src/main/java/uk/org/taverna/server/client/File.java
@@ -0,0 +1,95 @@
+package uk.org.taverna.server.client;
+
+import static java.io.File.createTempFile;
+import static javax.ws.rs.client.Entity.entity;
+import static javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM_TYPE;
+import static org.apache.commons.io.IOUtils.copy;
+import static org.apache.tika.mime.MimeTypes.getDefaultMimeTypes;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+
+import org.apache.tika.mime.MimeTypeException;
+import org.taverna.server.client.wadl.TavernaServer.Root.RunsRunName.Wd;
+
+import uk.org.taverna.server.client.TavernaServer.ClientException;
+import uk.org.taverna.server.client.TavernaServer.ServerException;
+
+import com.sun.jersey.api.client.ClientHandlerException;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.UniformInterfaceException;
+
+public class File extends DirEntry {
+ private final Wd wd;
+
+ File(Run run, String path) {
+ super(run, path);
+ wd = run.run.wd();
+ }
+
+ public InputStream getAsStream() {
+ return wd.path3(path).getAsOctetStream(InputStream.class);
+ }
+
+ public byte[] get() {
+ return wd.path3(path).getAsOctetStream(byte[].class);
+ }
+
+ public String get(Charset encoding) {
+ return new String(wd.path3(path).getAsOctetStream(byte[].class),
+ encoding);
+ }
+
+ public java.io.File getAsFile() throws ClientHandlerException,
+ UniformInterfaceException, IOException, MimeTypeException,
+ ClientException, ServerException {
+ ClientResponse cr = wd.path3(path).getAsOctetStream(
+ ClientResponse.class);
+ checkError(cr);
+ String[] bits = localName().split("[.]");
+ String ext = getDefaultMimeTypes().forName(
+ cr.getHeaders().getFirst("Content-Type")).getExtension();
+ if (ext == null)
+ ext = bits[bits.length - 1];
+ java.io.File tmp = createTempFile(bits[0], ext);
+ try (OutputStream os = new FileOutputStream(tmp);
+ InputStream is = cr.getEntity(InputStream.class)) {
+ copy(is, os);
+ }
+ return tmp;
+ }
+
+ public void setContents(byte[] newContents) throws ClientException,
+ ServerException {
+ checkError(wd.path(path).putOctetStreamAsXml(newContents,
+ ClientResponse.class));
+ }
+
+ public void setContents(String newContents) throws ClientException,
+ ServerException {
+ checkError(wd.path(path).putOctetStreamAsXml(newContents,
+ ClientResponse.class));
+ }
+
+ public void setContents(String newContents, Charset encoding)
+ throws ClientException, ServerException {
+ checkError(wd.path(path).putOctetStreamAsXml(
+ newContents.getBytes(encoding), ClientResponse.class));
+ }
+
+ public void setContents(InputStream newContents) throws ClientException,
+ ServerException {
+ checkError(wd.path(path).putOctetStreamAsXml(newContents,
+ ClientResponse.class));
+ }
+
+ public void setContents(java.io.File newContents) throws IOException,
+ ClientException, ServerException {
+ checkError(wd.path(path).putOctetStreamAsXml(
+ entity(newContents, APPLICATION_OCTET_STREAM_TYPE),
+ ClientResponse.class));
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/0b04b1ab/server-client/src/main/java/uk/org/taverna/server/client/Property.java
----------------------------------------------------------------------
diff --git a/server-client/src/main/java/uk/org/taverna/server/client/Property.java b/server-client/src/main/java/uk/org/taverna/server/client/Property.java
new file mode 100644
index 0000000..0e6542f
--- /dev/null
+++ b/server-client/src/main/java/uk/org/taverna/server/client/Property.java
@@ -0,0 +1,18 @@
+package uk.org.taverna.server.client;
+
+public enum Property {
+ STDOUT("stdout"), STDERR("stderr"), EXIT_CODE("exitcode"), READY_TO_NOTIFY(
+ "readyToNotify"), EMAIL("notificationAddress"), USAGE(
+ "usageRecord");
+
+ private String s;
+
+ private Property(String s) {
+ this.s = s;
+ }
+
+ @Override
+ public String toString() {
+ return s;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/0b04b1ab/server-client/src/main/java/uk/org/taverna/server/client/Run.java
----------------------------------------------------------------------
diff --git a/server-client/src/main/java/uk/org/taverna/server/client/Run.java b/server-client/src/main/java/uk/org/taverna/server/client/Run.java
new file mode 100644
index 0000000..5c6875e
--- /dev/null
+++ b/server-client/src/main/java/uk/org/taverna/server/client/Run.java
@@ -0,0 +1,215 @@
+package uk.org.taverna.server.client;
+
+import static org.joda.time.format.ISODateTimeFormat.dateTime;
+import static org.joda.time.format.ISODateTimeFormat.dateTimeParser;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.util.Date;
+import java.util.List;
+
+import javax.xml.bind.JAXBException;
+
+import org.apache.commons.io.IOUtils;
+import org.joda.time.DateTime;
+import org.ogf.usage.JobUsageRecord;
+import org.taverna.server.client.wadl.TavernaServer.Root.RunsRunName;
+import org.w3c.dom.Element;
+
+import uk.org.taverna.server.client.TavernaServer.ClientException;
+import uk.org.taverna.server.client.TavernaServer.ServerException;
+import uk.org.taverna.server.client.generic.KeyPairCredential;
+import uk.org.taverna.server.client.generic.PasswordCredential;
+import uk.org.taverna.server.client.generic.port.InputPort;
+import uk.org.taverna.server.client.generic.port.OutputPort;
+import uk.org.taverna.server.client.rest.InputDescription;
+import uk.org.taverna.server.client.rest.InputDescription.Value;
+
+import com.sun.jersey.api.client.ClientResponse;
+
+public class Run extends Connected {
+ RunsRunName run;
+
+ Run(TavernaServer server, String value) {
+ run = server.root.runsRunName(value);
+ }
+
+ public String getName() {
+ return run.name().getAsTextPlain(ClientResponse.class)
+ .getEntity(String.class);
+ }
+
+ public void setName(String name) {
+ run.name().putTextPlain(name, String.class);
+ }
+
+ public Date getExpiry() {
+ return dateTimeParser().parseDateTime(
+ run.expiry().getAsTextPlain(String.class)).toDate();
+ }
+
+ public void setExpiry(Date expiryTimestamp) {
+ run.expiry().putTextPlain(
+ dateTime().print(new DateTime(expiryTimestamp)), String.class);
+ }
+
+ public Date getCreate() {
+ String timestamp = run.createTime().getAsTextPlain(String.class);
+ if (timestamp == null || timestamp.trim().isEmpty())
+ return null;
+ return dateTimeParser().parseDateTime(timestamp).toDate();
+ }
+
+ public Date getStart() {
+ String timestamp = run.startTime().getAsTextPlain(String.class);
+ if (timestamp == null || timestamp.trim().isEmpty())
+ return null;
+ return dateTimeParser().parseDateTime(timestamp).toDate();
+ }
+
+ public Date getFinish() {
+ String timestamp = run.finishTime().getAsTextPlain(String.class);
+ if (timestamp == null || timestamp.trim().isEmpty())
+ return null;
+ return dateTimeParser().parseDateTime(timestamp).toDate();
+ }
+
+ public Status getStatus() {
+ return Status.valueOf(run.status().getAsTextPlain(String.class));
+ }
+
+ public void setStatus(Status status) {
+ run.status().putTextPlain(status, String.class);
+ }
+
+ public void start() {
+ setStatus(Status.Operating);
+ }
+
+ public void kill() {
+ setStatus(Status.Finished);
+ }
+
+ public boolean isRunning() {
+ return getStatus() == Status.Operating;
+ }
+
+ public String getStandardOutput() {
+ return run.stdout().getAsTextPlain(String.class);
+ }
+
+ public String getStandardError() {
+ return run.stderr().getAsTextPlain(String.class);
+ }
+
+ public String getLog() {
+ return run.log().getAsTextPlain(String.class);
+ }
+
+ public Integer getExitCode() {
+ String code = run.listeners().name("io")
+ .propertiesPropertyName("exitCode")
+ .getAsTextPlain(String.class);
+ if (code == null || code.trim().isEmpty())
+ return null;
+ return Integer.parseInt(code);
+ }
+
+ public String getProperty(Property prop) {
+ return run.listeners().name("io")
+ .propertiesPropertyName(prop.toString())
+ .getAsTextPlain(String.class);
+ }
+
+ public void setGenerateRunBundle(boolean generateRunBundle) {
+ run.generateProvenance().putTextPlain(generateRunBundle, String.class);
+ }
+
+ public byte[] getRunBundle() {
+ return run.runBundle().getAsVndWf4everRobundleZip(byte[].class);
+ }
+
+ public List<InputPort> getInputs() {
+ return run.input().expected().getAsInputDescriptionXml().getInput();
+ }
+
+ public List<OutputPort> getOutputs() {
+ return run.output().getAsOutputDescriptionXml().getOutput();
+ }
+
+ public void setInput(String name, String value) {
+ Value v = new Value();
+ v.setValue(value);
+ InputDescription idesc = new InputDescription();
+ idesc.setValue(v);
+ run.input().inputName(name).putXmlAsInputDescription(idesc);
+ }
+
+ public void setInput(String name, String value, char listSeparator) {
+ Value v = new Value();
+ v.setValue(value);
+ InputDescription idesc = new InputDescription();
+ idesc.setValue(v);
+ idesc.setListDelimiter(new String(new char[] { listSeparator }));
+ run.input().inputName(name).putXmlAsInputDescription(idesc);
+ }
+
+ public byte[] getWorkflow() {
+ return run.workflow().getAsVndTavernaT2flowXml(byte[].class);
+ }
+
+ // TODO Consider better ways to do this
+ public Element getInteractionFeed() {
+ return run.interaction().getAsAtomXml(Element.class);
+ }
+
+ public Element getInteractionEntry(String id) {
+ return run.interaction().id(id).getAsAtomXml(Element.class);
+ }
+
+ public JobUsageRecord getUsageRecord() throws JAXBException {
+ return JobUsageRecord.unmarshal(run.usage().getAsXml(Element.class));
+ }
+
+ public Directory getWorkingDirectory() {
+ return new Directory(this);
+ }
+
+ public String getOwner() {
+ return run.security().owner().getAsTextPlain(String.class);
+ }
+
+ // TODO permissions
+
+ public void grantPasswordCredential(URI contextService, String username,
+ String password) throws ClientException, ServerException {
+ PasswordCredential pc = new PasswordCredential();
+ pc.setServiceURI(contextService.toString());
+ pc.setUsername(username);
+ pc.setPassword(password);
+ checkError(run.security().credentials()
+ .postXmlAsOctetStream(pc, ClientResponse.class));
+ }
+
+ public void grantKeyCredential(URI contextService, java.io.File source,
+ String unlockPassword, String aliasEntry) throws IOException,
+ ClientException, ServerException {
+ KeyPairCredential kpc = new KeyPairCredential();
+ kpc.setServiceURI(contextService.toString());
+ try (InputStream in = new FileInputStream(source)) {
+ byte[] buffer = new byte[(int) source.length()];
+ IOUtils.read(in, buffer);
+ kpc.setCredentialBytes(buffer);
+ }
+ if (source.getName().endsWith(".p12"))
+ kpc.setFileType("PKCS12");
+ else
+ kpc.setFileType("JKS");
+ kpc.setCredentialName(aliasEntry);
+ kpc.setUnlockPassword(unlockPassword);
+ checkError(run.security().credentials()
+ .postXmlAsOctetStream(kpc, ClientResponse.class));
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/0b04b1ab/server-client/src/main/java/uk/org/taverna/server/client/Status.java
----------------------------------------------------------------------
diff --git a/server-client/src/main/java/uk/org/taverna/server/client/Status.java b/server-client/src/main/java/uk/org/taverna/server/client/Status.java
new file mode 100644
index 0000000..9c375ad
--- /dev/null
+++ b/server-client/src/main/java/uk/org/taverna/server/client/Status.java
@@ -0,0 +1,36 @@
+package uk.org.taverna.server.client;
+
+/**
+ * States of a workflow run. They are {@link #Initialized Initialized},
+ * {@link #Operating Operating}, {@link #Stopped Stopped}, and
+ * {@link #Finished Finished}. Conceptually, there is also a
+ * <tt>Destroyed</tt> state, but the workflow run does not exist (and hence
+ * can't have its state queried or set) in that case.
+ *
+ * @author Donal Fellows
+ */
+public enum Status {
+ /**
+ * The workflow run has been created, but is not yet running. The run
+ * will need to be manually moved to {@link #Operating Operating} when
+ * ready.
+ */
+ Initialized,
+ /**
+ * The workflow run is going, reading input, generating output, etc.
+ * Will eventually either move automatically to {@link #Finished
+ * Finished} or can be moved manually to {@link #Stopped Stopped} (where
+ * supported).
+ */
+ Operating,
+ /**
+ * The workflow run is paused, and will need to be moved back to
+ * {@link #Operating Operating} manually.
+ */
+ Stopped,
+ /**
+ * The workflow run has ceased; data files will continue to exist until
+ * the run is destroyed (which may be manual or automatic).
+ */
+ Finished
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/0b04b1ab/server-client/src/main/java/uk/org/taverna/server/client/TavernaServer.java
----------------------------------------------------------------------
diff --git a/server-client/src/main/java/uk/org/taverna/server/client/TavernaServer.java b/server-client/src/main/java/uk/org/taverna/server/client/TavernaServer.java
new file mode 100644
index 0000000..7c0dcdd
--- /dev/null
+++ b/server-client/src/main/java/uk/org/taverna/server/client/TavernaServer.java
@@ -0,0 +1,128 @@
+package uk.org.taverna.server.client;
+
+import static java.nio.file.Files.readAllBytes;
+import static org.taverna.server.client.wadl.TavernaServer.createClient;
+import static org.taverna.server.client.wadl.TavernaServer.root;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.taverna.server.client.wadl.TavernaServer.Root;
+
+import uk.org.taverna.server.client.generic.Capability;
+import uk.org.taverna.server.client.generic.TavernaRun;
+import uk.org.taverna.server.client.generic.VersionedElement;
+
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
+
+public class TavernaServer extends Connected {
+ final Root root;
+ private final URI location;
+ private final boolean authenticated;
+
+ TavernaServer(URI serviceRoot) {
+ root = root(createClient(), location = serviceRoot);
+ authenticated = false;
+ }
+
+ TavernaServer(URI serviceRoot, String username, String password) {
+ Client client = createClient();
+ client.addFilter(new HTTPBasicAuthFilter(username, password));
+ authenticated = true;
+ root = root(client, location = serviceRoot);
+ }
+
+ TavernaServer(TavernaServer service, String username, String password) {
+ Client client = createClient();
+ client.addFilter(new HTTPBasicAuthFilter(username, password));
+ authenticated = true;
+ root = root(client, location = service.location);
+ getServerVersionInfo();
+ }
+
+ public TavernaServer upgradeToAuth(String username, String password) {
+ if (authenticated)
+ throw new IllegalStateException("may only upgrade an unauthenticated connection");
+ return new TavernaServer(this, username, password);
+ }
+
+ public List<Capability> getCapabilities() {
+ return root.policy().capabilities().getAsCapabilitiesXml()
+ .getCapability();
+ }
+
+ public int getRunLimit() {
+ return root.policy().runLimit().getAsTextPlain(Integer.class);
+ }
+
+ public int getOperatingLimit() {
+ return root.policy().operatingLimit().getAsTextPlain(Integer.class);
+ }
+
+ public List<String> getPermittedWorkflows() {
+ return root.policy().permittedWorkflows().getAsPermittedWorkflowsXml()
+ .getWorkflow();
+ }
+
+ public List<Run> getExistingRuns() {
+ List<Run> runs = new ArrayList<>();
+ for (TavernaRun run : root.runs().getAsRunListXml().getRun())
+ runs.add(new Run(this, run.getValue()));
+ return runs;
+ }
+
+ public VersionedElement getServerVersionInfo() {
+ return root.getAsServerDescriptionXml();
+ }
+
+ private Run response2run(ClientResponse response) throws ClientException, ServerException {
+ checkError(response);
+ if (response.getClientResponseStatus().getStatusCode() == 201) {
+ String[] path = response.getLocation().getPath().split("/");
+ return new Run(this, path[path.length - 1]);
+ }
+ return null;
+ }
+
+ public Run createWorkflowRun(byte[] t2flowBytes) throws ClientException, ServerException {
+ return response2run(root.runs().postVndTavernaT2flowXmlAsOctetStream(
+ t2flowBytes, ClientResponse.class));
+ }
+
+ public Run createWorkflowRun(File t2flowFile) throws IOException, ClientException, ServerException {
+ return createWorkflowRun(readAllBytes(t2flowFile.toPath()));
+ }
+
+ public Run createWorkflowRun(URI t2flowUri) throws ClientException, ServerException {
+ return response2run(root.runs().postTextUriListAsOctetStream(
+ t2flowUri.toString(), ClientResponse.class));
+ }
+
+
+ public static class ClientException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ ClientException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+ }
+ public static class AuthorizationException extends ClientException {
+ private static final long serialVersionUID = 1L;
+
+ AuthorizationException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+ }
+ static class ServerException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ ServerException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/0b04b1ab/server-client/src/main/java/uk/org/taverna/server/client/TavernaServerConnectionFactory.java
----------------------------------------------------------------------
diff --git a/server-client/src/main/java/uk/org/taverna/server/client/TavernaServerConnectionFactory.java b/server-client/src/main/java/uk/org/taverna/server/client/TavernaServerConnectionFactory.java
new file mode 100644
index 0000000..b00b075
--- /dev/null
+++ b/server-client/src/main/java/uk/org/taverna/server/client/TavernaServerConnectionFactory.java
@@ -0,0 +1,23 @@
+package uk.org.taverna.server.client;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+public class TavernaServerConnectionFactory {
+ private Map<URI, TavernaServer> cache = new HashMap<>();
+
+ public synchronized TavernaServer connectNoAuth(URI uri) {
+ TavernaServer conn = cache.get(uri);
+ if (conn == null)
+ cache.put(uri, conn = new TavernaServer(uri));
+ return conn;
+ }
+
+ public TavernaServer connectAuth(URI uri, String username, String password) {
+ TavernaServer conn = new TavernaServer(uri, username, password);
+ // Force a check of the credentials by getting the server version
+ conn.getServerVersionInfo();
+ return conn;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/0b04b1ab/server-client/src/main/java/uk/org/taverna/server/client/package-info.java
----------------------------------------------------------------------
diff --git a/server-client/src/main/java/uk/org/taverna/server/client/package-info.java b/server-client/src/main/java/uk/org/taverna/server/client/package-info.java
new file mode 100644
index 0000000..59e809d
--- /dev/null
+++ b/server-client/src/main/java/uk/org/taverna/server/client/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Implementation of a basic client for Taverna Server.
+ * @author Donal Fellows
+ */
+package uk.org.taverna.server.client;
\ No newline at end of file