t2-server 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENCE +29 -0
- data/README.rdoc +21 -0
- data/bin/delete_all_runs +65 -0
- data/bin/run_workflow +138 -0
- data/lib/t2server.rb +40 -0
- data/lib/t2server/run.rb +228 -0
- data/lib/t2server/server.rb +324 -0
- data/lib/t2server/xml.rb +51 -0
- metadata +75 -0
data/LICENCE
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
Copyright (c) 2010, 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.
|
data/README.rdoc
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
= Taverna[http://www.taverna.org.uk/] 2 Server Interaction Gem
|
2
|
+
|
3
|
+
Authors:: Robert Haines
|
4
|
+
Version:: 0.1
|
5
|
+
Contact:: mailto:rhaines@manchester.ac.uk
|
6
|
+
URL:: http://taverna.sourceforge.net/
|
7
|
+
Licence:: BSD (See LICENCE or http://www.opensource.org/licenses/bsd-license.php)
|
8
|
+
Copyright:: (c) 2010 The University of Manchester, UK
|
9
|
+
|
10
|
+
|
11
|
+
== Synopsis
|
12
|
+
|
13
|
+
This is a Ruby library to interface with the Taverna 2 Server REST interface.
|
14
|
+
|
15
|
+
== Installation
|
16
|
+
|
17
|
+
[sudo] gem install t2-server
|
18
|
+
|
19
|
+
== Usage
|
20
|
+
|
21
|
+
TBC
|
data/bin/delete_all_runs
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Copyright (c) 2010, The University of Manchester, UK.
|
3
|
+
#
|
4
|
+
# All rights reserved.
|
5
|
+
#
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
8
|
+
#
|
9
|
+
# * Redistributions of source code must retain the above copyright notice,
|
10
|
+
# this list of conditions and the following disclaimer.
|
11
|
+
#
|
12
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
13
|
+
# this list of conditions and the following disclaimer in the documentation
|
14
|
+
# and/or other materials provided with the distribution.
|
15
|
+
#
|
16
|
+
# * Neither the names of The University of Manchester nor the names of its
|
17
|
+
# contributors may be used to endorse or promote products derived from this
|
18
|
+
# software without specific prior written permission.
|
19
|
+
#
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
23
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
24
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
25
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
26
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
27
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
28
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
29
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
30
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
#
|
32
|
+
# Author: Robert Haines
|
33
|
+
|
34
|
+
require 't2server'
|
35
|
+
require 'optparse'
|
36
|
+
|
37
|
+
# set up options
|
38
|
+
opts = OptionParser.new do |opt|
|
39
|
+
opt.banner = "Usage: delete_all_runs [options] server-address"
|
40
|
+
opt.separator ""
|
41
|
+
opt.separator " Where server-address is the full URI of the server to"
|
42
|
+
opt.separator " connect to, e.g.: http://example.com:8080/taverna"
|
43
|
+
opt.separator " and [options] can be:"
|
44
|
+
opt.on_tail("-h", "-?", "--help", "Show this message") do
|
45
|
+
puts opt
|
46
|
+
exit
|
47
|
+
end
|
48
|
+
opt.on_tail("-v", "--version", "Show the version") do
|
49
|
+
puts "Taverna 2 Server Ruby Gem version: #{T2Server::GEM_VERSION}"
|
50
|
+
puts "Taverna 2 Server REST API version: #{T2Server::API_VERSION}"
|
51
|
+
exit
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# parse options
|
56
|
+
opts.parse!
|
57
|
+
|
58
|
+
# check for server address
|
59
|
+
if ARGV[0] == nil
|
60
|
+
puts opts
|
61
|
+
exit 1
|
62
|
+
end
|
63
|
+
|
64
|
+
# connect and delete them all!
|
65
|
+
T2Server::Server.connect(ARGV[0]).delete_all_runs
|
data/bin/run_workflow
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Copyright (c) 2010, The University of Manchester, UK.
|
3
|
+
#
|
4
|
+
# All rights reserved.
|
5
|
+
#
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
8
|
+
#
|
9
|
+
# * Redistributions of source code must retain the above copyright notice,
|
10
|
+
# this list of conditions and the following disclaimer.
|
11
|
+
#
|
12
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
13
|
+
# this list of conditions and the following disclaimer in the documentation
|
14
|
+
# and/or other materials provided with the distribution.
|
15
|
+
#
|
16
|
+
# * Neither the names of The University of Manchester nor the names of its
|
17
|
+
# contributors may be used to endorse or promote products derived from this
|
18
|
+
# software without specific prior written permission.
|
19
|
+
#
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
23
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
24
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
25
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
26
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
27
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
28
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
29
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
30
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
#
|
32
|
+
# Author: Robert Haines
|
33
|
+
|
34
|
+
require 't2server'
|
35
|
+
require 'optparse'
|
36
|
+
|
37
|
+
# go through the outputs and either print the contents
|
38
|
+
# out or save them to a file.
|
39
|
+
# if the output is a list, it appears as a directory so
|
40
|
+
# all the individual entries must be grabbed from there.
|
41
|
+
# server seems to be rather sensitive to slashes, hence
|
42
|
+
# all the [...] mucking about.
|
43
|
+
def get_outputs(run, pout, dir="")
|
44
|
+
outputs = run.ls("out#{dir}")
|
45
|
+
outputs.each do |out|
|
46
|
+
if out.include? "/"
|
47
|
+
get_outputs(run, pout, "#{dir}/#{out[0...-1]}")
|
48
|
+
else
|
49
|
+
print " #{dir}/#{out} -> "
|
50
|
+
data = run.get_output("#{dir[1..-1]}/#{out}")
|
51
|
+
if pout
|
52
|
+
p data
|
53
|
+
else
|
54
|
+
filename = "#{dir[1..-1]}/#{out}".gsub('/','-')
|
55
|
+
File.open(filename, "w") do |file|
|
56
|
+
file.syswrite(data)
|
57
|
+
end
|
58
|
+
puts "written to file: #{filename}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# set up options
|
65
|
+
inputs = {}
|
66
|
+
wkf_file = ""
|
67
|
+
print_output = true
|
68
|
+
opts = OptionParser.new do |opt|
|
69
|
+
opt.banner = "Usage: run_workflow [options] server-address"
|
70
|
+
opt.separator ""
|
71
|
+
opt.separator " Where server-address is the full URI of the server to"
|
72
|
+
opt.separator " connect to, e.g.: http://example.com:8080/taverna"
|
73
|
+
opt.separator " and [options] can be:"
|
74
|
+
opt.on("-w WORKFLOW", "--workflow=WORKFLOW", "The workflow to run. If this is not " +
|
75
|
+
"specified then the workflow is read from standard input") do |val|
|
76
|
+
wkf_file = val
|
77
|
+
end
|
78
|
+
opt.on("-i INPUT:VALUE", "--input=INPUT:VALUE", "Set input port INPUT to VALUE") do |val|
|
79
|
+
input, value = val.chomp.split(':')
|
80
|
+
inputs[input] = value
|
81
|
+
end
|
82
|
+
opt.on("-p", "--[no-]print", "Print outputs to the console. On by default") do |val|
|
83
|
+
print_output = val
|
84
|
+
end
|
85
|
+
opt.on_tail("-h", "-?", "--help", "Show this message") do
|
86
|
+
puts opt
|
87
|
+
exit
|
88
|
+
end
|
89
|
+
opt.on_tail("-v", "--version", "Show the version") do
|
90
|
+
puts "Taverna 2 Server Ruby Gem version: #{T2Server::GEM_VERSION}"
|
91
|
+
puts "Taverna 2 Server REST API version: #{T2Server::API_VERSION}"
|
92
|
+
exit
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# parse options
|
97
|
+
opts.parse!
|
98
|
+
|
99
|
+
# read and check server address
|
100
|
+
uri = ARGV.shift
|
101
|
+
if uri == nil
|
102
|
+
puts opts
|
103
|
+
exit 1
|
104
|
+
end
|
105
|
+
|
106
|
+
# read workflow
|
107
|
+
if wkf_file == ""
|
108
|
+
wkf = ARGF.read
|
109
|
+
else
|
110
|
+
wkf = IO.read(wkf_file)
|
111
|
+
end
|
112
|
+
|
113
|
+
# create run and set inputs
|
114
|
+
run = T2Server::Run.create(uri, wkf)
|
115
|
+
puts "Created run with uuid: #{run.uuid}"
|
116
|
+
|
117
|
+
inputs.each do |input, value|
|
118
|
+
puts "Set input '#{input}' to #{value}"
|
119
|
+
run.set_input(input, value)
|
120
|
+
end
|
121
|
+
|
122
|
+
# start run and wait until it is finished
|
123
|
+
print "Running"
|
124
|
+
run.start_and_wait(:progress => true)
|
125
|
+
|
126
|
+
# get outputs
|
127
|
+
stdout = run.stdout
|
128
|
+
stderr = run.stderr
|
129
|
+
puts "Exitcode: #{run.exitcode}"
|
130
|
+
if stdout != "" then puts "Stdout:\n #{stdout}" end
|
131
|
+
if stderr != "" then puts "Stderr:\n #{stderr}" end
|
132
|
+
|
133
|
+
puts "Outputs:"
|
134
|
+
get_outputs(run, print_output)
|
135
|
+
|
136
|
+
# delete run
|
137
|
+
run.delete
|
138
|
+
puts "Finished and deleted run"
|
data/lib/t2server.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# Copyright (c) 2010, 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 't2server/xml'
|
34
|
+
require 't2server/server'
|
35
|
+
require 't2server/run'
|
36
|
+
|
37
|
+
module T2Server
|
38
|
+
GEM_VERSION = "0.0.1"
|
39
|
+
API_VERSION = "2.2.0a1"
|
40
|
+
end
|
data/lib/t2server/run.rb
ADDED
@@ -0,0 +1,228 @@
|
|
1
|
+
# Copyright (c) 2010, 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 'rexml/document'
|
34
|
+
include REXML
|
35
|
+
|
36
|
+
module T2Server
|
37
|
+
|
38
|
+
class Run
|
39
|
+
|
40
|
+
STATE = {
|
41
|
+
:initialized => "Initialized",
|
42
|
+
:running => "Operating",
|
43
|
+
:finished => "Finished",
|
44
|
+
:stopped => "Stopped"
|
45
|
+
}
|
46
|
+
|
47
|
+
private_class_method :new
|
48
|
+
attr_reader :uuid
|
49
|
+
|
50
|
+
def initialize(server, uuid)
|
51
|
+
@server = server
|
52
|
+
@uuid = uuid
|
53
|
+
@workflow = ""
|
54
|
+
@baclava = false
|
55
|
+
|
56
|
+
@links = get_attributes(@server.get_run_attribute(uuid, ""))
|
57
|
+
#@links.each {|key, val| puts "#{key}: #{val}"}
|
58
|
+
end
|
59
|
+
|
60
|
+
def Run.create(server, workflow, uuid="")
|
61
|
+
if server.class == String
|
62
|
+
server = Server.connect(server)
|
63
|
+
end
|
64
|
+
if uuid == ""
|
65
|
+
new(server, server.initialize_run(workflow))
|
66
|
+
else
|
67
|
+
new(server, uuid)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def delete
|
72
|
+
@server.delete_run uuid
|
73
|
+
end
|
74
|
+
|
75
|
+
def inputs
|
76
|
+
@links[:inputs]
|
77
|
+
end
|
78
|
+
|
79
|
+
def set_input(input, value)
|
80
|
+
@server.set_run_input(self, input, value)
|
81
|
+
end
|
82
|
+
|
83
|
+
def set_input_file(input, filename)
|
84
|
+
@server.set_run_input_file(self, input, filename)
|
85
|
+
end
|
86
|
+
|
87
|
+
def get_output(output, type="text/plain")
|
88
|
+
return unless finished? ### raise exception?
|
89
|
+
doc = @server.get_run_attribute(@uuid, "#{@links[:wdir]}/out/#{output}")
|
90
|
+
doc
|
91
|
+
end
|
92
|
+
|
93
|
+
def expiry
|
94
|
+
@server.get_run_attribute(@uuid, @links[:expiry])
|
95
|
+
end
|
96
|
+
|
97
|
+
def expiry=(date)
|
98
|
+
@server.set_run_attribute(@uuid, @links[:expiry], date)
|
99
|
+
end
|
100
|
+
|
101
|
+
def workflow
|
102
|
+
if @workflow == ""
|
103
|
+
@workflow = @server.get_run_attribute(@uuid, @links[:workflow])
|
104
|
+
end
|
105
|
+
@workflow
|
106
|
+
end
|
107
|
+
|
108
|
+
def status
|
109
|
+
@server.get_run_attribute(@uuid, @links[:status])
|
110
|
+
end
|
111
|
+
|
112
|
+
def start
|
113
|
+
@server.set_run_attribute(@uuid, @links[:status], STATE[:running])
|
114
|
+
end
|
115
|
+
|
116
|
+
def start_and_wait(params={})
|
117
|
+
interval = params[:interval] || 1
|
118
|
+
progress = params[:progress] || false
|
119
|
+
keepalive = params[:keepalive] || false ### TODO maybe move out of params
|
120
|
+
|
121
|
+
# start run and wait
|
122
|
+
start
|
123
|
+
until finished?
|
124
|
+
sleep(interval)
|
125
|
+
if progress
|
126
|
+
print "."
|
127
|
+
STDOUT.flush
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# tidy up output if there is any
|
132
|
+
puts if progress
|
133
|
+
end
|
134
|
+
|
135
|
+
def exitcode
|
136
|
+
@server.get_run_attribute(@uuid, @links[:exitcode]).to_i
|
137
|
+
end
|
138
|
+
|
139
|
+
def stdout
|
140
|
+
@server.get_run_attribute(@uuid, @links[:stdout])
|
141
|
+
end
|
142
|
+
|
143
|
+
def stderr
|
144
|
+
@server.get_run_attribute(@uuid, @links[:stderr])
|
145
|
+
end
|
146
|
+
|
147
|
+
def mkdir(dir)
|
148
|
+
@server.make_run_dir(@uuid, @links[:wdir], dir)
|
149
|
+
end
|
150
|
+
|
151
|
+
def upload_file(filename, params={})
|
152
|
+
location = params[:dir] || ""
|
153
|
+
location = "#{@links[:wdir]}/#{location}"
|
154
|
+
rename = params[:rename] || ""
|
155
|
+
@server.upload_run_file(@uuid, filename, location, rename)
|
156
|
+
end
|
157
|
+
|
158
|
+
def upload_input_file(input, filename, params={})
|
159
|
+
file = upload_file(filename, params)
|
160
|
+
set_input_file(input, file)
|
161
|
+
end
|
162
|
+
|
163
|
+
def upload_baclava_file(filename)
|
164
|
+
@baclava = true
|
165
|
+
rename = upload_file(filename)
|
166
|
+
@server.set_run_attribute(@uuid, @links[:baclava], rename)
|
167
|
+
end
|
168
|
+
|
169
|
+
def ls(dir="")
|
170
|
+
dir_list = @server.get_run_attribute(@uuid, "#{@links[:wdir]}/#{dir}")
|
171
|
+
doc = Document.new(dir_list)
|
172
|
+
|
173
|
+
# compile a list of directory entries stripping the
|
174
|
+
# directory name from the front of each filename
|
175
|
+
entries = []
|
176
|
+
XPath.each(doc, "//nss:dir", Namespaces::MAP) {|e| entries << "#{e.text.split('/')[-1]}/"}
|
177
|
+
XPath.each(doc, "//nss:file", Namespaces::MAP) {|e| entries << e.text.split('/')[-1]}
|
178
|
+
entries
|
179
|
+
end
|
180
|
+
|
181
|
+
def initialized?
|
182
|
+
status == STATE[:initialized]
|
183
|
+
end
|
184
|
+
|
185
|
+
def running?
|
186
|
+
status == STATE[:running]
|
187
|
+
end
|
188
|
+
|
189
|
+
def finished?
|
190
|
+
status == STATE[:finished]
|
191
|
+
end
|
192
|
+
|
193
|
+
private
|
194
|
+
def get_attributes(desc)
|
195
|
+
# first parse out the basic stuff
|
196
|
+
links = parse_description(desc)
|
197
|
+
|
198
|
+
# get inputs
|
199
|
+
inputs = @server.get_run_attribute(@uuid, links[:inputs])
|
200
|
+
doc = Document.new(inputs)
|
201
|
+
nsmap = Namespaces::MAP
|
202
|
+
links[:baclava] = "#{links[:inputs]}/" + XPath.first(doc, "//nsr:baclava", nsmap).attributes["href"].split('/')[-1]
|
203
|
+
|
204
|
+
# set io properties
|
205
|
+
links[:io] = "#{links[:listeners]}/io"
|
206
|
+
links[:stdout] = "#{links[:io]}/properties/stdout"
|
207
|
+
links[:stderr] = "#{links[:io]}/properties/stderr"
|
208
|
+
links[:exitcode] = "#{links[:io]}/properties/exitcode"
|
209
|
+
|
210
|
+
links
|
211
|
+
end
|
212
|
+
|
213
|
+
def parse_description(desc)
|
214
|
+
doc = Document.new(desc)
|
215
|
+
nsmap = Namespaces::MAP
|
216
|
+
{
|
217
|
+
:expiry => XPath.first(doc, "//nsr:expiry", nsmap).attributes["href"].split('/')[-1],
|
218
|
+
:workflow => XPath.first(doc, "//nsr:creationWorkflow", nsmap).attributes["href"].split('/')[-1],
|
219
|
+
:status => XPath.first(doc, "//nsr:status", nsmap).attributes["href"].split('/')[-1],
|
220
|
+
:wdir => XPath.first(doc, "//nsr:workingDirectory", nsmap).attributes["href"].split('/')[-1],
|
221
|
+
:inputs => XPath.first(doc, "//nsr:inputs", nsmap).attributes["href"].split('/')[-1],
|
222
|
+
:output => XPath.first(doc, "//nsr:output", nsmap).attributes["href"].split('/')[-1],
|
223
|
+
:securectx => XPath.first(doc, "//nsr:securityContext", nsmap).attributes["href"].split('/')[-1],
|
224
|
+
:listeners => XPath.first(doc, "//nsr:listeners", nsmap).attributes["href"].split('/')[-1]
|
225
|
+
}
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
@@ -0,0 +1,324 @@
|
|
1
|
+
# Copyright (c) 2010, 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 'base64'
|
34
|
+
require 'uri'
|
35
|
+
require 'net/http'
|
36
|
+
require 'rexml/document'
|
37
|
+
include REXML
|
38
|
+
|
39
|
+
module T2Server
|
40
|
+
class Server
|
41
|
+
private_class_method :new
|
42
|
+
attr_reader :uri, :run_limit
|
43
|
+
|
44
|
+
# list of servers we know about
|
45
|
+
@@servers = []
|
46
|
+
|
47
|
+
def initialize(uri)
|
48
|
+
@uri = uri
|
49
|
+
uri = URI.parse(uri)
|
50
|
+
@host = uri.host
|
51
|
+
@port = uri.port
|
52
|
+
@base_path = uri.path
|
53
|
+
@rest_path = uri.path + "/rest"
|
54
|
+
@links = get_server_description
|
55
|
+
#@links.each {|key, val| puts "#{key}: #{val}"}
|
56
|
+
|
57
|
+
# get max runs
|
58
|
+
@run_limit = get_attribute(@links[:runlimit]).to_i
|
59
|
+
|
60
|
+
# initialise run list
|
61
|
+
@runs = {}
|
62
|
+
@runs = runs
|
63
|
+
end
|
64
|
+
|
65
|
+
def Server.connect(uri)
|
66
|
+
# see if we've already got this server
|
67
|
+
server = @@servers.find {|s| s.uri == uri}
|
68
|
+
|
69
|
+
if !server
|
70
|
+
# no, so create new one and return it
|
71
|
+
server = new(uri)
|
72
|
+
@@servers << server
|
73
|
+
end
|
74
|
+
|
75
|
+
server
|
76
|
+
end
|
77
|
+
|
78
|
+
def create_run(workflow)
|
79
|
+
uuid = initialize_run(workflow)
|
80
|
+
@runs[uuid] = Run.create(self, "", uuid)
|
81
|
+
end
|
82
|
+
|
83
|
+
def initialize_run(workflow)
|
84
|
+
request = Net::HTTP::Post.new("#{@links[:runs]}")
|
85
|
+
request.content_type = "application/xml"
|
86
|
+
response = Net::HTTP.new(@host, @port).start do |http|
|
87
|
+
http.request(request, Fragments::WORKFLOW % workflow)
|
88
|
+
end
|
89
|
+
|
90
|
+
case response
|
91
|
+
when Net::HTTPCreated
|
92
|
+
# return the uuid of the newly created run
|
93
|
+
epr = URI.parse(response['location'])
|
94
|
+
epr.path[-36..-1]
|
95
|
+
when Net::HTTPForbidden
|
96
|
+
puts "Sorry, but the server is already running its configured limit of concurrent workflows."
|
97
|
+
puts "Please try again later."
|
98
|
+
""
|
99
|
+
else
|
100
|
+
response_error(response)
|
101
|
+
""
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def runs
|
106
|
+
request = Net::HTTP::Get.new("#{@links[:runs]}")
|
107
|
+
response = Net::HTTP.new(@host, @port).start {|http| http.request(request)}
|
108
|
+
|
109
|
+
case response
|
110
|
+
when Net::HTTPOK
|
111
|
+
doc = Document.new(response.body)
|
112
|
+
|
113
|
+
# get list of run uuids
|
114
|
+
uuids = []
|
115
|
+
XPath.each(doc, "//nsr:run", Namespaces::MAP) do |run|
|
116
|
+
uuids << run.attributes["href"].split('/')[-1]
|
117
|
+
end
|
118
|
+
|
119
|
+
# add new runs
|
120
|
+
uuids.each do |uuid|
|
121
|
+
if !@runs.has_key? uuid
|
122
|
+
description = get_run_description(uuid)
|
123
|
+
@runs[uuid] = Run.create(self, "", uuid)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# clear out the expired runs
|
128
|
+
if @runs.length > @run_limit
|
129
|
+
@runs.delete_if {|key, val| !uuids.member? key}
|
130
|
+
end
|
131
|
+
|
132
|
+
@runs
|
133
|
+
else
|
134
|
+
response_error(response)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def delete_run(uuid)
|
139
|
+
request = Net::HTTP::Delete.new("#{@links[:runs]}/#{uuid}")
|
140
|
+
response = Net::HTTP.new(@host, @port).start {|http| http.request(request)}
|
141
|
+
|
142
|
+
case response
|
143
|
+
when Net::HTTPNoContent
|
144
|
+
# Success, carry on...
|
145
|
+
@runs.delete(uuid)
|
146
|
+
true
|
147
|
+
when Net::HTTPNotFound
|
148
|
+
puts "Cannot find run #{run.uuid}."
|
149
|
+
false
|
150
|
+
else
|
151
|
+
response_error(response)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def delete_all_runs
|
156
|
+
# first refresh run list
|
157
|
+
runs.each_value {|run| run.delete}
|
158
|
+
end
|
159
|
+
|
160
|
+
def set_run_input(run, input, value)
|
161
|
+
request = Net::HTTP::Put.new("#{@links[:runs]}/#{run.uuid}/#{run.inputs}/input/#{input}")
|
162
|
+
request.content_type = "application/xml"
|
163
|
+
response = Net::HTTP.new(@host, @port).start do |http|
|
164
|
+
http.request(request, Fragments::RUNINPUTVALUE % value)
|
165
|
+
end
|
166
|
+
|
167
|
+
case response
|
168
|
+
when Net::HTTPOK
|
169
|
+
# Yay!
|
170
|
+
true
|
171
|
+
else
|
172
|
+
response_error(response)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def set_run_input_file(run, input, filename)
|
177
|
+
request = Net::HTTP::Put.new("#{@links[:runs]}/#{run.uuid}/#{run.inputs}/input/#{input}")
|
178
|
+
request.content_type = "application/xml"
|
179
|
+
response = Net::HTTP.new(@host, @port).start do |http|
|
180
|
+
http.request(request, Fragments::RUNINPUTFILE % filename)
|
181
|
+
end
|
182
|
+
|
183
|
+
case response
|
184
|
+
when Net::HTTPOK
|
185
|
+
# Yay!
|
186
|
+
true
|
187
|
+
else
|
188
|
+
response_error(response)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def make_run_dir(uuid, root, dir)
|
193
|
+
request = Net::HTTP::Post.new("#{@links[:runs]}/#{uuid}/#{root}")
|
194
|
+
request.content_type = "application/xml"
|
195
|
+
response = Net::HTTP.new(@host, @port).start do |http|
|
196
|
+
http.request(request, Fragments::MKDIR % dir)
|
197
|
+
end
|
198
|
+
|
199
|
+
case response
|
200
|
+
when Net::HTTPCreated
|
201
|
+
# OK, carry on...
|
202
|
+
true
|
203
|
+
when Net::HTTPForbidden
|
204
|
+
puts "Error!", response.body
|
205
|
+
false
|
206
|
+
when Net::HTTPNotFound
|
207
|
+
puts "Cannot find run #{uuid}."
|
208
|
+
false
|
209
|
+
else
|
210
|
+
response_error(response)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def upload_run_file(uuid, filename, location, rename)
|
215
|
+
contents = Base64.encode64(IO.read(filename))
|
216
|
+
rename = filename.split('/')[-1] if rename == ""
|
217
|
+
request = Net::HTTP::Post.new("#{@links[:runs]}/#{uuid}/#{location}")
|
218
|
+
request.content_type = "application/xml"
|
219
|
+
response = Net::HTTP.new(@host, @port).start do |http|
|
220
|
+
http.request(request, Fragments::UPLOAD % [rename, contents])
|
221
|
+
end
|
222
|
+
|
223
|
+
case response
|
224
|
+
when Net::HTTPCreated
|
225
|
+
# Success, return remote name of uploaded file
|
226
|
+
rename
|
227
|
+
when Net::HTTPForbidden
|
228
|
+
puts "Error!", response.body
|
229
|
+
else
|
230
|
+
response_error(response)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def get_run_attribute(uuid, path)
|
235
|
+
get_attribute("#{@links[:runs]}/#{uuid}/#{path}")
|
236
|
+
end
|
237
|
+
|
238
|
+
def set_run_attribute(uuid, path, value)
|
239
|
+
request = Net::HTTP::Put.new("#{@links[:runs]}/#{uuid}/#{path}")
|
240
|
+
request.content_type = "text/plain"
|
241
|
+
response = Net::HTTP.new(@host, @port).start {|http| http.request(request, value)}
|
242
|
+
|
243
|
+
case response
|
244
|
+
when Net::HTTPOK
|
245
|
+
# OK, so carry on
|
246
|
+
true
|
247
|
+
when Net::HTTPForbidden
|
248
|
+
puts "Error!"
|
249
|
+
puts response.body
|
250
|
+
false
|
251
|
+
when Net::HTTPNotFound
|
252
|
+
puts "Cannot find run #{uuid}."
|
253
|
+
false
|
254
|
+
else
|
255
|
+
response_error(response)
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
protected
|
260
|
+
def get_attribute(path)
|
261
|
+
request = Net::HTTP::Get.new(path)
|
262
|
+
response = Net::HTTP.new(@host, @port).start {|http| http.request(request)}
|
263
|
+
|
264
|
+
case response
|
265
|
+
when Net::HTTPOK
|
266
|
+
return response.body
|
267
|
+
when Net::HTTPNotFound
|
268
|
+
puts "Cannot find attribute #{path}."
|
269
|
+
else
|
270
|
+
response_error(response)
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
private
|
275
|
+
def get_server_description
|
276
|
+
request = Net::HTTP::Get.new(@rest_path)
|
277
|
+
response = Net::HTTP.new(@host, @port).start {|http| http.request(request)}
|
278
|
+
|
279
|
+
case response
|
280
|
+
when Net::HTTPOK
|
281
|
+
parse_description(response.body)
|
282
|
+
else
|
283
|
+
response_error(response)
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
def parse_description(desc)
|
288
|
+
doc = Document.new(desc)
|
289
|
+
nsmap = Namespaces::MAP
|
290
|
+
{
|
291
|
+
:runs => URI.parse(XPath.first(doc, "//nsr:runs", nsmap).attributes["href"]).path,
|
292
|
+
:runlimit => URI.parse(XPath.first(doc, "//nsr:runLimit", nsmap).attributes["href"]).path,
|
293
|
+
:permworkflows => URI.parse(XPath.first(doc, "//nsr:permittedWorkflows", nsmap).attributes["href"]).path,
|
294
|
+
:permlisteners => URI.parse(XPath.first(doc, "//nsr:permittedListeners", nsmap).attributes["href"]).path
|
295
|
+
}
|
296
|
+
end
|
297
|
+
|
298
|
+
def get_run_description(uuid)
|
299
|
+
request = Net::HTTP::Get.new("#{@links[:runs]}/#{uuid}")
|
300
|
+
response = Net::HTTP.new(@host, @port).start {|http| http.request(request)}
|
301
|
+
|
302
|
+
case response
|
303
|
+
when Net::HTTPOK
|
304
|
+
return response.body
|
305
|
+
when Net::HTTPNotFound
|
306
|
+
puts "Cannot find run #{uuid}."
|
307
|
+
else
|
308
|
+
response_error(response)
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
def response_error(response)
|
313
|
+
puts "Unnexpected response from Taverna Server!"
|
314
|
+
puts "Server is: #{@host}:#{@port}#{@base_path}"
|
315
|
+
puts "Response code is: #{response.code}"
|
316
|
+
if response.body
|
317
|
+
puts "Response body is: \n#{response.body}"
|
318
|
+
end
|
319
|
+
puts "\nRaw error is: \n#{response.error!}"
|
320
|
+
false
|
321
|
+
end
|
322
|
+
|
323
|
+
end
|
324
|
+
end
|
data/lib/t2server/xml.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# Copyright (c) 2010, 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
|
+
module T2Server
|
34
|
+
module Namespaces
|
35
|
+
SERVER = "http://ns.taverna.org.uk/2010/xml/server/"
|
36
|
+
REST = SERVER + "rest/"
|
37
|
+
MAP = {
|
38
|
+
"nss" => Namespaces::SERVER,
|
39
|
+
"nsr" => Namespaces::REST
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
module Fragments
|
44
|
+
WORKFLOW = "<t2s:scufl xmlns:t2s=\"#{Namespaces::SERVER}\">\n %s\n</t2s:scufl>"
|
45
|
+
RUNINPUT = "<t2sr:runInput xmlns:t2sr=\"#{Namespaces::REST}\">\n %s\n</t2sr:runInput>"
|
46
|
+
RUNINPUTVALUE = RUNINPUT % "<t2sr:value>%s</t2sr:value>"
|
47
|
+
RUNINPUTFILE = RUNINPUT % "<t2sr:file>%s</t2sr:file>"
|
48
|
+
UPLOAD = "<t2sr:upload xmlns:t2sr=\"#{Namespaces::REST}\" t2sr:name=\"%s\">\n %s\n</t2sr:upload>"
|
49
|
+
MKDIR = "<t2sr:mkdir xmlns:t2sr=\"#{Namespaces::REST}\" t2sr:name=\"%s\" />"
|
50
|
+
end
|
51
|
+
end
|
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: t2-server
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Robert Haines
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-07-21 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: This gem provides access to the Taverna 2 Server REST interface from Ruby.
|
23
|
+
email: rhaines@manchester.ac.uk
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files:
|
29
|
+
- README.rdoc
|
30
|
+
- LICENCE
|
31
|
+
files:
|
32
|
+
- bin/run_workflow
|
33
|
+
- bin/delete_all_runs
|
34
|
+
- lib/t2server.rb
|
35
|
+
- lib/t2server/server.rb
|
36
|
+
- lib/t2server/xml.rb
|
37
|
+
- lib/t2server/run.rb
|
38
|
+
- README.rdoc
|
39
|
+
- LICENCE
|
40
|
+
has_rdoc: true
|
41
|
+
homepage: http://www.taverna.org.uk/
|
42
|
+
licenses: []
|
43
|
+
|
44
|
+
post_install_message:
|
45
|
+
rdoc_options: []
|
46
|
+
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
hash: 3
|
55
|
+
segments:
|
56
|
+
- 0
|
57
|
+
version: "0"
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
hash: 3
|
64
|
+
segments:
|
65
|
+
- 0
|
66
|
+
version: "0"
|
67
|
+
requirements: []
|
68
|
+
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 1.3.7
|
71
|
+
signing_key:
|
72
|
+
specification_version: 3
|
73
|
+
summary: Support for interacting with Taverna 2 Server.
|
74
|
+
test_files: []
|
75
|
+
|