Class: T2Server::Server

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

Overview

An interface for directly communicating with one or more Taverna 2 Server instances.

Defined Under Namespace

Classes: RunCache, Version

Constant Summary collapse

REST_ENDPOINT =

:stopdoc: Internal references to the main rest and admin top-level resource endpoints.

"rest/"
XPATHS =
{
  # Server top-level XPath queries
  :server   => "//nsr:serverDescription",
  :policy   => "//nsr:policy",
  :run      => "//nsr:run",
  :runs     => "//nsr:runs",

  # Server policy XPath queries
  :runlimit      => "//nsr:runLimit",
  :permworkflows => "//nsr:permittedWorkflows",
  :permlisteners => "//nsr:permittedListenerTypes",
  :notifications => "//nsr:enabledNotificationFabrics"
}
@@xpaths =
XML::XPathCache.instance

Instance Method Summary collapse

Methods included from XML::Methods

#get_uris_from_doc, #xml_children, #xml_document, #xml_first_child, #xml_node_attribute, #xml_node_content, #xml_node_name, #xml_text_node, #xpath_attr, #xpath_compile, #xpath_find, #xpath_first

Constructor Details

#initialize(uri, params = nil) {|_self| ... } ⇒ Server

:call-seq:

new(uri, connection_parameters = nil) -> Server
new(uri, connection_parameters = nil) {|self| ...}

Create a new Server instance that represents the real server at uri. If connection_parameters are supplied they will be used to set up the network connection to the server.

It will yield itself if a block is given.

Yields:

  • (_self)

Yield Parameters:



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/t2-server/server.rb', line 76

def initialize(uri, params = nil)
  # Convert strings to URIs and strip any credentials that have been given
  # in the URI. We do not want to store credentials in this class.
  uri, creds = Util.strip_uri_credentials(uri)

  # setup connection
  @connection = ConnectionFactory.connect(uri, params)

  # The following four fields hold cached data about the server that is
  # only downloaded the first time it is requested.
  @server_doc = nil
  @version = nil
  @version_components = nil
  @links = nil

  # Initialize the run object cache.
  @run_cache = RunCache.new(self)

  yield(self) if block_given?
end

Instance Method Details

#administrator(credentials = nil) {|admin| ... } ⇒ Object

:call-seq:

administrator(credentials = nil) -> Administrator
administrator(credentials = nil) {|admin| ...}

Return an instance of the Taverna Server administrator interface. This method will yield the newly created administrator if a block is given.

Yields:

  • (admin)


103
104
105
106
107
108
# File 'lib/t2-server/server.rb', line 103

def administrator(credentials = nil)
  admin = Administrator.new(self, credentials)

  yield(admin) if block_given?
  admin
end

#create(uri, value, type, credentials = nil) ⇒ Object



262
263
264
# File 'lib/t2-server/server.rb', line 262

def create(uri, value, type, credentials = nil)
  @connection.POST(uri, value, type, credentials)
end

#create_run(workflow, credentials = nil) {|run| ... } ⇒ Object

:call-seq:

create_run(workflow, credentials = nil) -> run
create_run(workflow, credentials = nil) {|run| ...}

Create a run on this server using the specified workflow. This method will yield the newly created Run if a block is given.

The workflow parameter may be the workflow itself, a file name or a File or IO object.

Yields:



119
120
121
122
123
124
125
126
127
128
# File 'lib/t2-server/server.rb', line 119

def create_run(workflow, credentials = nil)
  uri = initialize_run(workflow, credentials)
  run = Run.create(self, "", credentials, uri)

  # Add the newly created run object to the user's run cache
  @run_cache.add_run(run, credentials)

  yield(run) if block_given?
  run
end

#delete(uri, credentials = nil) ⇒ Object



321
322
323
324
325
326
327
328
329
330
# File 'lib/t2-server/server.rb', line 321

def delete(uri, credentials = nil)
  @connection.DELETE(uri, credentials)
rescue AttributeNotFoundError => ane
  # Ignore this. Delete is idempotent so deleting something that has
  # already been deleted, or is for some other reason not there, should
  # happen silently. Return true here because when deleting it's enough to
  # know that it's no longer there rather than whether it was deleted
  # *this time* or not.
  true
end

#delete_all_runs(credentials = nil) ⇒ Object

:call-seq:

delete_all_runs(credentials = nil)

Delete all runs on this server, discarding all of their state. Note that only those runs that the provided credentials have permission to delete will be deleted.



218
219
220
221
222
# File 'lib/t2-server/server.rb', line 218

def delete_all_runs(credentials = nil)
  # Refresh run list, delete everything, clear the user's run cache.
  runs(credentials).each {|run| run.delete}
  @run_cache.clear!(credentials)
end

#initialize_run(workflow, credentials = nil) ⇒ Object

:stopdoc: Create a run on this server using the specified workflow and return the URI to it.

We need to catch AccessForbiddenError here to be compatible with Server versions pre 2.4.2. When we no longer support them we can remove the rescue clause of this method.



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/t2-server/server.rb', line 137

def initialize_run(workflow, credentials = nil)
  # If workflow is a String, it might be a filename! If so, stream it.
  if (workflow.instance_of? String) && (File.file? workflow)
    return File.open(workflow, "r") do |file|
      create(links[:runs], file, "application/vnd.taverna.t2flow+xml",
        credentials)
    end
  end

  # If we get here then workflow could either be a String containing a
  # workflow or a File or IO object.
  create(links[:runs], workflow, "application/vnd.taverna.t2flow+xml",
    credentials)
rescue AccessForbiddenError => afe
  if version >= "2.4.2"
    # Need to re-raise as it's a real error for later versions.
    raise afe
  else
    raise ServerAtCapacityError.new
  end
end

#is_resource_writable?(uri, credentials = nil) ⇒ Boolean

Returns:

  • (Boolean)


257
258
259
260
# File 'lib/t2-server/server.rb', line 257

def is_resource_writable?(uri, credentials = nil)
  headers = @connection.OPTIONS(uri, credentials)
  headers["allow"][0].split(",").include? "PUT"
end

#mkdir(uri, dir, credentials = nil) ⇒ Object

:stopdoc:



225
226
227
228
# File 'lib/t2-server/server.rb', line 225

def mkdir(uri, dir, credentials = nil)
  @connection.POST(uri, XML::Fragments::MKDIR % dir, "application/xml",
    credentials)
end

#read(uri, type, *rest, &block) ⇒ Object



266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
# File 'lib/t2-server/server.rb', line 266

def read(uri, type, *rest, &block)
  credentials = nil
  range = nil

  rest.each do |param|
    case param
    when HttpCredentials
      credentials = param
    when Range
      range = param
    when Array
      range = param[0]..param[1]
    end
  end

  begin
    @connection.GET(uri, type, range, credentials, &block)
  rescue ConnectionRedirectError => cre
    # We've been redirected so save the new connection object with the new
    # server URI and try again with the new URI.
    @connection = cre.redirect
    uri = Util.replace_uri_path(@connection.uri, uri.path)
    retry
  end
end

#read_to_file(filename, uri, type, *rest) ⇒ Object

An internal helper to write streamed data straight to a file.



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

def read_to_file(filename, uri, type, *rest)
  File.open(filename, "wb") do |file|
    read_to_stream(file, uri, type, *rest)
  end
end

#read_to_stream(stream, uri, type, *rest) ⇒ Object

An internal helper to write streamed data directly to another stream. The number of bytes written to the stream is returned. The stream passed in may be anything that provides a write method; instances of IO and File, for example.

Raises:

  • (ArgumentError)


296
297
298
299
300
301
302
303
304
305
306
307
308
# File 'lib/t2-server/server.rb', line 296

def read_to_stream(stream, uri, type, *rest)
  raise ArgumentError,
    "Stream passed in must provide a write method" unless
      stream.respond_to? :write

  bytes = 0

  read(uri, type, *rest) do |chunk|
    bytes += stream.write(chunk)
  end

  bytes
end

#run(identifier, credentials = nil) ⇒ Object

:call-seq:

run(identifier, credentials = nil) -> run

Return the specified run.



208
209
210
# File 'lib/t2-server/server.rb', line 208

def run(identifier, credentials = nil)
  get_runs(credentials)[identifier]
end

#run_limit(credentials = nil) ⇒ Object

:call-seq:

run_limit(credentials = nil) -> fixnum

The maximum number of runs that this server will allow at any one time. Runs in any state (Initialized, Running and Finished) are counted against this maximum.



192
193
194
# File 'lib/t2-server/server.rb', line 192

def run_limit(credentials = nil)
  read(links[:runlimit], "text/plain", credentials).to_i
end

#runs(credentials = nil) ⇒ Object

:call-seq:

runs(credentials = nil) -> [runs]

Return the set of runs on this server.



200
201
202
# File 'lib/t2-server/server.rb', line 200

def runs(credentials = nil)
  get_runs(credentials).values
end

#update(uri, value, type, credentials = nil) ⇒ Object



317
318
319
# File 'lib/t2-server/server.rb', line 317

def update(uri, value, type, credentials = nil)
  @connection.PUT(uri, value, type, credentials)
end

#upload_data(data, remote_name, uri, credentials = nil) ⇒ Object



244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/t2-server/server.rb', line 244

def upload_data(data, remote_name, uri, credentials = nil)
  # Different Server versions support different upload methods
  if version >= "2.4.1"
    put_uri = Util.append_to_uri_path(uri, remote_name)
    @connection.PUT(put_uri, data, "application/octet-stream", credentials)
  else
    contents = Base64.encode64(data)
    @connection.POST(uri,
      XML::Fragments::UPLOAD % [remote_name, contents], "application/xml",
      credentials)
  end
end

#upload_file(filename, uri, remote_name, credentials = nil) ⇒ Object



230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/t2-server/server.rb', line 230

def upload_file(filename, uri, remote_name, credentials = nil)
  remote_name = filename.split('/')[-1] if remote_name == ""

  # Different Server versions support different upload methods
  if version >= "2.4.1"
    File.open(filename, "rb") do |file|
      upload_data(file, remote_name, uri, credentials)
    end
  else
    contents = IO.read(filename)
    upload_data(contents, remote_name, uri, credentials)
  end
end

#uriObject

:call-seq:

uri -> URI

The URI of the connection to the remote Taverna Server.



182
183
184
# File 'lib/t2-server/server.rb', line 182

def uri
  @connection.uri
end

#versionObject

:call-seq:

version -> Server::Version

An object representing the version of the remote Taverna Server.



164
165
166
# File 'lib/t2-server/server.rb', line 164

def version
  @version ||= _get_version
end

#version_componentsObject

:stopdoc:



169
170
171
172
173
174
175
# File 'lib/t2-server/server.rb', line 169

def version_components
  warn "[DEPRECATED] Server#version_components is deprecated and will "\
    "be removed in the next major release. Please use "\
    "Server#version.to_a instead."

  version.to_a
end