= Taverna[http://www.taverna.org.uk/] 2 Server Interaction Gem
Authors:: Robert Haines
Contact:: mailto:support@mygrid.org.uk
URL:: http://www.taverna.org.uk/
Licence:: BSD (See LICENCE or http://www.opensource.org/licenses/bsd-license.php)
Copyright:: (c) 2010-2015 The University of Manchester, UK
{}[http://badge.fury.io/rb/t2-server]
{}[https://codeclimate.com/github/myGrid/t2-server-gem]
{}[https://travis-ci.org/myGrid/t2-server-gem]
{}[https://coveralls.io/r/myGrid/t2-server-gem?branch=master]
== Synopsis
This is a Ruby library to interface with the Taverna 2 Server REST API.
== Installation
Simply install as you would any other gem:
[sudo] gem install t2-server
Or use {Bundler}[http://bundler.io/], with
gem 't2-server', '~> 1.0'
in your +Gemfile+, for example.
In case of problems with the above the gem is available for download here:
https://rubygems.org/gems/t2-server
You can also download the source code from here:
https://github.com/myGrid/t2-server-gem
== Compatibility
This gem uses {Semantic Versioning}[http://semver.org/].
=== Taverna Server
Versions 0.9.x of this library are compatible with Taverna Server 2.3 and 2.4.
It is not compatible with any earlier version of Taverna Server due to breaking
changes in its REST interface.
From version 1.0.0 this library is not guaranteed to be compatible with
Taverna Server 2.3. It might work but it is not supported, and may stop working
at any time.
Version 1.0.0 of this library saw the removal of older methods that were
previously deprecated. If your code no longer works with this version then
please re-test it with version 0.9.3 and check for deprecation messages before
reporting bugs.
We strongly encourage all users to upgrade to the current version of Taverna
Server, but if that is not possible right now then these are the recommended
version pairings:
* pre Taverna Server 2.3, use version 0.6.1 of the gem
* 2.3, use version 0.9.3
* 2.4, use version 1.0.0 and up.
* 2.5 and up, use version 1.2.0 and up.
=== Ruby
This library is known to work with the following versions of Ruby:
* 1.9.3 +*
* 2.0.0 +*
* 2.1.5 +*
* 2.2.0 +*
* rbx 2.2 +
Those marked with an asterisk (*) are fully supported and bugs found against
them will be fixed. Other versions may work but are not tested or supported.
Those marked with a plus (+) are tested in
{https://travis-ci.org/myGrid/t2-server-gem}[Travis].
Ruby 1.8.7 is no longer supported as it reached its end of life at the end of
June 2013.
== Usage
There are two entry points for the T2Server API:
* T2Server::Run - Use this for running single jobs on a server.
* T2Server::Server - Use this if you are providing a web interface to
one or more Taverna 2 Server instances.
In both cases the gem should be initialized by requiring the top level ruby
file:
require 't2-server'
=== Configuring a Server connection
Setting up a connection to a secure server can be quite tricky and a secure
Taverna Server is no different. To make things slightly easier this library
provides some short cuts to providing various parameters for different types of
connection.
Connection configuration settings are passed in to various methods using the
+ConnectionParameters+ class. Parameters that can be set are:
* :ca_file - A file to use as a Certificate Authority (CA) for self-signed server certificates.
* :ca_path - Path or list of paths to directories of CA certificates.
* :verify_peer - Use a CA to verify that the Taverna Server you are connecting to has a valid server certificate and that it is the correct one.
* :client_certificate - A certificate to use for client certificate authentication.
* :client_password - The password to unlock the private key of the client certificate.
* :ssl_version - The TLS/SSL version to use (:TLSv1, :SSLv23 or :SSLv3)
* :open_timeout - The number of seconds to wait while opening a connection.
* :read_timeout - The number of seconds to wait while reading from a connection.
And can be set like this for a standard https connection:
conn_params = ConnectionParameters.new
conn_params[:verify_peer] = true
This will ensure that the identity of the Taverna Server you are connecting to
will be verified using the default set of certificates for your platform.
:ca_path can also be set to a list of paths if required. You do not
need to include your platform's default certificate paths as these are included
automatically.
For convenience a number of standard sets of parameters have been defined. The
above example is available as +DefaultConnectionParameters+. Others available
are:
* +InsecureSSLConnectionParameters+ - to ignore SSL checks. Not recommended!
* +CustomCASSLConnectionParameters+ - for custom (self-signed) CAs.
* +ClientAuthSSLConnectionParameters+ - for client certificate authentication.
* +SSL3ConnectionParameters+ - uses SSLv3 as the default transport layer.
See the rdoc for more details on these classes.
=== Authenticating to a Taverna Server
Some calls to a server require that a set of user credentials are provided.
These are simple to set up:
credentials = T2Server::HttpBasic.new("username", "password")
=== Server API example
The Server constructor can yield the newly created object. Simply supply a URI
and a set of connection parameters to connect to a server:
T2Server::Server.new(uri, conn_params) do |server|
...
end
Note that credentials are not required by default to simply connect to a
Taverna Server. Further operations (such as creating and starting runs) may
require authorization depending on how your server has been set up.
To create a Run on a Server simply pass the workflow you wish to run and your
credentials:
server.create_run(workflow, credentials) do |run|
...
end
The +workflow+ parameter can be the workflow itself, a filename or a File or
IO object.
An individual run can be deleted with its own delete method (see
below) but all runs on a server can be deleted in one go:
server.delete_all_runs(credentials)
Note that you can only delete runs for which your credentials have delete
authorization. See later for details.
=== Run API example
You can bypass the Server API if you know you are only going to be dealing with
a couple of runs directly:
T2Server::Run.create(uri, workflow, credentials, conn_params) do |run|
...
end
As before, the +workflow+ parameter can be the workflow itself, a filename or
a File or IO object.
Setting an input port to a run is very easy:
run.input_port("port_name").value = 1
run.input_port("port_name").value = "Hello!"
run.input_port("port_name").value = ["list", "of", "values"]
Or you can use a local file as input:
run.input_port("port_name").file = filename
Once all the inputs have been set the run can be started:
run.start
And monitored to see if it has finished:
run.finished?
run.running?
Or just wait until the run has finished:
run.wait
While a workflow is running it might produce notifications via the
{Interaction Service}[http://dev.mygrid.org.uk/wiki/display/taverna/Interaction+service].
These can be polled with:
run.notifications
If there are any new notifications that have not been responded to they will
be returned in a list to be processed. Notifications take the form of a Web
page to be displayed and the notification objects returned from the above call
hold a URI to that page. The following code prints those URIs to the console:
run.notifications.each do |i|
puts i.uri
end
When the workflow has finished executing then the outputs can be collected
into memory or saved to a file:
result = run.output_port("port_name").value
run.output_port("port_name").write_value_to_file("/path/to/value.txt")
Outputs can be queried as to their type, size (in bytes) or if they contain an
error message:
run.output_port("port_name").type
run.output_port("port_name").size
run.output_port("port_name").error?
If the output does hold an error then it can be found in the value of the
output as normal.
If you have a lot of output you can grab the whole lot in a zip archive. This
can be downloaded into memory or saved directly to a file.
zip_data = run.zip_output # download to memory
run.zip_output("/path/to/output.zip") # save to a file
Using baclava documents for setting inputs and collecting outputs is also
supported:
run.baclava_input = filename
But make sure you request baclava output *before* starting the run. Baclava
output can be downloaded into memory or saved directly to a file.
run.generate_baclava_output
run.start
run.wait
output = run.baclava_output # download to memory
run.baclava_output("/path/to/output.baclava") # save to a file
Later versions of Taverna Server can generate a complete provenance log of a
workflow run in {Taverna-PROV}[https://github.com/myGrid/taverna-prov] format.
The generation of provenance data must be requested *before* starting the run.
run.generate_provenance
run.start
...
provenance = run.provenance # download to memory
run.provenance("/path/to/provenance.zip") # save to a file
The resultant provenance bundle is a zip file containing all input, output and
intermediate values as separate files, along with the provenance of
the workflow run. The bundle is based on the
{Research Object Bundle specification}[http://wf4ever.github.io/ro/bundle/],
and complies with the
{W3C PROV-O provenance specification}[http://www.w3.org/TR/prov-o/].
The log from Taverna Server can be downloaded in a similar way to zip files or
Baclava documents.
log = run.log # download to memory
run.log("/path/to/log.txt") # save to a file
When downloading outputs the underlying stream can be accessed by supplying a
block to the value, zip_output, provenance, baclava_output or log methods:
run.output_port("port_name").value do |data|
print data
end
A run can be deleted when no longer needed, like so:
run.delete
See the rdoc for more information. Many methods and classes have much more
functionality than the defaults described above. Please note that anything
which does not appear in the documentation is not intended to be part of the
public API. Use of undocumented classes and methods is entirely at your own
risk! Such things might not have consistent behaviour and might be removed at
any time.
=== Example scripts
As well as rdoc there are also a couple of example scripts which
demonstrate good use of the T2Server API. These are available in the
bin directory but are also installed with the library code when the
gem is installed:
* t2-run-workflow
* t2-server-info
* t2-delete-runs
* t2-get-output
* t2-server-admin
Running any of these scripts with a -h or --help
switch will show how to use them, e.g.:
t2-run-workflow --help
== Interacting with secure Web Services
This library can be used to run workflows that contain secure
services. Such services may be secured in a number of ways depending
on how the credentials are passed and whether they are REST, SOAP or Rshell
services.
Running workflows that contain secure services requires that you pass
your credentials to Taverna Server so that it can authenticate itself
as you on your behalf.
It is essential that you trust the Taverna Server that you are
using!
Ideally, you should only pass sensitive information, such as
passwords, via https so that you can be sure that it is not being read
in transit.
=== Username and password credentials
==== REST
REST services are commonly secured via HTTP Basic or HTTP Digest
authentication and Taverna treats these two schemes in the same
way. Simply pass in your username and password with the *host* name of
the server on which the service is running:
run.add_password_credential("https://example.com:8443/", "username", "password")
The above example shows a https server running on port 8443. If the
service is on port 80 for http or port 443 for https then you don't
need to specify the port.
If there are services on the same host that require different credentials then
you will need to specify the realm for which each set of credentials applies.
This is done by adding the name of the realm to the end of the host name with
a # separating them:
run.add_password_credential("https://example.com:8443/#realm", "username", "password")
==== SOAP
SOAP services are commonly secured via WS-Security. Simply pass in the
WSDL address of the service with your username and password:
run.add_password_credential("https://example.com:8443/services/MyService?wsdl", "username", "password")
==== R Servers (via Rshells)
You can authenticate to R Servers in almost exactly the same way as for
REST services - only the protocol scheme is different. So instead of
+http+ or +https+ it is +rserve+:
run.add_password_credential("rserve://example.com:6311", "username", "password")
=== Keypair (certificate-based) credentials
Some https servers authenticate clients using certificates. If you
have services that require this type of authentication you can upload
a keypair:
run.add_keypair_credential("https://example.com:8443/", "certificate.p12", "password")
=== Trusts (peer verification)
If the services in your workflows are on a https server then Taverna
requires that it can verify that the server is the one you expect it
to be. This is done by peer verification. In most cases this happens
automatically and transparently but if the remote server has a
non-standard or "self-signed" certificate then you will need to
provide Taverna with the corresponding public key for verification to
take place:
run.add_trust("public-key.pem")
== Interacting with other Taverna Server users
Taverna Server is a multi-user system and as such insulates users from one
another as much as possible. Each run that a user creates can only be accessed
by that user by default. If you want to give another user permission to
perform certain actions on a run then you can do so:
run.grant_permission("username", :permission)
Available permissions are:
* :none - No permissions.
* :read - Read the state of the run and get its outputs.
* :update - Set the state of the run (e.g. start it).
* :destroy - Delete the run.
Permissions are accumulative so giving a user the :destroy permission
also allows that user to read and set the run's state. Note that there is no
way for any user other than the owner of a run to perform any security related
actions on it. This means that only the owner may grant, query and revoke
permissions and only the owner may add, query and delete trusts and
credentials.
You can revoke a user's permission:
run.revoke_permission("username")
You can get a list of the permissions you have granted for a run:
run.permissions
And also see what permission you have granted a particular user:
run.permission("username")
== Support
Please email mailto:support@mygrid.org.uk for any questions relating to
this Ruby gem.
== References
Taverna 2 Server:: http://www.taverna.org.uk/documentation/taverna-2-x/server/
REST API Documentation:: http://www.taverna.org.uk/documentation/taverna-2-x/server/rest-api/