From 8b21c539baa207cf9d4c8abb2188fb5c8c495661 Mon Sep 17 00:00:00 2001 From: Robert Haines Date: Fri, 9 Mar 2012 18:27:16 +0000 Subject: [PATCH] Fake list inputs with baclava. If a workflow has any ports of depth > 0 then the inputs are converted to baclava format and uploaded as a single document. This includes local files but remote files can not be handled this way. Tests have been updated to include checks for mixed input depth workflows. --- Rakefile | 1 + lib/t2-server/run.rb | 45 +++++++++++++++++++++++++++- test/tc_run.rb | 35 ++++++++++++++++++++++ test/ts_t2server.rb | 1 + test/workflows/list_and_value.t2flow | 12 ++++++++ 5 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 test/workflows/list_and_value.t2flow diff --git a/Rakefile b/Rakefile index ef534c4..4f11ecf 100644 --- a/Rakefile +++ b/Rakefile @@ -67,6 +67,7 @@ spec = Gem::Specification.new do |s| s.add_development_dependency('libxml-ruby', '>= 1.1.4') s.add_development_dependency('nokogiri', '>= 1.5.0') s.add_development_dependency('rdoc', '>= 3.9.4') + s.add_runtime_dependency('taverna-baclava', '~> 1.0.0') s.add_runtime_dependency('hirb', '>= 0.4.0') end diff --git a/lib/t2-server/run.rb b/lib/t2-server/run.rb index 317dc73..aefcd1c 100644 --- a/lib/t2-server/run.rb +++ b/lib/t2-server/run.rb @@ -32,6 +32,8 @@ require 'base64' require 'time' +require 'rubygems' +require 'taverna-baclava' module T2Server @@ -328,7 +330,7 @@ def start raise RunStateError.new(state, :initialized) if state != :initialized # set all the inputs - _set_all_inputs unless baclava_input? + _check_and_set_inputs unless baclava_input? @server.set_run_attribute(@identifier, @links[:status], state_to_text(:running), "text/plain", @credentials) @@ -877,6 +879,20 @@ def download_output_data(path, range = nil) private + # Check each input to see if it requires a list input and call the + # requisite upload method for the entire set of inputs. + def _check_and_set_inputs + lists = false + input_ports.each_value do |port| + if port.depth > 0 + lists = true + break + end + end + + lists ? _fake_lists : _set_all_inputs + end + # Set all the inputs on the server. The inputs must have been set prior to # this call using the InputPort API. def _set_all_inputs @@ -906,6 +922,33 @@ def _set_all_inputs end end + # Fake being able to handle lists as inputs by converting everything into + # one big baclava document and uploading that. This has to be done for all + # inputs or none at all. The inputs must have been set prior to this call + # using the InputPort API. + def _fake_lists + data_map = {} + + input_ports.each_value do |port| + next unless port.set? + + if port.file? + unless port.remote_file? + file = File.read(port.file) + data_map[port.name] = Taverna::Baclava::Node.new(file) + end + else + data_map[port.name] = Taverna::Baclava::Node.new(port.value) + end + end + + # Create and upload the baclava data. + baclava = Taverna::Baclava::Writer.write(data_map) + upload_data(baclava, "in.baclava") + @server.set_run_attribute(@identifier, @links[:baclava], "in.baclava", + "text/plain", @credentials) + end + # Check that the uri passed in is suitable for credential use: # * rserve uris must not have a path. # * http(s) uris must have at least "/" as their path. diff --git a/test/tc_run.rb b/test/tc_run.rb index b7c43db..268072f 100644 --- a/test/tc_run.rb +++ b/test/tc_run.rb @@ -79,6 +79,41 @@ def test_status_codes end end + # Test run with list inputs + def test_run_list_input + T2Server::Run.create($uri, $wkf_lists, $creds, $conn_params) do |run| + many = [[["boo"]], [["", "Hello"]], [], [[], ["test"], []]] + single = [1, 2, 3, 4, 5] + single_out = single.map { |v| v.to_s } # Taverna outputs strings! + + run.input_port("SINGLE_IN").value = single + run.input_port("MANY_IN").value = many + assert_nothing_raised { run.start } + assert(run.running?) + run.wait + + assert_equal(run.output_port("MANY").value, many) + assert_equal(run.output_port("SINGLE").value, single_out) + end + end + + # Test run with a list and file input + def test_run_list_and_file + T2Server::Run.create($uri, $wkf_l_v, $creds, $conn_params) do |run| + list = ["one", 2, :three] + list_out = list.map { |v| v.to_s } + + run.input_port("list_in").value = list + run.input_port("singleton_in").file = $file_input + assert_nothing_raised { run.start } + assert(run.running?) + run.wait + + assert_equal(run.output_port("list_out").value, list_out) + assert_equal(run.output_port("singleton_out").value, "Hello, World!") + end + end + # Test run with xml input def test_run_xml_input T2Server::Run.create($uri, $wkf_xml, $creds, $conn_params) do |run| diff --git a/test/ts_t2server.rb b/test/ts_t2server.rb index e61a690..ae2b559 100644 --- a/test/ts_t2server.rb +++ b/test/ts_t2server.rb @@ -77,6 +77,7 @@ $wkf_pass = File.read("test/workflows/pass_through.t2flow") $wkf_lists = File.read("test/workflows/empty_list.t2flow") + $wkf_l_v = File.read("test/workflows/list_and_value.t2flow") $wkf_xml = File.read("test/workflows/xml_xpath.t2flow") $wkf_fail = File.read("test/workflows/always_fail.t2flow") $wkf_errors = File.read("test/workflows/list_with_errors.t2flow") diff --git a/test/workflows/list_and_value.t2flow b/test/workflows/list_and_value.t2flow new file mode 100644 index 0000000..75e9363 --- /dev/null +++ b/test/workflows/list_and_value.t2flow @@ -0,0 +1,12 @@ +Workflow3singleton_in00list_in11list_outsingleton_outlist_outlist_insingleton_outsingleton_in + + + + 2d5f4961-acc0-43c4-989d-c0249e9695a6 + + 2012-03-13 17:05:40.688 GMT + + + + + \ No newline at end of file