Class: T2Server::Run

Inherits:
Object
  • Object
show all
Includes:
XML::Methods
Defined in:
lib/t2-server/run.rb

Overview

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.

Defined Under Namespace

Classes: Status

Constant Summary collapse

XPATHS =

:stopdoc:

{
  # Run XPath queries
  :run_desc   => "/nsr:runDescription",
  :dir        => "//nss:dir",
  :file       => "//nss:file",
  :expiry     => "//nsr:expiry",
  :workflow   => "//nsr:creationWorkflow",
  :status     => "//nsr:status",
  :createtime => "//nsr:createTime",
  :starttime  => "//nsr:startTime",
  :finishtime => "//nsr:finishTime",
  :wdir       => "//nsr:workingDirectory",
  :inputs     => "//nsr:inputs",
  :output     => "//nsr:output",
  :securectx  => "//nsr:securityContext",
  :listeners  => "//nsr:listeners",
  :baclava    => "//nsr:baclava",
  :inputexp   => "//nsr:expected",
  :name       => "//nsr:name",
  :feed       => "//nsr:interaction",
  :gen_prov   => "//nsr:generate-provenance",
  :run_bundle => "//nsr:run-bundle",

  # Port descriptions XPath queries
  :port_in    => "//port:input",
  :port_out   => "//port:output",

  # Run security XPath queries
  :sec_creds  => "//nsr:credentials",
  :sec_perms  => "//nsr:permissions",
  :sec_trusts => "//nsr:trusts",
  :sec_perm   => "/nsr:permissionsDescriptor/nsr:permission",
  :sec_uname  => "nsr:userName",
  :sec_uperm  => "nsr:permission",
  :sec_cred   => "/nsr:credential",
  :sec_suri   => "nss:serviceURI",
  :sec_trust  => "/nsr:trustedIdentities/nsr:trust"
}
BACLAVA_FILE =

The name to be used internally for retrieving results via baclava

"out.xml"
@@xpaths =
XML::XPathCache.instance

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from XML::Methods

#get_uris_from_doc, #xml_children, #xml_document, #xml_first_child, #xml_input_fragment, #xml_keypair_cred_fragment, #xml_mkdir_fragment, #xml_node_attribute, #xml_node_content, #xml_node_name, #xml_password_cred_fragment, #xml_permissions_fragment, #xml_trust_fragment, #xml_upload_fragment, #xpath_attr, #xpath_compile, #xpath_find, #xpath_first

Constructor Details

#initialize(server, uri, credentials = nil) ⇒ Run

New is private but rdoc does not get it right! Hence :stopdoc: section.



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/t2-server/run.rb', line 107

def initialize(server, uri, credentials = nil)
  @server = server
  @uri = uri
  @identifier = Util.get_path_leaf_from_uri(@uri)
  @workflow = ""
  @baclava_in = false
  @baclava_out = false
  @provenance = false

  @credentials = credentials

  # Has this Run finished executing on the server?
  @finished = false

  # Has this Run object been deleted from the server?
  @deleted = false

  # The following three fields hold cached data about the run that is only
  # downloaded the first time it is requested.
  @run_doc = nil
  @owner = nil
  @links = nil

  # initialize ports lists to nil as an empty list means no inputs/outputs
  @input_ports = nil
  @output_ports = nil

  # The interaction reader to use for this run, if required.
  @interaction_reader = nil
end

Instance Attribute Details

#identifierObject (readonly) Also known as: id

The identifier of this run on the server.



54
55
56
# File 'lib/t2-server/run.rb', line 54

def identifier
  @identifier
end

#serverObject (readonly)

The server instance that this run is hosted on.



58
59
60
# File 'lib/t2-server/run.rb', line 58

def server
  @server
end

Class Method Details

.create(server, workflow, *rest) {|run| ... } ⇒ Object

:call-seq:

Run.create(server, workflow) -> run
Run.create(server, workflow, connection_parameters) -> run
Run.create(server, workflow, user_credentials) -> run
Run.create(server, workflow, ...) {|run| ...}

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.

Yields:

  • (run)


155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# 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

Instance Method Details

#add_keypair_credential(uri, filename, password, name = "Imported Certificate", type = :pkcs12) ⇒ Object

:call-seq:

add_keypair_credential(service_uri, filename, password,
  alias = "Imported Certificate", type = :pkcs12) -> URI

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.



833
834
835
836
837
838
839
840
841
842
843
844
845
846
# 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

#add_password_credential(uri, username, password) ⇒ Object

:call-seq:

add_password_credential(service_uri, username, password) -> URI

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.



803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
# 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_trust(filename, type = :x509) ⇒ Object

:call-seq:

add_trust(filename, type = :x509) -> URI

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.



913
914
915
916
917
918
919
920
921
922
# 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

#baclava_input=(filename) ⇒ Object

:call-seq:

baclava_input = filename -> true or false

Use a baclava file for the workflow inputs.

Raises:



470
471
472
473
474
475
476
477
478
479
480
# 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

#baclava_input?Boolean

:call-seq:

baclava_input? -> true or false

Have the inputs to this run been set by a baclava document?

Returns:

  • (Boolean)


510
511
512
# File 'lib/t2-server/run.rb', line 510

def baclava_input?
  @baclava_in
end

#baclava_output(param = nil, &block) ⇒ Object

:call-seq:

baclava_output -> string
baclava_output(filename) -> fixnum
baclava_output(stream) -> fixnum
baclava_output {|chunk| ...}

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.

Raises:

  • (ArgumentError)


554
555
556
557
558
559
560
561
562
563
564
565
# 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

#baclava_output?Boolean

:stopdoc:

Returns:

  • (Boolean)


523
524
525
526
527
528
529
# File 'lib/t2-server/run.rb', line 523

def baclava_output?
  warn "[DEPRECATED] Run#baclava_output? is deprecated and will be "\
    "removed in the next major release. Please use "\
    "Run#generate_baclava_output? instead."

  generate_baclava_output?
end

#create_timeObject

:call-seq:

create_time -> string

Get the creation time of this run as an instance of class Time.



703
704
705
# File 'lib/t2-server/run.rb', line 703

def create_time
  Time.parse(@server.read(links[:createtime], "text/plain", @credentials))
end

#credential(uri) ⇒ Object

:call-seq:

credential(service_uri) -> URI

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.



876
877
878
879
880
# File 'lib/t2-server/run.rb', line 876

def credential(uri)
  return unless owner?

  credentials[uri]
end

#credentialsObject

:call-seq:

credentials -> hash

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.



854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
# 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

#deleteObject

:call-seq:

delete

Delete this run from the server.



230
231
232
233
# File 'lib/t2-server/run.rb', line 230

def delete
  @server.delete(@uri, @credentials)
  @deleted = true
end

#delete_all_credentialsObject

:call-seq:

delete_all_credentials -> true or false

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.



900
901
902
903
904
# File 'lib/t2-server/run.rb', line 900

def delete_all_credentials
  return unless owner?

  @server.delete(links[:sec_creds], @credentials)
end

#delete_all_trustsObject

:call-seq:

delete_all_trusts -> true or false

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.



964
965
966
967
968
# File 'lib/t2-server/run.rb', line 964

def delete_all_trusts
  return unless owner?

  @server.delete(links[:sec_trusts], @credentials)
end

#delete_credential(uri) ⇒ Object

:call-seq:

delete_credential(service_uri) -> true or false

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.



888
889
890
891
892
# File 'lib/t2-server/run.rb', line 888

def delete_credential(uri)
  return unless owner?

  @server.delete(credentials[uri], @credentials)
end

#delete_trust(uri) ⇒ Object

:call-seq:

delete_trust(URI) -> true or false

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.



952
953
954
955
956
# File 'lib/t2-server/run.rb', line 952

def delete_trust(uri)
  return unless owner?

  @server.delete(uri, @credentials)
end

#deleted?Boolean

:call-seq:

deleted? -> true or false

Has this run been deleted from the server?

Returns:

  • (Boolean)


239
240
241
# File 'lib/t2-server/run.rb', line 239

def deleted?
  @deleted
end

#download_output_data(uri, range = nil, &block) ⇒ Object

:stopdoc: Outputs are represented as a directory structure with the eventual list items (leaves) as files. This method (not part of the public API) downloads a file from the run’s working directory.



974
975
976
977
# File 'lib/t2-server/run.rb', line 974

def download_output_data(uri, range = nil, &block)
  @server.read(uri, "application/octet-stream", range, @credentials,
    &block)
end

#error?Boolean

:call-seq:

error? -> true or false

Are there errors in this run’s outputs? Returns false if the run is not finished yet.

Returns:

  • (Boolean)


689
690
691
692
693
694
695
696
697
# 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

#exitcodeObject

:call-seq:

exitcode -> fixnum

Get the return code of the run. Zero indicates success.



378
379
380
# File 'lib/t2-server/run.rb', line 378

def exitcode
  @server.read(links[:exitcode], "text/plain", @credentials).to_i
end

#expiryObject

:call-seq:

expiry -> string

Return the expiry time of this run as an instance of class Time.



284
285
286
# File 'lib/t2-server/run.rb', line 284

def expiry
  Time.parse(@server.read(links[:expiry], "text/plain", @credentials))
end

#expiry=(time) ⇒ Object

:call-seq:

expiry = time -> true or false

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.



295
296
297
298
299
300
301
302
303
304
305
# 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

#finish_timeObject

:call-seq:

finish_time -> string

Get the finish time of this run as an instance of class Time.



719
720
721
# File 'lib/t2-server/run.rb', line 719

def finish_time
  Time.parse(@server.read(links[:finishtime], "text/plain", @credentials))
end

#finished?Boolean

:call-seq:

finished? -> true or false

Is this run in the :finished state?

Returns:

  • (Boolean)


680
681
682
# File 'lib/t2-server/run.rb', line 680

def finished?
  status == :finished
end

#generate_baclava_outputObject

:call-seq:

generate_baclava_output -> true or false

Set the server to save the outputs of this run in baclava format. This must be done before the run is started.

Raises:



487
488
489
490
491
492
493
494
# 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

#generate_baclava_output?Boolean

:call-seq:

generate_baclava_output? -> true or false

Has this run been set to return results in baclava format?

Returns:

  • (Boolean)


518
519
520
# File 'lib/t2-server/run.rb', line 518

def generate_baclava_output?
  @baclava_out
end

#generate_provenance(toggle = true) ⇒ Object

:call-seq:

generate_provenance(toggle = true) -> true or false

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 Run#provenance.

Requesting baclava output for a run will override this setting.

Raises:



575
576
577
578
579
580
581
582
583
584
585
586
# 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

#generate_provenance?Boolean

:call-seq:

generate_provenance? -> true or false

Has this run been set to generate provenance output?

Returns:

  • (Boolean)


592
593
594
# File 'lib/t2-server/run.rb', line 592

def generate_provenance?
  @provenance
end

#grant_permission(username, permission) ⇒ Object

:call-seq:

grant_permission(username, permission) -> username

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.



742
743
744
745
746
747
# 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

#initialized?Boolean

:call-seq:

initialized? -> true or false

Is this run in the :initialized state?

Returns:

  • (Boolean)


664
665
666
# File 'lib/t2-server/run.rb', line 664

def initialized?
  status == :initialized
end

#input_port(port) ⇒ Object

:call-seq:

input_port(port) -> port

Get port.



255
256
257
# File 'lib/t2-server/run.rb', line 255

def input_port(port)
  input_ports[port]
end

#input_portsObject

:call-seq:

input_ports -> hash

Return a hash (name, port) of all the input ports this run expects.



247
248
249
# File 'lib/t2-server/run.rb', line 247

def input_ports
  @input_ports ||= _get_input_port_info
end

#interactions_uriObject

This is a slightly unpleasant hack to help proxy interaction communications through a third party.



1009
1010
1011
# File 'lib/t2-server/run.rb', line 1009

def interactions_uri
  links[:feeddir] || ""
end

#log(param = nil, &block) ⇒ Object

:call-seq:

log -> string
log(filename) -> fixnum
log(stream) -> fixnum
log {|chunk| ...}

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

Raises:

  • (ArgumentError)


416
417
418
419
420
421
# 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

#mkdir(dir) ⇒ Object

:call-seq:

mkdir(dir) -> true or false

Create a directory in the run’s working directory on the server. This could be used to store input data.



428
429
430
431
432
# File 'lib/t2-server/run.rb', line 428

def mkdir(dir)
  dir = Util.strip_path_slashes(dir)

  @server.mkdir(links[:wdir], dir, @credentials)
end

#nameObject

:call-seq:

name -> String

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.



203
204
205
206
# File 'lib/t2-server/run.rb', line 203

def name
  return "" if links[:name].nil?
  @server.read(links[:name], "text/plain", @credentials)
end

#name=(name) ⇒ Object

:call-seq:

name = new_name -> bool

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.



221
222
223
224
# 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

#notifications(type = :new_requests) ⇒ Object

:call-seq:

notifications(type = :new_requests) -> array

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.



1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
# 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

#notifications_uriObject

This is a slightly unpleasant hack to help proxy notification communications through a third party.



1003
1004
1005
# File 'lib/t2-server/run.rb', line 1003

def notifications_uri
  links[:feed] || ""
end

#output_port(port) ⇒ Object

:call-seq:

output_port(port) -> port

Get output port port.



276
277
278
# File 'lib/t2-server/run.rb', line 276

def output_port(port)
  output_ports[port] if finished?
end

#output_portsObject

:call-seq:

output_ports -> hash

Return a hash (name, port) of all the output ports this run has. Until the run is finished this method will return nil.



264
265
266
267
268
269
270
# 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

#ownerObject

:call-seq:

owner -> string

Get the username of the owner of this run. The owner is the user who created the run on the server.



188
189
190
# File 'lib/t2-server/run.rb', line 188

def owner
  @owner ||= _get_run_owner
end

#owner?Boolean

:call-seq:

owner? -> true or false

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.

Returns:

  • (Boolean)


731
732
733
# File 'lib/t2-server/run.rb', line 731

def owner?
  @credentials.username == owner
end

#permission(username) ⇒ Object

:call-seq:

permission(username) -> permission

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.



777
778
779
780
781
# File 'lib/t2-server/run.rb', line 777

def permission(username)
  return unless owner?

  permissions[username] || :none
end

#permissionsObject

:call-seq:

permissions -> hash

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.



755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
# 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

#provenance(param = nil, &block) ⇒ Object

:call-seq:

provenance -> binary blob
provenance(filename) -> fixnum
provenance(stream) -> fixnum
provenance {|chunk| ...}

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.

Raises:

  • (ArgumentError)


616
617
618
619
620
621
622
623
624
625
# 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

#read_interaction_data(name) ⇒ Object

Read a file from the interactions directory for this run on the server.



990
991
992
993
# File 'lib/t2-server/run.rb', line 990

def read_interaction_data(name)
  uri = Util.append_to_uri_path(links[:feeddir], name)
  @server.read(uri, "*/*", @credentials)
end

#read_notification_feedObject

Read from the run’s notification feed.



980
981
982
# File 'lib/t2-server/run.rb', line 980

def read_notification_feed
  @server.read(links[:feed], "application/atom+xml", @credentials)
end

#request_baclava_outputObject

:stopdoc:



497
498
499
500
501
502
503
# File 'lib/t2-server/run.rb', line 497

def request_baclava_output
  warn "[DEPRECATED] Run#request_baclava_output is deprecated and will "\
    "be removed in the next major release. Please use "\
    "Run#generate_baclava_output instead."

  generate_baclava_output
end

#revoke_permission(username) ⇒ Object

:call-seq:

revoke_permission(username) -> true or false

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.



789
790
791
792
793
794
# 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

#running?Boolean

:call-seq:

running? -> true or false

Is this run in the :running state?

Returns:

  • (Boolean)


672
673
674
# File 'lib/t2-server/run.rb', line 672

def running?
  status == :running
end

#startObject

:call-seq:

start -> true or false

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.

Raises:



342
343
344
345
346
347
348
349
350
351
352
353
354
355
# 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

#start_timeObject

:call-seq:

start_time -> string

Get the start time of this run as an instance of class Time.



711
712
713
# File 'lib/t2-server/run.rb', line 711

def start_time
  Time.parse(@server.read(links[:starttime], "text/plain", @credentials))
end

#statusObject

:call-seq:

status -> string

Get the status of this run. Status can be one of :initialized, :running or :finished.



324
325
326
327
328
329
330
331
332
333
# 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

#stderrObject

:call-seq:

stderr -> string

Get anything that the run printed to the standard error stream.



394
395
396
# File 'lib/t2-server/run.rb', line 394

def stderr
  @server.read(links[:stderr], "text/plain", @credentials)
end

#stdoutObject

:call-seq:

stdout -> string

Get anything that the run printed to the standard out stream.



386
387
388
# File 'lib/t2-server/run.rb', line 386

def stdout
  @server.read(links[:stdout], "text/plain", @credentials)
end

#trustsObject

:call-seq:

trusts -> array

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.



932
933
934
935
936
937
938
939
940
941
942
943
944
# 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(data, remote_name, remote_directory = "") ⇒ Object

:call-seq:

upload_data(data, remote_name, remote_directory = "") -> URI

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 Run#mkdir.

Returns the URI of the file on the server in which the data has been stored.



461
462
463
464
# 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_file(filename, params = {}) ⇒ Object

:call-seq:

upload_file(filename, params={}) -> string

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 Run#mkdir.

  • :rename - Save the file on the server with a different name.

The name of the file on the server is returned.



444
445
446
447
448
449
450
# 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(interval = 1) ⇒ Object

:call-seq:

wait(check_interval = 1)

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.

Raises:



364
365
366
367
368
369
370
371
372
# 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

#workflowObject

:call-seq:

workflow -> string

Get the workflow that this run represents.



311
312
313
314
315
316
317
# File 'lib/t2-server/run.rb', line 311

def workflow
  if @workflow == ""
    @workflow = @server.read(links[:workflow], "application/xml",
      @credentials)
  end
  @workflow
end

#write_interaction_data(name, data) ⇒ Object

Write a file to the interactions directory for this run on the server.



996
997
998
999
# File 'lib/t2-server/run.rb', line 996

def write_interaction_data(name, data)
  uri = Util.append_to_uri_path(links[:feeddir], name)
  @server.update(uri, data, "*/*", @credentials)
end

#write_notification(entry) ⇒ Object

Write to the run’s notification feed.



985
986
987
# File 'lib/t2-server/run.rb', line 985

def write_notification(entry)
  @server.create(links[:feed], entry, "application/atom+xml", @credentials)
end

#zip_output(param = nil, port = "", &block) ⇒ Object

:call-seq:

zip_output -> binary blob
zip_output(filename) -> fixnum
zip_output(stream) -> fixnum
zip_output {|chunk| ...}

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.

Raises:

  • (ArgumentError)


648
649
650
651
652
653
654
655
656
657
658
# 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