class T2Server::Run
An interface for easily running jobs on a Taverna 2 Server with minimal setup and configuration required.
A run can be in one of three states:
-
:initialized - The run has been accepted by the server. It may not yet be ready to run though as its input port may not have been set.
-
:running - The run is being run by the server.
-
:finished - The run has finished running and its outputs are available for download.
Attributes
The identifier of this run on the server.
The identifier of this run on the server.
The server instance that this run is hosted on.
Public Class Methods
Create a new run in the :initialized state. The run will be created on the
server with address supplied by server. This can either be a
String of the form http://example.com:8888/blah
or an already
created instance of T2Server::Server. The
workflow may be supplied as a string in t2flow format, a filename
or a File or IO object. User credentials and connection parameters can be
supplied if required but are both optional. If server is an
instance of T2Server::Server then
connection_parameters will be ignored.
This method will yield the newly created Run if a block is given.
# File lib/t2-server/run.rb, line 155 def Run.create(server, workflow, *rest) credentials = nil uri = nil conn_params = nil rest.each do |param| case param when URI uri = param when ConnectionParameters conn_params = param when HttpCredentials credentials = param end end # If server is not a Server object, get one. server = Server.new(server, conn_params) if server.class != Server # If we are not given a URI to a run then we know we need to create one. uri ||= server.initialize_run(workflow, credentials) # Create the run object and yield it if necessary. run = new(server, uri, credentials) yield(run) if block_given? run end
Public Instance Methods
Provide a client certificate credential for the secure service at the
specified URI. You will need to provide the password to unlock the private
key. You will also need to provide the ‘alias’ or ‘friendlyName’ of the key
you wish to use if it differs from the default. The URI of the credential
on the server is returned. Only the owner of a run may supply credentials
for it. nil
is returned if a user other than the owner uses
this method.
# File lib/t2-server/run.rb, line 833 def add_keypair_credential(uri, filename, password, name = "Imported Certificate", type = :pkcs12) return unless owner? type = type.to_s.upcase contents = Base64.encode64(IO.read(filename)) # basic uri checks uri = _check_cred_uri(uri) value = xml_keypair_cred_fragment(uri, name, contents, type, password) @server.create(links[:sec_creds], value, "application/xml", @credentials) end
Provide a username and password credential for the secure service at the
specified URI. The URI of the credential on the server is returned. Only
the owner of a run may supply credentials for it. nil
is
returned if a user other than the owner uses this method.
# File lib/t2-server/run.rb, line 803 def add_password_credential(uri, username, password) return unless owner? # Is this a new credential, or an update? cred_uri = credential(uri) # basic uri checks uri = _check_cred_uri(uri) value = xml_password_cred_fragment(uri, username, password) if cred_uri.nil? @server.create(links[:sec_creds], value, "application/xml", @credentials) else @server.update(cred_uri, value, "application/xml", @credentials) end end
Add a trusted identity (server public key) to verify peers when using https
connections to Web Services. The URI of the trust on the server is
returned. Only the owner of a run may add a trust. nil
is
returned if a user other than the owner uses this method.
# File lib/t2-server/run.rb, line 913 def add_trust(filename, type = :x509) return unless owner? type = type.to_s.upcase contents = Base64.encode64(IO.read(filename)) value = xml_trust_fragment(contents, type) @server.create(links[:sec_trusts], value, "application/xml", @credentials) end
Use a baclava file for the workflow inputs.
# File lib/t2-server/run.rb, line 470 def baclava_input=(filename) state = status raise RunStateError.new(state, :initialized) if state != :initialized file = upload_file(filename) result = @server.update(links[:baclava], file, "text/plain", @credentials) @baclava_in = true if result result end
Have the inputs to this run been set by a baclava document?
# File lib/t2-server/run.rb, line 510 def baclava_input? @baclava_in end
Get the outputs of this run in baclava format. This can only be done if the output has been requested in baclava format by set_baclava_output before starting the run.
Calling this method with no parameters will simply return a blob of XML
data. Providing a filename will stream the data directly to that file and
return the number of bytes written. Passing in an object that has a
write
method (for example, an instance of File or IO) will
stream the XML data directly to that object and return the number of bytes
that were streamed. Passing in a block will allow access to the underlying
data stream:
run.baclava_output do |chunk| print chunk end
Raises RunStateError if the run has not finished running.
# File lib/t2-server/run.rb, line 554 def baclava_output(param = nil, &block) raise ArgumentError, 'both a parameter and block given for baclava_output' if param && block state = status raise RunStateError.new(state, :finished) if state != :finished raise AccessForbiddenError.new("baclava output") if !@baclava_out baclava_uri = Util.append_to_uri_path(links[:wdir], BACLAVA_FILE) download_or_stream(param, baclava_uri, "*/*", &block) end
Get the creation time of this run as an instance of class Time.
# File lib/t2-server/run.rb, line 703 def create_time Time.parse(@server.read(links[:createtime], "text/plain", @credentials)) end
Return the URI of the credential set for the supplied service, if any. Only
the owner of a run may query its credentials. nil
is returned
if a user other than the owner uses this method.
# File lib/t2-server/run.rb, line 876 def credential(uri) return unless owner? credentials[uri] end
Return a hash (service_uri => credential_uri) of all the credentials
provided for this run. Only the owner of a run may query its credentials.
nil
is returned if a user other than the owner uses this
method.
# File lib/t2-server/run.rb, line 854 def credentials return unless owner? creds = {} doc = xml_document(@server.read(links[:sec_creds], "application/xml", @credentials)) xpath_find(doc, @@xpaths[:sec_cred]).each do |c| uri = URI.parse(xml_node_content(xpath_first(c, @@xpaths[:sec_suri]))) cred_uri = URI.parse(xml_node_attribute(c, "href")) creds[uri] = cred_uri end creds end
Delete this run from the server.
# File lib/t2-server/run.rb, line 230 def delete @server.delete(@uri, @credentials) @deleted = true end
Delete all credentials associated with this workflow run. Only the owner of
a run may delete its credentials. nil
is returned if a user
other than the owner uses this method.
# File lib/t2-server/run.rb, line 900 def delete_all_credentials return unless owner? @server.delete(links[:sec_creds], @credentials) end
Delete all trusted identities associated with this workflow run. Only the
owner of a run may delete its trusts. nil
is returned if a
user other than the owner uses this method.
# File lib/t2-server/run.rb, line 964 def delete_all_trusts return unless owner? @server.delete(links[:sec_trusts], @credentials) end
Delete the credential that has been provided for the specified service.
Only the owner of a run may delete its credentials. nil
is
returned if a user other than the owner uses this method.
# File lib/t2-server/run.rb, line 888 def delete_credential(uri) return unless owner? @server.delete(credentials[uri], @credentials) end
Delete the trust with the provided URI. Only the owner of a run may delete
its trusts. nil
is returned if a user other than the owner
uses this method.
# File lib/t2-server/run.rb, line 952 def delete_trust(uri) return unless owner? @server.delete(uri, @credentials) end
Has this run been deleted from the server?
# File lib/t2-server/run.rb, line 239 def deleted? @deleted end
Are there errors in this run’s outputs? Returns false if the run is not finished yet.
# File lib/t2-server/run.rb, line 689 def error? return false unless finished? output_ports.values.each do |output| return true if output.error? end false end
Get the return code of the run. Zero indicates success.
# File lib/t2-server/run.rb, line 378 def exitcode @server.read(links[:exitcode], "text/plain", @credentials).to_i end
Return the expiry time of this run as an instance of class Time.
# File lib/t2-server/run.rb, line 284 def expiry Time.parse(@server.read(links[:expiry], "text/plain", @credentials)) end
Set the expiry time of this run to time. time should either be a Time object or something that the Time class can parse. If the value given does not specify a date then today’s date will be assumed. If a time/date in the past is specified, the expiry time will not be changed.
# File lib/t2-server/run.rb, line 295 def expiry=(time) unless time.instance_of? Time time = Time.parse(time) end # need to massage the xmlschema format slightly as the server cannot # parse timezone offsets with a colon (eg +00:00) date_str = time.xmlschema(2) date_str = date_str[0..-4] + date_str[-2..-1] @server.update(links[:expiry], date_str, "text/plain", @credentials) end
Get the finish time of this run as an instance of class Time.
# File lib/t2-server/run.rb, line 719 def finish_time Time.parse(@server.read(links[:finishtime], "text/plain", @credentials)) end
Is this run in the :finished state?
# File lib/t2-server/run.rb, line 680 def finished? status == :finished end
Set the server to save the outputs of this run in baclava format. This must be done before the run is started.
# File lib/t2-server/run.rb, line 487 def generate_baclava_output return if @baclava_out state = status raise RunStateError.new(state, :initialized) if state != :initialized @baclava_out = @server.update(links[:output], BACLAVA_FILE, "text/plain", @credentials) end
Has this run been set to return results in baclava format?
# File lib/t2-server/run.rb, line 518 def generate_baclava_output? @baclava_out end
Toggle the generation of provenance for this run on or off. This must be done before the run is started. Once the run has completed provenance can be retrieved with #provenance.
Requesting baclava output for a run will override this setting.
# File lib/t2-server/run.rb, line 575 def generate_provenance(toggle = true) return @provenance if @provenance == toggle || links[:gen_prov].nil? state = status raise RunStateError.new(state, :initialized) if state != :initialized result = @server.update(links[:gen_prov], toggle.to_s, "text/plain", @credentials) # If changing the setting worked then return the new setting, otherwise # return the old one. @provenance = result ? toggle : @provenance end
Has this run been set to generate provenance output?
# File lib/t2-server/run.rb, line 592 def generate_provenance? @provenance end
Grant the user the stated permission. A permission can be one of
:none
, :read
, :update
or
:destroy
. Only the owner of a run may grant permissions on it.
nil
is returned if a user other than the owner uses this
method.
# File lib/t2-server/run.rb, line 742 def grant_permission(username, permission) return unless owner? value = xml_permissions_fragment(username, permission.to_s) @server.create(links[:sec_perms], value, "application/xml", @credentials) end
Is this run in the :initialized state?
# File lib/t2-server/run.rb, line 664 def initialized? status == :initialized end
Get port.
# File lib/t2-server/run.rb, line 255 def input_port(port) input_ports[port] end
Return a hash (name, port) of all the input ports this run expects.
# File lib/t2-server/run.rb, line 247 def input_ports @input_ports ||= _get_input_port_info end
Get the internal Taverna Server log from this run.
Calling this method with no parameters will simply return a text string.
Providing a filename will stream the data directly to that file and return
the number of bytes written. Passing in an object that has a
write
method (for example, an instance of File or IO) will
stream the text directly to that object and return the number of bytes that
were streamed. Passing in a block will allow access to the underlying data
stream:
run.log do |chunk| print chunk end
# File lib/t2-server/run.rb, line 416 def log(param = nil, &block) raise ArgumentError, 'both a parameter and block given for baclava_output' if param && block download_or_stream(param, links[:logfile], "text/plain", &block) end
Create a directory in the run’s working directory on the server. This could be used to store input data.
# File lib/t2-server/run.rb, line 428 def mkdir(dir) dir = Util.strip_path_slashes(dir) @server.mkdir(links[:wdir], dir, @credentials) end
Get the name of this run.
Initially this name is derived by Taverna Server
from the name annotation in the workflow file and the time at which the run
was initialized. It can be set with the name=
method.
For Taverna Server versions prior to version 2.5.0 this is a no-op and the empty string is returned for consistency.
# File lib/t2-server/run.rb, line 203 def name return "" if links[:name].nil? @server.read(links[:name], "text/plain", @credentials) end
Set the name of this run. true
is returned upon success. The
maximum length of names supported by the server is 48 characters. Anything
longer than 48 characters will be truncated before upload.
Initially this name is derived by Taverna Server from the name annotation in the workflow file and the time at which the run was initialized.
For Taverna Server versions prior to version
2.5.0 this is a no-op but true
is still returned for
consistency.
# File lib/t2-server/run.rb, line 221 def name=(name) return true if links[:name].nil? @server.update(links[:name], name[0...48], "text/plain", @credentials) end
Poll the server for notifications and return them in a list. Returns the empty list if there are none, or if the server does not support the Interaction Service.
The type
parameter is used to select which types of
notifications are returned as follows:
-
:requests
- Interaction requests. -
:replies
- Interaction replies. -
:new_requests
- Interaction requests that are new since the last time they were polled (default). -
:all
- All interaction requests and replies.
# File lib/t2-server/run.rb, line 1028 def notifications(type = :new_requests) return [] if links[:feed].nil? @interaction_reader ||= Interaction::Feed.new(self) if type == :new_requests @interaction_reader.new_requests else @interaction_reader.notifications(type) end end
Get output port port.
# File lib/t2-server/run.rb, line 276 def output_port(port) output_ports[port] if finished? end
Return a hash (name, port) of all the output ports this run has. Until the run is finished this method will return nil.
# File lib/t2-server/run.rb, line 264 def output_ports if finished? && @output_ports.nil? @output_ports = _get_output_port_info end @output_ports end
Get the username of the owner of this run. The owner is the user who created the run on the server.
# File lib/t2-server/run.rb, line 188 def owner @owner ||= _get_run_owner end
Are the credentials being used to access this run those of the owner? The owner of the run can give other users certain access rights to their runs but only the owner can change these rights - or even see what they are. Sometimes it is useful to know if the user accessing the run is actually the owner of it or not.
# File lib/t2-server/run.rb, line 731 def owner? @credentials.username == owner end
Return the permission granted to the supplied username, if any. Only the
owner of a run may query its permissions. nil
is returned if a
user other than the owner uses this method.
# File lib/t2-server/run.rb, line 777 def permission(username) return unless owner? permissions[username] || :none end
Return a hash (username => permission) of all the permissions set for
this run. Only the owner of a run may query its permissions.
nil
is returned if a user other than the owner uses this
method.
# File lib/t2-server/run.rb, line 755 def permissions return unless owner? perms = {} doc = xml_document(@server.read(links[:sec_perms], "application/xml", @credentials)) xpath_find(doc, @@xpaths[:sec_perm]).each do |p| user = xml_node_content(xpath_first(p, @@xpaths[:sec_uname])) perm = xml_node_content(xpath_first(p, @@xpaths[:sec_uperm])).to_sym perms[user] = perm end perms end
Get the provenance of this run from the server in zip format.
Calling this method with no parameters will simply return a blob of zipped
data. Providing a filename will stream the data directly to that file and
return the number of bytes written. Passing in an object that has a
write
method (for example, an instance of File or IO) will
stream the data directly to that object and return the number of bytes that
were streamed. Passing in a block will allow access to the underlying data
stream:
run.provenance do |chunk| print chunk end
Raises RunStateError if the run has not finished running.
# File lib/t2-server/run.rb, line 616 def provenance(param = nil, &block) raise ArgumentError, 'both a parameter and block given for provenance' if param && block state = status raise RunStateError.new(state, :finished) if state != :finished raise AccessForbiddenError.new("provenance") unless @provenance download_or_stream(param, links[:run_bundle], "*/*", &block) end
Revoke whatever permissions that have been granted to the user. Only the
owner of a run may revoke permissions on it. nil
is returned
if a user other than the owner uses this method.
# File lib/t2-server/run.rb, line 789 def revoke_permission(username) return unless owner? uri = Util.append_to_uri_path(links[:sec_perms], username) @server.delete(uri, @credentials) end
Is this run in the :running state?
# File lib/t2-server/run.rb, line 672 def running? status == :running end
Start this run on the server. Returns true if the run was started, false otherwise.
Raises RunStateError if the run is not in the :initialized state.
# File lib/t2-server/run.rb, line 342 def start state = status raise RunStateError.new(state, :initialized) if state != :initialized # set all the inputs _check_and_set_inputs unless baclava_input? begin @server.update(links[:status], Status.to_text(:running), "text/plain", @credentials) rescue ServerAtCapacityError => sace false end end
Get the start time of this run as an instance of class Time.
# File lib/t2-server/run.rb, line 711 def start_time Time.parse(@server.read(links[:starttime], "text/plain", @credentials)) end
Get the status of this run. Status can be one of :initialized, :running or :finished.
# File lib/t2-server/run.rb, line 324 def status return :deleted if @deleted return :finished if @finished state = Status.to_sym(@server.read(links[:status], "text/plain", @credentials)) @finished = (state == :finished) state end
Get anything that the run printed to the standard error stream.
# File lib/t2-server/run.rb, line 394 def stderr @server.read(links[:stderr], "text/plain", @credentials) end
Get anything that the run printed to the standard out stream.
# File lib/t2-server/run.rb, line 386 def stdout @server.read(links[:stdout], "text/plain", @credentials) end
Return a list of all the URIs of trusts that have been registered for this
run. At present there is no way to differentiate between trusts without
noting the URI returned when originally uploaded. Only the owner of a run
may query its trusts. nil
is returned if a user other than the
owner uses this method.
# File lib/t2-server/run.rb, line 932 def trusts return unless owner? t_uris = [] doc = xml_document(@server.read(links[:sec_trusts], "application/xml", @credentials)) xpath_find(doc, @@xpaths[:sec_trust]). each do |t| t_uris << URI.parse(xml_node_attribute(t, "href")) end t_uris end
Upload data to the server and store it in remote_file
. The
remote directory to put this file in can also be specified, but if it is it
must first have been created by a call to #mkdir.
Returns the URI of the file on the server in which the data has been stored.
# File lib/t2-server/run.rb, line 461 def upload_data(data, remote_name, remote_directory = "") location_uri = Util.append_to_uri_path(links[:wdir], remote_directory) @server.upload_data(data, remote_name, location_uri, @credentials) end
Upload a file, with name filename, to the server. Possible values that can be passed in via params are:
-
:dir - The directory to upload to. If this is not left blank the corresponding directory will need to have been created by #mkdir.
-
:rename - Save the file on the server with a different name.
The name of the file on the server is returned.
# File lib/t2-server/run.rb, line 444 def upload_file(filename, params={}) location = params[:dir] || "" uri = Util.append_to_uri_path(links[:wdir], location) rename = params[:rename] || "" file_uri = @server.upload_file(filename, uri, rename, @credentials) Util.get_path_leaf_from_uri(file_uri) end
Wait (block) for this run to finish. How often (in seconds) the run is tested for completion can be specified with check_interval.
Raises RunStateError if the run is still in the :initialized state.
# File lib/t2-server/run.rb, line 364 def wait(interval = 1) state = status raise RunStateError.new(state, :running) if state == :initialized # wait until finished? sleep(interval) end end
Get the workflow that this run represents.
# File lib/t2-server/run.rb, line 311 def workflow if @workflow == "" @workflow = @server.read(links[:workflow], "application/xml", @credentials) end @workflow end
Get the working directory of this run directly from the server in zip format.
Calling this method with no parameters will simply return a blob of zipped
data. Providing a filename will stream the data directly to that file and
return the number of bytes written. Passing in an object that has a
write
method (for example, an instance of File or IO) will
stream the zip data directly to that object and return the number of bytes
that were streamed. Passing in a block will allow access to the underlying
data stream:
run.zip_output do |chunk| print chunk end
Raises RunStateError if the run has not finished running.
# File lib/t2-server/run.rb, line 648 def zip_output(param = nil, port = "", &block) raise ArgumentError, "both a parameter and block given for zip_output" if param && block state = status raise RunStateError.new(state, :finished) if state != :finished path = port.empty? ? "out" : "out/#{port}" output_uri = Util.append_to_uri_path(links[:wdir], path) download_or_stream(param, output_uri, "application/zip", &block) end