t2-server 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +8 -0
- data/.travis.yml +6 -0
- data/CHANGES.rdoc +24 -0
- data/Gemfile +35 -0
- data/LICENCE.rdoc +1 -1
- data/README.rdoc +35 -12
- data/Rakefile +4 -41
- data/bin/t2-run-workflow +18 -3
- data/bin/t2-server-admin +12 -2
- data/bin/t2-server-info +11 -1
- data/lib/t2-server.rb +6 -13
- data/lib/t2-server/exceptions.rb +3 -2
- data/lib/t2-server/interaction.rb +1 -2
- data/lib/t2-server/run.rb +89 -7
- data/lib/t2-server/server.rb +95 -33
- data/lib/t2-server/{xml/rexml.rb → version.rb} +9 -49
- data/lib/t2-server/xml.rb +36 -0
- data/lib/t2-server/xml/{xml.rb → fragments.rb} +1 -45
- data/lib/t2-server/xml/{libxml.rb → methods.rb} +14 -2
- data/lib/t2-server/xml/{nokogiri.rb → namespaces.rb} +13 -50
- data/t2-server.gemspec +63 -125
- data/test/tc_run.rb +66 -9
- data/test/tc_server_version.rb +82 -0
- data/test/ts_t2server.rb +8 -7
- data/version.yml +1 -1
- metadata +39 -49
data/lib/t2-server/server.rb
CHANGED
@@ -148,8 +148,7 @@ module T2Server
|
|
148
148
|
create(links[:runs], workflow, "application/vnd.taverna.t2flow+xml",
|
149
149
|
credentials)
|
150
150
|
rescue AccessForbiddenError => afe
|
151
|
-
|
152
|
-
if minor == 4 && patch >= 2
|
151
|
+
if version >= "2.4.2"
|
153
152
|
# Need to re-raise as it's a real error for later versions.
|
154
153
|
raise afe
|
155
154
|
else
|
@@ -159,26 +158,22 @@ module T2Server
|
|
159
158
|
# :startdoc:
|
160
159
|
|
161
160
|
# :call-seq:
|
162
|
-
# version ->
|
161
|
+
# version -> Server::Version
|
163
162
|
#
|
164
|
-
#
|
163
|
+
# An object representing the version of the remote Taverna Server.
|
165
164
|
def version
|
166
165
|
@version ||= _get_version
|
167
166
|
end
|
168
167
|
|
169
|
-
# :
|
170
|
-
# version_components -> array
|
171
|
-
#
|
172
|
-
# An array of the major, minor and patch version components of the remote
|
173
|
-
# Taverna Server.
|
168
|
+
# :stopdoc:
|
174
169
|
def version_components
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
end
|
170
|
+
warn "[DEPRECATED] Server#version_components is deprecated and will "\
|
171
|
+
"be removed in the next major release. Please use "\
|
172
|
+
"Server#version.to_a instead."
|
179
173
|
|
180
|
-
|
174
|
+
version.to_a
|
181
175
|
end
|
176
|
+
# :startdoc:
|
182
177
|
|
183
178
|
# :call-seq:
|
184
179
|
# uri -> URI
|
@@ -233,12 +228,10 @@ module T2Server
|
|
233
228
|
end
|
234
229
|
|
235
230
|
def upload_file(filename, uri, remote_name, credentials = nil)
|
236
|
-
# Different Server versions support different upload methods
|
237
|
-
(major, minor, patch) = version_components
|
238
|
-
|
239
231
|
remote_name = filename.split('/')[-1] if remote_name == ""
|
240
232
|
|
241
|
-
|
233
|
+
# Different Server versions support different upload methods
|
234
|
+
if version >= "2.4.1"
|
242
235
|
File.open(filename, "rb") do |file|
|
243
236
|
upload_data(file, remote_name, uri, credentials)
|
244
237
|
end
|
@@ -250,9 +243,7 @@ module T2Server
|
|
250
243
|
|
251
244
|
def upload_data(data, remote_name, uri, credentials = nil)
|
252
245
|
# Different Server versions support different upload methods
|
253
|
-
|
254
|
-
|
255
|
-
if minor == 4 && patch >= 1
|
246
|
+
if version >= "2.4.1"
|
256
247
|
put_uri = Util.append_to_uri_path(uri, remote_name)
|
257
248
|
@connection.PUT(put_uri, data, "application/octet-stream", credentials)
|
258
249
|
else
|
@@ -357,21 +348,13 @@ module T2Server
|
|
357
348
|
def _get_version
|
358
349
|
doc = _get_server_description
|
359
350
|
version = xpath_attr(doc, @@xpaths[:server], "serverVersion")
|
360
|
-
|
351
|
+
|
352
|
+
if version.nil?
|
361
353
|
raise RuntimeError.new("Taverna Servers prior to version 2.3 " +
|
362
354
|
"are no longer supported.")
|
363
|
-
else
|
364
|
-
# Remove extra version tags if present.
|
365
|
-
version.gsub!("-SNAPSHOT", "")
|
366
|
-
version.gsub!(/alpha[0-9]*/, "")
|
367
|
-
|
368
|
-
# Add .0 if we only have a major and minor component.
|
369
|
-
if version.split(".").length == 2
|
370
|
-
version += ".0"
|
371
|
-
end
|
372
|
-
|
373
|
-
return version
|
374
355
|
end
|
356
|
+
|
357
|
+
Version.new(version)
|
375
358
|
end
|
376
359
|
|
377
360
|
def _get_server_links
|
@@ -400,5 +383,84 @@ module T2Server
|
|
400
383
|
@run_cache.refresh_all!(run_list, credentials)
|
401
384
|
end
|
402
385
|
|
386
|
+
# Represents a Taverna Server version number in a way that can be compared
|
387
|
+
# to other version numbers or strings.
|
388
|
+
#
|
389
|
+
# This class mixes in Comparable so all the usual comparison operators
|
390
|
+
# work as expected.
|
391
|
+
class Version
|
392
|
+
include Comparable
|
393
|
+
|
394
|
+
# :call-seq:
|
395
|
+
# new(version_string) -> Version
|
396
|
+
#
|
397
|
+
# Create a new Version object from the supplied version string.
|
398
|
+
def initialize(version)
|
399
|
+
@string = parse_version(version)
|
400
|
+
@array = []
|
401
|
+
end
|
402
|
+
|
403
|
+
# :call-seq:
|
404
|
+
# to_s -> String
|
405
|
+
#
|
406
|
+
# Convert this Version object back into a String.
|
407
|
+
def to_s
|
408
|
+
@string
|
409
|
+
end
|
410
|
+
|
411
|
+
# :call-seq:
|
412
|
+
# to_a -> Array
|
413
|
+
#
|
414
|
+
# Convert this Version object into an array of numbers representing the
|
415
|
+
# components of the version number. The order of the components is:
|
416
|
+
# * Major
|
417
|
+
# * Minor
|
418
|
+
# * Patch
|
419
|
+
#
|
420
|
+
# For example:
|
421
|
+
# Version.new("2.5.1").to_a == [2, 5, 1]
|
422
|
+
def to_a
|
423
|
+
if @array.empty?
|
424
|
+
comps = @string.split(".")
|
425
|
+
@array = comps.map { |v| v.to_i }
|
426
|
+
end
|
427
|
+
|
428
|
+
@array
|
429
|
+
end
|
430
|
+
|
431
|
+
# :call-seq:
|
432
|
+
# version <=> other -> -1, 0 or +1
|
433
|
+
#
|
434
|
+
# Returns -1, 0 or +1 depending of whether +version+ is less than,
|
435
|
+
# equal to or greater than +other+.
|
436
|
+
#
|
437
|
+
# This is the basis for the tests in Comparable.
|
438
|
+
def <=>(other)
|
439
|
+
other = Version.new(other) if other.instance_of?(String)
|
440
|
+
self.to_a.zip(other.to_a).each do |c|
|
441
|
+
comp = c[0] <=> c[1]
|
442
|
+
return comp unless comp == 0
|
443
|
+
end
|
444
|
+
|
445
|
+
# If we get here then we know we have equal version numbers.
|
446
|
+
0
|
447
|
+
end
|
448
|
+
|
449
|
+
private
|
450
|
+
|
451
|
+
def parse_version(version)
|
452
|
+
# Remove extra version tags if present.
|
453
|
+
version.gsub!("-SNAPSHOT", "")
|
454
|
+
version.gsub!(/alpha[0-9]*/, "")
|
455
|
+
|
456
|
+
# Add .0 if we only have a major and minor component.
|
457
|
+
if version.split(".").length == 2
|
458
|
+
version += ".0"
|
459
|
+
end
|
460
|
+
|
461
|
+
version
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
403
465
|
end
|
404
466
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2010-
|
1
|
+
# Copyright (c) 2010-2014 The University of Manchester, UK.
|
2
2
|
#
|
3
3
|
# All rights reserved.
|
4
4
|
#
|
@@ -30,57 +30,17 @@
|
|
30
30
|
#
|
31
31
|
# Author: Robert Haines
|
32
32
|
|
33
|
-
require '
|
34
|
-
require 'rexml/text'
|
33
|
+
require 'yaml'
|
35
34
|
|
36
35
|
module T2Server
|
37
|
-
module XML
|
38
36
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
37
|
+
# Library version information.
|
38
|
+
module Version
|
39
|
+
# Version information in a Hash
|
40
|
+
INFO = YAML.load_file(File.join(File.dirname(__FILE__), "..", "..",
|
41
|
+
"version.yml"))
|
43
42
|
|
44
|
-
|
45
|
-
|
46
|
-
end
|
47
|
-
|
48
|
-
def xml_first_child(node)
|
49
|
-
node.first
|
50
|
-
end
|
51
|
-
|
52
|
-
def xml_children(doc, &block)
|
53
|
-
doc.each { |node| yield node }
|
54
|
-
end
|
55
|
-
|
56
|
-
def xml_node_name(node)
|
57
|
-
node.name
|
58
|
-
end
|
59
|
-
|
60
|
-
def xml_node_content(node)
|
61
|
-
node.text
|
62
|
-
end
|
63
|
-
|
64
|
-
def xml_node_attribute(node, attribute)
|
65
|
-
node.attributes[attribute]
|
66
|
-
end
|
67
|
-
|
68
|
-
def xpath_compile(xpath)
|
69
|
-
xpath
|
70
|
-
end
|
71
|
-
|
72
|
-
def xpath_find(doc, expr)
|
73
|
-
REXML::XPath.each(doc, expr, Namespaces::MAP)
|
74
|
-
end
|
75
|
-
|
76
|
-
def xpath_first(doc, expr)
|
77
|
-
REXML::XPath.first(doc, expr, Namespaces::MAP)
|
78
|
-
end
|
79
|
-
|
80
|
-
def xpath_attr(doc, expr, attribute)
|
81
|
-
node = xpath_first(doc, expr)
|
82
|
-
node.nil? ? nil : node.attributes[attribute]
|
83
|
-
end
|
84
|
-
end
|
43
|
+
# Version number as a String
|
44
|
+
STRING = [:major, :minor, :patch].map {|d| INFO[d]}.compact.join('.')
|
85
45
|
end
|
86
46
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Copyright (c) 2010-2014 The University of Manchester, UK.
|
2
|
+
#
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# * Redistributions of source code must retain the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer in the documentation
|
13
|
+
# and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# * Neither the names of The University of Manchester nor the names of its
|
16
|
+
# contributors may be used to endorse or promote products derived from this
|
17
|
+
# software without specific prior written permission.
|
18
|
+
#
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
22
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
23
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
24
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
25
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
26
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
27
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
28
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
29
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
#
|
31
|
+
# Author: Robert Haines
|
32
|
+
|
33
|
+
require_relative 'xml/namespaces'
|
34
|
+
require_relative 'xml/fragments'
|
35
|
+
require_relative 'xml/methods'
|
36
|
+
require_relative 'xml/xpath_cache'
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2010-
|
1
|
+
# Copyright (c) 2010-2014 The University of Manchester, UK.
|
2
2
|
#
|
3
3
|
# All rights reserved.
|
4
4
|
#
|
@@ -30,34 +30,8 @@
|
|
30
30
|
#
|
31
31
|
# Author: Robert Haines
|
32
32
|
|
33
|
-
begin
|
34
|
-
require 't2-server/xml/libxml'
|
35
|
-
rescue LoadError
|
36
|
-
begin
|
37
|
-
require 't2-server/xml/nokogiri'
|
38
|
-
rescue LoadError
|
39
|
-
require 't2-server/xml/rexml'
|
40
|
-
end
|
41
|
-
end
|
42
|
-
require 't2-server/xml/xpath_cache'
|
43
|
-
|
44
33
|
module T2Server
|
45
34
|
module XML
|
46
|
-
|
47
|
-
module Namespaces
|
48
|
-
SERVER = "http://ns.taverna.org.uk/2010/xml/server/"
|
49
|
-
REST = SERVER + "rest/"
|
50
|
-
ADMIN = SERVER + "admin/"
|
51
|
-
PORT = "http://ns.taverna.org.uk/2010/port/"
|
52
|
-
|
53
|
-
MAP = {
|
54
|
-
"nss" => Namespaces::SERVER,
|
55
|
-
"nsr" => Namespaces::REST,
|
56
|
-
"nsa" => Namespaces::ADMIN,
|
57
|
-
"port" => Namespaces::PORT
|
58
|
-
}
|
59
|
-
end
|
60
|
-
|
61
35
|
module Fragments
|
62
36
|
WORKFLOW = "<t2s:workflow xmlns:t2s=\"#{Namespaces::SERVER}\">\n"\
|
63
37
|
" %s\n</t2s:workflow>"
|
@@ -100,23 +74,5 @@ module T2Server
|
|
100
74
|
" <t2s:fileType>%s</t2s:fileType>\n"\
|
101
75
|
"</t2s:trustedIdentity>"
|
102
76
|
end
|
103
|
-
|
104
|
-
module Methods
|
105
|
-
# Most methods in this module are provided by the particular XML
|
106
|
-
# library selected above.
|
107
|
-
|
108
|
-
# Given a list of xpath keys, extract the href URIs from those elements.
|
109
|
-
def get_uris_from_doc(doc, keys)
|
110
|
-
cache = XPathCache.instance
|
111
|
-
uris = {}
|
112
|
-
|
113
|
-
keys.each do |key|
|
114
|
-
uri = xpath_attr(doc, cache[key], "href")
|
115
|
-
uris[key] = uri.nil? ? nil : URI.parse(uri)
|
116
|
-
end
|
117
|
-
|
118
|
-
uris
|
119
|
-
end
|
120
|
-
end
|
121
77
|
end
|
122
78
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2010-
|
1
|
+
# Copyright (c) 2010-2014 The University of Manchester, UK.
|
2
2
|
#
|
3
3
|
# All rights reserved.
|
4
4
|
#
|
@@ -30,7 +30,6 @@
|
|
30
30
|
#
|
31
31
|
# Author: Robert Haines
|
32
32
|
|
33
|
-
require 'rubygems'
|
34
33
|
require 'libxml'
|
35
34
|
|
36
35
|
module T2Server
|
@@ -83,6 +82,19 @@ module T2Server
|
|
83
82
|
node = xpath_first(doc, expr)
|
84
83
|
node.nil? ? nil : node.attributes[attribute]
|
85
84
|
end
|
85
|
+
|
86
|
+
# Given a list of xpath keys, extract the href URIs from those elements.
|
87
|
+
def get_uris_from_doc(doc, keys)
|
88
|
+
cache = XPathCache.instance
|
89
|
+
uris = {}
|
90
|
+
|
91
|
+
keys.each do |key|
|
92
|
+
uri = xpath_attr(doc, cache[key], "href")
|
93
|
+
uris[key] = uri.nil? ? nil : URI.parse(uri)
|
94
|
+
end
|
95
|
+
|
96
|
+
uris
|
97
|
+
end
|
86
98
|
end
|
87
99
|
end
|
88
100
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2010-
|
1
|
+
# Copyright (c) 2010-2014 The University of Manchester, UK.
|
2
2
|
#
|
3
3
|
# All rights reserved.
|
4
4
|
#
|
@@ -30,57 +30,20 @@
|
|
30
30
|
#
|
31
31
|
# Author: Robert Haines
|
32
32
|
|
33
|
-
require 'rubygems'
|
34
|
-
require 'nokogiri'
|
35
|
-
|
36
33
|
module T2Server
|
37
34
|
module XML
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
end
|
51
|
-
|
52
|
-
def xml_children(doc, &block)
|
53
|
-
doc.children.each(&block)
|
54
|
-
end
|
55
|
-
|
56
|
-
def xml_node_name(node)
|
57
|
-
node.node_name
|
58
|
-
end
|
59
|
-
|
60
|
-
def xml_node_content(node)
|
61
|
-
node.content
|
62
|
-
end
|
63
|
-
|
64
|
-
def xml_node_attribute(node, attribute)
|
65
|
-
node[attribute]
|
66
|
-
end
|
67
|
-
|
68
|
-
def xpath_compile(xpath)
|
69
|
-
xpath
|
70
|
-
end
|
71
|
-
|
72
|
-
def xpath_find(doc, expr)
|
73
|
-
doc.xpath(expr, Namespaces::MAP)
|
74
|
-
end
|
75
|
-
|
76
|
-
def xpath_first(doc, expr)
|
77
|
-
doc.at_xpath(expr, Namespaces::MAP)
|
78
|
-
end
|
79
|
-
|
80
|
-
def xpath_attr(doc, expr, attribute)
|
81
|
-
node = xpath_first(doc, expr)
|
82
|
-
node.nil? ? nil : node[attribute]
|
83
|
-
end
|
35
|
+
module Namespaces
|
36
|
+
SERVER = "http://ns.taverna.org.uk/2010/xml/server/"
|
37
|
+
REST = SERVER + "rest/"
|
38
|
+
ADMIN = SERVER + "admin/"
|
39
|
+
PORT = "http://ns.taverna.org.uk/2010/port/"
|
40
|
+
|
41
|
+
MAP = {
|
42
|
+
"nss" => Namespaces::SERVER,
|
43
|
+
"nsr" => Namespaces::REST,
|
44
|
+
"nsa" => Namespaces::ADMIN,
|
45
|
+
"port" => Namespaces::PORT
|
46
|
+
}
|
84
47
|
end
|
85
48
|
end
|
86
49
|
end
|