taverna-player 0.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.
Files changed (192) hide show
  1. data/.gitignore +18 -0
  2. data/Gemfile +18 -0
  3. data/LICENCE.rdoc +29 -0
  4. data/README.rdoc +663 -0
  5. data/Rakefile +65 -0
  6. data/app/assets/javascripts/taverna_player/application.js +14 -0
  7. data/app/assets/javascripts/taverna_player/runs.js +42 -0
  8. data/app/assets/stylesheets/scaffold.css +56 -0
  9. data/app/assets/stylesheets/taverna_player/application.css +13 -0
  10. data/app/assets/stylesheets/taverna_player/coderay.css +120 -0
  11. data/app/controllers/taverna_player/application_controller.rb +16 -0
  12. data/app/controllers/taverna_player/runs_controller.rb +18 -0
  13. data/app/controllers/taverna_player/service_credentials_controller.rb +18 -0
  14. data/app/helpers/taverna_player/application_helper.rb +55 -0
  15. data/app/helpers/taverna_player/runs_helper.rb +84 -0
  16. data/app/models/taverna_player/interaction.rb +25 -0
  17. data/app/models/taverna_player/run.rb +117 -0
  18. data/app/models/taverna_player/run_port.rb +148 -0
  19. data/app/models/taverna_player/service_credential.rb +56 -0
  20. data/app/views/layouts/taverna_player/embedded.html.erb +27 -0
  21. data/app/views/taverna_player/runs/_button.html.erb +19 -0
  22. data/app/views/taverna_player/runs/_info.html.erb +56 -0
  23. data/app/views/taverna_player/runs/_info.json.jbuilder +2 -0
  24. data/app/views/taverna_player/runs/_inputs.html.erb +34 -0
  25. data/app/views/taverna_player/runs/_inputs.json.jbuilder +8 -0
  26. data/app/views/taverna_player/runs/_interaction.html.erb +68 -0
  27. data/app/views/taverna_player/runs/_outputs.html.erb +41 -0
  28. data/app/views/taverna_player/runs/_poll.html.erb +27 -0
  29. data/app/views/taverna_player/runs/create.json.jbuilder +3 -0
  30. data/app/views/taverna_player/runs/embedded/_button.html.erb +19 -0
  31. data/app/views/taverna_player/runs/embedded/_info.html.erb +25 -0
  32. data/app/views/taverna_player/runs/embedded/_inputs.html.erb +32 -0
  33. data/app/views/taverna_player/runs/embedded/_outputs.html.erb +32 -0
  34. data/app/views/taverna_player/runs/embedded/new.html.erb +58 -0
  35. data/app/views/taverna_player/runs/embedded/show.html.erb +39 -0
  36. data/app/views/taverna_player/runs/embedded/show.js.erb +35 -0
  37. data/app/views/taverna_player/runs/index.html.erb +40 -0
  38. data/app/views/taverna_player/runs/index.json.jbuilder +1 -0
  39. data/app/views/taverna_player/runs/new.html.erb +56 -0
  40. data/app/views/taverna_player/runs/new.json.jbuilder +1 -0
  41. data/app/views/taverna_player/runs/show.html.erb +29 -0
  42. data/app/views/taverna_player/runs/show.js.erb +25 -0
  43. data/app/views/taverna_player/runs/show.json.jbuilder +25 -0
  44. data/app/views/taverna_player/service_credentials/_form.html.erb +53 -0
  45. data/app/views/taverna_player/service_credentials/edit.html.erb +18 -0
  46. data/app/views/taverna_player/service_credentials/index.html.erb +41 -0
  47. data/app/views/taverna_player/service_credentials/new.html.erb +17 -0
  48. data/app/views/taverna_player/service_credentials/show.html.erb +36 -0
  49. data/config/routes.rb +34 -0
  50. data/db/migrate/20130313105546_create_taverna_player_runs.rb +16 -0
  51. data/db/migrate/20130315163019_create_taverna_player_run_ports.rb +15 -0
  52. data/db/migrate/20130318170744_add_attachment_file_to_taverna_player_run_ports.rb +6 -0
  53. data/db/migrate/20130319183634_create_delayed_jobs.rb +22 -0
  54. data/db/migrate/20130320102600_add_status_message_to_taverna_player_runs.rb +5 -0
  55. data/db/migrate/20130321100110_add_depth_and_metadata_to_taverna_player_run_ports.rb +6 -0
  56. data/db/migrate/20130704095504_add_attachment_results_to_taverna_player_runs.rb +5 -0
  57. data/db/migrate/20130705142704_add_embedded_to_taverna_player_runs.rb +5 -0
  58. data/db/migrate/20130714140911_create_taverna_player_interactions.rb +13 -0
  59. data/db/migrate/20130717083653_add_proxy_to_taverna_player_runs.rb +6 -0
  60. data/db/migrate/20130717155415_add_stop_to_taverna_player_runs.rb +5 -0
  61. data/db/migrate/20130811152840_add_attachment_log_to_taverna_player_runs.rb +5 -0
  62. data/db/migrate/20130811211725_change_taverna_player_runs_state_column.rb +5 -0
  63. data/db/migrate/20130812155839_add_name_to_taverna_player_runs.rb +5 -0
  64. data/db/migrate/20130918135348_create_taverna_player_service_credentials.rb +15 -0
  65. data/db/migrate/20130919154200_add_displayed_to_taverna_player_interactions.rb +5 -0
  66. data/db/migrate/20131007153209_add_job_ref_to_taverna_player_runs.rb +13 -0
  67. data/db/migrate/20131010094537_add_reply_caching_to_taverna_player_interactions.rb +19 -0
  68. data/db/migrate/20131017141514_add_failure_message_to_taverna_player_run.rb +5 -0
  69. data/db/migrate/20131018152940_add_serial_number_to_taverna_player_interactions.rb +5 -0
  70. data/db/migrate/20131018160715_add_parent_run_id_to_taverna_player_runs.rb +5 -0
  71. data/db/migrate/20131102113933_add_page_uri_to_taverna_player_interaction.rb +5 -0
  72. data/db/migrate/20131105115218_remove_proxy_from_taverna_player_runs.rb +11 -0
  73. data/db/migrate/20131105141934_change_taverna_player_interactions_output_value_column_name.rb +5 -0
  74. data/db/migrate/20131112165520_add_user_to_taverna_player_run.rb +5 -0
  75. data/lib/generators/taverna_player/callbacks_generator.rb +25 -0
  76. data/lib/generators/taverna_player/controllers_generator.rb +30 -0
  77. data/lib/generators/taverna_player/install_generator.rb +30 -0
  78. data/lib/generators/taverna_player/job_generator.rb +26 -0
  79. data/lib/generators/taverna_player/models_generator.rb +27 -0
  80. data/lib/generators/taverna_player/renderers_generator.rb +26 -0
  81. data/lib/generators/taverna_player/views_generator.rb +27 -0
  82. data/lib/generators/templates/ReadMe.txt +118 -0
  83. data/lib/generators/templates/callbacks/render_callbacks.rb +56 -0
  84. data/lib/generators/templates/callbacks/worker_callbacks.rb +31 -0
  85. data/lib/generators/templates/controllers/runs_controller.rb +20 -0
  86. data/lib/generators/templates/controllers/service_credentials_controller.rb +20 -0
  87. data/lib/generators/templates/initializer.rb +154 -0
  88. data/lib/generators/templates/models/run.rb +20 -0
  89. data/lib/tasks/delete-cancelled-runs.rake +26 -0
  90. data/lib/tasks/delete-old-embedded-runs.rake +26 -0
  91. data/lib/taverna-player.rb +139 -0
  92. data/lib/taverna_player/concerns/controllers/runs_controller.rb +281 -0
  93. data/lib/taverna_player/concerns/controllers/service_credentials_controller.rb +89 -0
  94. data/lib/taverna_player/concerns/models/run.rb +205 -0
  95. data/lib/taverna_player/engine.rb +23 -0
  96. data/lib/taverna_player/model_proxy.rb +51 -0
  97. data/lib/taverna_player/output_renderer.rb +96 -0
  98. data/lib/taverna_player/render_callbacks.rb +41 -0
  99. data/lib/taverna_player/version.rb +15 -0
  100. data/lib/taverna_player/worker.rb +325 -0
  101. data/script/delayed_job +5 -0
  102. data/script/rails +8 -0
  103. data/taverna_player.gemspec +46 -0
  104. data/test/dummy/Rakefile +7 -0
  105. data/test/dummy/app/assets/javascripts/application.js +16 -0
  106. data/test/dummy/app/assets/stylesheets/application.css +14 -0
  107. data/test/dummy/app/controllers/application_controller.rb +15 -0
  108. data/test/dummy/app/controllers/home_controller.rb +16 -0
  109. data/test/dummy/app/controllers/taverna_player/runs_controller.rb +25 -0
  110. data/test/dummy/app/controllers/taverna_player/service_credentials_controller.rb +25 -0
  111. data/test/dummy/app/controllers/workflows_controller.rb +17 -0
  112. data/test/dummy/app/models/user.rb +15 -0
  113. data/test/dummy/app/models/workflow.rb +32 -0
  114. data/test/dummy/app/views/home/index.html.erb +18 -0
  115. data/test/dummy/app/views/layouts/application.html.erb +43 -0
  116. data/test/dummy/app/views/workflows/index.html.erb +35 -0
  117. data/test/dummy/config.ru +4 -0
  118. data/test/dummy/config/application.rb +58 -0
  119. data/test/dummy/config/boot.rb +10 -0
  120. data/test/dummy/config/database.yml +25 -0
  121. data/test/dummy/config/environment.rb +5 -0
  122. data/test/dummy/config/environments/development.rb +37 -0
  123. data/test/dummy/config/environments/production.rb +67 -0
  124. data/test/dummy/config/environments/test.rb +37 -0
  125. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  126. data/test/dummy/config/initializers/inflections.rb +15 -0
  127. data/test/dummy/config/initializers/mime_types.rb +5 -0
  128. data/test/dummy/config/initializers/secret_token.rb +7 -0
  129. data/test/dummy/config/initializers/session_store.rb +8 -0
  130. data/test/dummy/config/initializers/taverna_player.example.rb +40 -0
  131. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  132. data/test/dummy/config/locales/en.yml +5 -0
  133. data/test/dummy/config/routes.rb +22 -0
  134. data/test/dummy/db/migrate/20130314103555_create_workflows.rb +12 -0
  135. data/test/dummy/db/migrate/20130318141557_create_taverna_player_runs.taverna_player.rb +17 -0
  136. data/test/dummy/db/migrate/20130318141558_create_taverna_player_run_ports.taverna_player.rb +16 -0
  137. data/test/dummy/db/migrate/20130318173013_add_attachment_file_to_taverna_player_run_ports.taverna_player.rb +7 -0
  138. data/test/dummy/db/migrate/20130319183816_create_delayed_jobs.taverna_player.rb +23 -0
  139. data/test/dummy/db/migrate/20130320102635_add_status_message_to_taverna_player_runs.taverna_player.rb +6 -0
  140. data/test/dummy/db/migrate/20130321161859_add_depth_and_metadata_to_taverna_player_run_ports.taverna_player.rb +7 -0
  141. data/test/dummy/db/migrate/20130704100146_add_attachment_results_to_taverna_player_runs.taverna_player.rb +6 -0
  142. data/test/dummy/db/migrate/20130705142816_add_embedded_to_taverna_player_runs.taverna_player.rb +6 -0
  143. data/test/dummy/db/migrate/20130714142144_create_taverna_player_interactions.taverna_player.rb +14 -0
  144. data/test/dummy/db/migrate/20130717084809_add_proxy_to_taverna_player_runs.taverna_player.rb +7 -0
  145. data/test/dummy/db/migrate/20130718102707_add_stop_to_taverna_player_runs.taverna_player.rb +6 -0
  146. data/test/dummy/db/migrate/20130811204449_add_attachment_log_to_taverna_player_runs.taverna_player.rb +6 -0
  147. data/test/dummy/db/migrate/20130811212709_change_taverna_player_runs_state_column.taverna_player.rb +6 -0
  148. data/test/dummy/db/migrate/20130812161152_add_name_to_taverna_player_runs.taverna_player.rb +6 -0
  149. data/test/dummy/db/migrate/20130918155525_create_taverna_player_service_credentials.taverna_player.rb +16 -0
  150. data/test/dummy/db/migrate/20130919155202_add_displayed_to_taverna_player_interactions.taverna_player.rb +6 -0
  151. data/test/dummy/db/migrate/20131007153659_add_job_ref_to_taverna_player_runs.taverna_player.rb +14 -0
  152. data/test/dummy/db/migrate/20131016123941_add_reply_caching_to_taverna_player_interactions.taverna_player.rb +20 -0
  153. data/test/dummy/db/migrate/20131017141614_add_failure_message_to_taverna_player_run.taverna_player.rb +6 -0
  154. data/test/dummy/db/migrate/20131018153316_add_serial_number_to_taverna_player_interactions.taverna_player.rb +6 -0
  155. data/test/dummy/db/migrate/20131018164614_add_parent_run_id_to_taverna_player_runs.taverna_player.rb +6 -0
  156. data/test/dummy/db/migrate/20131102114343_add_page_uri_to_taverna_player_interaction.taverna_player.rb +6 -0
  157. data/test/dummy/db/migrate/20131105115724_remove_proxy_from_taverna_player_runs.taverna_player.rb +12 -0
  158. data/test/dummy/db/migrate/20131105142417_change_taverna_player_interactions_output_value_column_name.taverna_player.rb +6 -0
  159. data/test/dummy/db/migrate/20131112165815_add_user_to_taverna_player_run.taverna_player.rb +6 -0
  160. data/test/dummy/db/migrate/20131114130937_create_users.rb +10 -0
  161. data/test/dummy/db/schema.rb +123 -0
  162. data/test/dummy/lib/callbacks.rb +35 -0
  163. data/test/dummy/log/.gitkeep +0 -0
  164. data/test/dummy/public/404.html +26 -0
  165. data/test/dummy/public/422.html +26 -0
  166. data/test/dummy/public/500.html +25 -0
  167. data/test/dummy/public/favicon.ico +0 -0
  168. data/test/dummy/script/delayed_job +5 -0
  169. data/test/dummy/script/rails +6 -0
  170. data/test/dummy/test/functional/home_controller_test.rb +28 -0
  171. data/test/dummy/test/functional/workflows_controller_test.rb +21 -0
  172. data/test/fixtures/files/crassostrea_gigas.csv +737 -0
  173. data/test/fixtures/taverna_player/interactions.yml +32 -0
  174. data/test/fixtures/taverna_player/run_ports.yml +54 -0
  175. data/test/fixtures/taverna_player/runs.yml +69 -0
  176. data/test/fixtures/taverna_player/service_credentials.yml +25 -0
  177. data/test/fixtures/users.yml +16 -0
  178. data/test/fixtures/workflows.yml +32 -0
  179. data/test/functional/taverna_player/runs_controller_test.rb +316 -0
  180. data/test/functional/taverna_player/service_credentials_controller_test.rb +99 -0
  181. data/test/taverna_player_test.rb +25 -0
  182. data/test/test_helper.rb +33 -0
  183. data/test/unit/helpers/taverna_player/application_helper_test.rb +70 -0
  184. data/test/unit/helpers/taverna_player/runs_helper_test.rb +45 -0
  185. data/test/unit/taverna_player/interaction_test.rb +47 -0
  186. data/test/unit/taverna_player/run_port_test.rb +309 -0
  187. data/test/unit/taverna_player/run_test.rb +196 -0
  188. data/test/unit/taverna_player/service_credential_test.rb +64 -0
  189. data/test/workflows/hello.t2flow +164 -0
  190. data/test/workflows/list_with_errors.t2flow +107 -0
  191. data/test/workflows/pass_through.t2flow +12 -0
  192. metadata +539 -0
@@ -0,0 +1,23 @@
1
+ #------------------------------------------------------------------------------
2
+ # Copyright (c) 2013 The University of Manchester, UK.
3
+ #
4
+ # BSD Licenced. See LICENCE.rdoc for details.
5
+ #
6
+ # Taverna Player was developed in the BioVeL project, funded by the European
7
+ # Commission 7th Framework Programme (FP7), through grant agreement
8
+ # number 283359.
9
+ #
10
+ # Author: Robert Haines
11
+ #------------------------------------------------------------------------------
12
+
13
+ module TavernaPlayer
14
+ class Engine < ::Rails::Engine
15
+ isolate_namespace TavernaPlayer
16
+
17
+ initializer "taverna_player.action_controller" do
18
+ ActiveSupport.on_load :action_controller do
19
+ helper TavernaPlayer::ApplicationHelper
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,51 @@
1
+ #------------------------------------------------------------------------------
2
+ # Copyright (c) 2013 The University of Manchester, UK.
3
+ #
4
+ # BSD Licenced. See LICENCE.rdoc for details.
5
+ #
6
+ # Taverna Player was developed in the BioVeL project, funded by the European
7
+ # Commission 7th Framework Programme (FP7), through grant agreement
8
+ # number 283359.
9
+ #
10
+ # Author: Robert Haines
11
+ #------------------------------------------------------------------------------
12
+
13
+ module TavernaPlayer
14
+ class ModelProxy
15
+ attr_reader :class_name
16
+
17
+ def initialize(class_name, method_names = [])
18
+ if class_name.is_a?(String)
19
+ begin
20
+ @class_name = Object.const_get(class_name)
21
+ rescue NameError
22
+ @class_name = class_name.constantize
23
+ end
24
+ end
25
+
26
+ method_names.each do |name|
27
+ add_method(name.to_sym)
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def add_method(name)
34
+ setter = "#{name}_method_name=".to_sym
35
+ mapper = name
36
+
37
+ (class << self; self; end).instance_eval do
38
+ # Define the method to use the mapped method on the object.
39
+ define_method name do |object|
40
+ mapper.nil? ? nil : object.send(mapper)
41
+ end
42
+
43
+ # Define the method used to set the mapped method's name.
44
+ define_method setter do |method_name|
45
+ mapper = method_name.nil? ? nil : method_name.to_sym
46
+ end
47
+ end
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,96 @@
1
+ #------------------------------------------------------------------------------
2
+ # Copyright (c) 2013 The University of Manchester, UK.
3
+ #
4
+ # BSD Licenced. See LICENCE.rdoc for details.
5
+ #
6
+ # Taverna Player was developed in the BioVeL project, funded by the European
7
+ # Commission 7th Framework Programme (FP7), through grant agreement
8
+ # number 283359.
9
+ #
10
+ # Author: Robert Haines
11
+ #------------------------------------------------------------------------------
12
+
13
+ module TavernaPlayer
14
+
15
+ # This class manages the rendering of many different output types that could
16
+ # be produced by a workflow. It can be configured with new types and the
17
+ # example renderers for each type can also be changed. An example of how to
18
+ # set it up can be found in the taverna_player initializer.
19
+ #
20
+ # Each renderer has all of the ActionView::Helpers (such as link_to, tag,
21
+ # etc) available to them.
22
+ class OutputRenderer
23
+ # The renderers are all called in the scope of this class so we include
24
+ # ActionView::Helpers here so that they are all available to them.
25
+ include ActionView::Helpers
26
+
27
+ # :stopdoc:
28
+ # Taverna Workflow error MIME type
29
+ TAVERNA_ERROR_TYPE = MIME::Type.new("application/x-error")
30
+
31
+ # Empty file MIME types as used in older and new versions of "file".
32
+ EMPTY_FILE_OLD = MIME::Type.new("application/x-empty")
33
+ EMPTY_FILE_NEW = MIME::Type.new("inode/x-empty")
34
+
35
+ def initialize
36
+ @hash = Hash.new
37
+ MIME::Types.add(TAVERNA_ERROR_TYPE, EMPTY_FILE_OLD, EMPTY_FILE_NEW)
38
+ end
39
+ # :startdoc:
40
+
41
+ # :call-seq:
42
+ # add(mimetype, renderer, default = false)
43
+ #
44
+ # Add a renderer method for the specified MIME type. If you would like the
45
+ # renderer to be the default for that particular media type then pass true
46
+ # in the final parameter - the media type is the part of a MIME type before
47
+ # the slash (/), e.g. "text" or "image". The MIME type should be specified
48
+ # as a string.
49
+ def add(mimetype, method, default = false)
50
+ type = MIME::Types[mimetype].first
51
+
52
+ @hash[type.media_type] ||= {}
53
+ @hash[type.media_type][type.sub_type] = method
54
+ @hash[type.media_type][:default] = method if default
55
+ end
56
+
57
+ # :call-seq:
58
+ # type_default(media_type, renderer)
59
+ #
60
+ # This is another way of setting the default renderer method for a whole
61
+ # media type (see the add method for more details).
62
+ def type_default(media_type, method)
63
+ @hash[media_type] ||= {}
64
+ @hash[media_type][:default] = method
65
+ end
66
+
67
+ # :call-seq:
68
+ # default(method)
69
+ #
70
+ # Set a default renderer for any MIME type not specifically set. This
71
+ # could be used to supply a piece of text and a download link for any type
72
+ # that cannot normally be shown in the browser inline.
73
+ def default(method)
74
+ @hash[:default] = method
75
+ end
76
+
77
+ # :call-seq:
78
+ # render(content, mimetype) -> markup
79
+ #
80
+ # This is the method that calls the correct renderer for the given content
81
+ # with the given MIME type and returns the resultant rendering.
82
+ def render(content, mimetype)
83
+ type = MIME::Types[mimetype].first
84
+
85
+ renderer = @hash[type.media_type][type.sub_type] ||
86
+ @hash[type.media_type][:default] || @hash[:default]
87
+
88
+ if renderer.is_a? Proc
89
+ renderer.call(content, type)
90
+ else
91
+ method(renderer).call(content, type)
92
+ end
93
+ end
94
+
95
+ end
96
+ end
@@ -0,0 +1,41 @@
1
+ #------------------------------------------------------------------------------
2
+ # Copyright (c) 2013 The University of Manchester, UK.
3
+ #
4
+ # BSD Licenced. See LICENCE.rdoc for details.
5
+ #
6
+ # Taverna Player was developed in the BioVeL project, funded by the European
7
+ # Commission 7th Framework Programme (FP7), through grant agreement
8
+ # number 283359.
9
+ #
10
+ # Author: Robert Haines
11
+ #------------------------------------------------------------------------------
12
+
13
+ def format_text_tp_default(content, type)
14
+ content = CodeRay.scan(content, :text).div(:css => :class)
15
+ auto_link(content, :html => { :target => '_blank' }, :sanitize => false)
16
+ end
17
+
18
+ def format_xml_tp_default(content, type)
19
+ out = String.new
20
+ REXML::Document.new(content).write(out, 1)
21
+ CodeRay.scan(out, :xml).div(:css => :class, :line_numbers => :table)
22
+ end
23
+
24
+ def show_image_tp_default(content, type)
25
+ # Can't use image_tag() here because the image doesn't really exist (it's in
26
+ # a zip file, really) and this confuses the Rails asset pipeline.
27
+ tag("img", :src => content)
28
+ end
29
+
30
+ def workflow_error_tp_default(content, type)
31
+ link_to("This output is a workflow error.", content)
32
+ end
33
+
34
+ def cannot_inline_tp_default(content, type)
35
+ "Sorry but we cannot show this type of content in the browser. Please " +
36
+ link_to("download it", content) + " to view it on your local machine."
37
+ end
38
+
39
+ def empty_tp_default(content, type)
40
+ "<div>&lt;empty output&gt;</div>"
41
+ end
@@ -0,0 +1,15 @@
1
+ #------------------------------------------------------------------------------
2
+ # Copyright (c) 2013 The University of Manchester, UK.
3
+ #
4
+ # BSD Licenced. See LICENCE.rdoc for details.
5
+ #
6
+ # Taverna Player was developed in the BioVeL project, funded by the European
7
+ # Commission 7th Framework Programme (FP7), through grant agreement
8
+ # number 283359.
9
+ #
10
+ # Author: Robert Haines
11
+ #------------------------------------------------------------------------------
12
+
13
+ module TavernaPlayer
14
+ VERSION = "0.1.0"
15
+ end
@@ -0,0 +1,325 @@
1
+ #------------------------------------------------------------------------------
2
+ # Copyright (c) 2013 The University of Manchester, UK.
3
+ #
4
+ # BSD Licenced. See LICENCE.rdoc for details.
5
+ #
6
+ # Taverna Player was developed in the BioVeL project, funded by the European
7
+ # Commission 7th Framework Programme (FP7), through grant agreement
8
+ # number 283359.
9
+ #
10
+ # Author: Robert Haines
11
+ #------------------------------------------------------------------------------
12
+
13
+ module TavernaPlayer
14
+ class Worker
15
+
16
+ # How to get the interaction presentation frame out of the interaction page.
17
+ INTERACTION_REGEX = /document\.getElementById\(\'presentationFrame\'\)\.src = \"(.+)\";/
18
+
19
+ def initialize(run)
20
+ @run = run
21
+ @workflow = TavernaPlayer.workflow_proxy.class_name.find(@run.workflow_id)
22
+ end
23
+
24
+ # This tells delayed_job to only try and complete each run once.
25
+ def max_attempts
26
+ 1
27
+ end
28
+
29
+ def perform
30
+ unless TavernaPlayer.pre_run_callback.nil?
31
+ status_message "Running pre-run tasks"
32
+ run_callback(TavernaPlayer.pre_run_callback, @run)
33
+ end
34
+
35
+ status_message "Connecting to Taverna Server"
36
+
37
+ server_uri = URI.parse(TavernaPlayer.server_address)
38
+ credentials = T2Server::HttpBasic.new(TavernaPlayer.server_username,
39
+ TavernaPlayer.server_password)
40
+ conn_params = TavernaPlayer.server_connection
41
+
42
+ begin
43
+ server = T2Server::Server.new(server_uri, conn_params)
44
+ wkf = File.read(TavernaPlayer.workflow_proxy.file(@workflow))
45
+
46
+ # Try and create the run bearing in mind that the server might be at
47
+ # the limit of runs that it can hold at once.
48
+ begin
49
+ run = server.create_run(wkf, credentials)
50
+ rescue T2Server::ServerAtCapacityError
51
+ status_message "Server full - please wait; run will start soon"
52
+
53
+ if cancelled?
54
+ cancel
55
+ return
56
+ end
57
+
58
+ sleep(TavernaPlayer.server_retry_interval)
59
+ retry
60
+ end
61
+
62
+ status_message "Initializing new workflow run"
63
+
64
+ @run.run_id = run.id
65
+ @run.state = run.status
66
+ @run.create_time = run.create_time
67
+ @run.save
68
+
69
+ unless @run.inputs.size == 0
70
+ status_message "Uploading run inputs"
71
+ @run.inputs.each do |input|
72
+ unless input.file.blank?
73
+ run.input_port(input.name).file = input.file.path
74
+ else
75
+ run.input_port(input.name).value = input.value
76
+ end
77
+ end
78
+ end
79
+
80
+ # Just add in all service credentials right now
81
+ TavernaPlayer::ServiceCredential.all.each do |cred|
82
+ run.add_password_credential(cred.uri, cred.login, cred.password)
83
+ end
84
+
85
+ status_message "Starting run"
86
+ run.name = @run.name
87
+
88
+ # Try and start the run bearing in mind that the server might be at
89
+ # the limit of runs that it can run at once.
90
+ while !run.start
91
+ status_message "Server busy - please wait; run will start soon"
92
+
93
+ if cancelled?
94
+ cancel(run)
95
+ return
96
+ end
97
+
98
+ sleep(TavernaPlayer.server_retry_interval)
99
+ end
100
+
101
+ @run.state = run.status
102
+ @run.start_time = run.start_time
103
+ @run.save
104
+
105
+ status_message "Running"
106
+ until run.finished?
107
+ sleep(TavernaPlayer.server_poll_interval)
108
+ waiting = false
109
+
110
+ if cancelled?
111
+ cancel(run)
112
+ return
113
+ end
114
+
115
+ run.notifications(:requests).each do |note|
116
+ if @run.has_parent?
117
+ next if note.has_reply?
118
+ int = Interaction.find_by_run_id_and_serial(@run.parent_id, note.serial)
119
+ new_int = Interaction.find_or_initialize_by_run_id_and_unique_id_and_serial(@run.id, note.id, note.serial)
120
+ if new_int.new_record?
121
+ note.reply(int.feed_reply, int.data)
122
+ new_int.displayed = true
123
+ new_int.replied = true
124
+ new_int.feed_reply = int.feed_reply
125
+ new_int.data = int.data
126
+ new_int.save
127
+ end
128
+ else
129
+ waiting = true unless note.has_reply?
130
+ int = Interaction.find_or_initialize_by_run_id_and_unique_id_and_serial(@run.id, note.id, note.serial)
131
+
132
+ # Need to catch this here in case some other process has replied.
133
+ if note.has_reply? && !int.replied?
134
+ int.replied = true
135
+ int.save
136
+ end
137
+
138
+ unless int.replied?
139
+ if int.page.blank?
140
+ page = server.read(note.uri, "text/html", credentials)
141
+
142
+ INTERACTION_REGEX.match(page) do
143
+ page_uri = $1
144
+
145
+ if page_uri.starts_with?(server.uri.to_s)
146
+ page = server.read(URI.parse(page_uri), "text/html", credentials)
147
+ int.page = page.gsub("#{run.interactions_uri.to_s}/pmrpc.js",
148
+ "/assets/taverna_player/application.js")
149
+ else
150
+ int.page_uri = page_uri
151
+ end
152
+ end
153
+ end
154
+
155
+ if int.data.blank?
156
+ int.data = note.input_data.force_encoding("UTF-8")
157
+ end
158
+
159
+ if !int.feed_reply.blank? && !int.data.blank?
160
+ note.reply(int.feed_reply, int.data)
161
+
162
+ int.replied = true
163
+ end
164
+
165
+ int.save
166
+ end
167
+ end
168
+ end
169
+
170
+ status_message(waiting ? "Waiting for user input" : "Running")
171
+ end
172
+
173
+ status_message "Gathering run outputs and log"
174
+ download_outputs(run)
175
+ download_log(run)
176
+
177
+ @run.outputs = process_outputs(run)
178
+ @run.finish_time = run.finish_time
179
+ @run.save
180
+
181
+ run.delete
182
+ rescue => exception
183
+ begin
184
+ unless run.nil?
185
+ download_log(run)
186
+ run.delete
187
+ end
188
+ rescue
189
+ # Try and grab the log then delete the run from Taverna Server here,
190
+ # but at this point we don't care if we fail...
191
+ end
192
+
193
+ unless TavernaPlayer.run_failed_callback.nil?
194
+ status_message "Running post-failure tasks"
195
+ run_callback(TavernaPlayer.run_failed_callback, @run)
196
+ end
197
+
198
+ backtrace = exception.backtrace.join("\n")
199
+ @run.failure_message = "#{exception.message}\n#{backtrace}"
200
+
201
+ @run.state = :failed
202
+ @run.finish_time = Time.now
203
+ status_message "Failed"
204
+ return
205
+ end
206
+
207
+ unless TavernaPlayer.post_run_callback.nil?
208
+ status_message "Running post-run tasks"
209
+ run_callback(TavernaPlayer.post_run_callback, @run)
210
+ end
211
+
212
+ @run.state = :finished
213
+ status_message "Finished"
214
+ end
215
+
216
+ private
217
+
218
+ def run_callback(callback, *params)
219
+ if callback.is_a? Proc
220
+ callback.call(*params)
221
+ else
222
+ method(callback).call(*params)
223
+ end
224
+ end
225
+
226
+ def download_log(run)
227
+ Dir.mktmpdir(run.id, Rails.root.join("tmp")) do |tmp_dir|
228
+ tmp_file_name = File.join(tmp_dir, "log.txt")
229
+ begin
230
+ run.log(tmp_file_name)
231
+ @run.log = File.new(tmp_file_name)
232
+ @run.save
233
+ rescue T2Server::AttributeNotFoundError
234
+ # We don't care if there's no log but we do want to catch the error!
235
+ end
236
+ end
237
+ end
238
+
239
+ def download_outputs(run)
240
+ Dir.mktmpdir(run.id, Rails.root.join("tmp")) do |tmp_dir|
241
+ tmp_file_name = File.join(tmp_dir, "all.zip")
242
+ run.zip_output(tmp_file_name)
243
+ @run.results = File.new(tmp_file_name)
244
+ @run.save
245
+ end
246
+ end
247
+
248
+ def process_outputs(run)
249
+ outputs = []
250
+
251
+ Dir.mktmpdir(run.id, Rails.root.join("tmp")) do |tmp_dir|
252
+ run.output_ports.each_value do |port|
253
+ output = TavernaPlayer::RunPort::Output.new(:name => port.name,
254
+ :depth => port.depth)
255
+
256
+ tmp_file_name = File.join(tmp_dir, port.name)
257
+
258
+ if port.depth == 0
259
+ Zip::ZipFile.open(@run.results.path) do |zip|
260
+ if port.type =~ /text/
261
+ output.value = zip.read(port.name)
262
+ else
263
+ port_name = port.error? ? "#{port.name}.error" : port.name
264
+ output.file = singleton_output(port_name, tmp_file_name, zip)
265
+ end
266
+ end
267
+ else
268
+ # TODO: Need to rework this so it's not just re-downloading the
269
+ # whole port again. This is the quickest way right now though.
270
+ port.zip("#{tmp_file_name}.zip")
271
+ output.file = File.new("#{tmp_file_name}.zip")
272
+ end
273
+
274
+ output.metadata = {
275
+ :size => port.size,
276
+ :type => port.type
277
+ }
278
+
279
+ outputs << output
280
+ end
281
+ end
282
+
283
+ outputs
284
+ end
285
+
286
+ def singleton_output(name, tmp_file, zip)
287
+ File.open(tmp_file, "wb") do |file|
288
+ file.write zip.read(name)
289
+ end
290
+
291
+ File.new(tmp_file)
292
+ end
293
+
294
+ def status_message(message)
295
+ @run.status_message = message
296
+ @run.save!
297
+ end
298
+
299
+ def cancelled?
300
+ # Need to poll for updates as the run instance may have been
301
+ # changed in the Rails app.
302
+ @run.reload
303
+ @run.stop
304
+ end
305
+
306
+ def cancel(run = nil)
307
+ status_message "Cancelling"
308
+
309
+ unless run.nil?
310
+ download_log(run)
311
+ run.delete
312
+ end
313
+
314
+ unless TavernaPlayer.run_cancelled_callback.nil?
315
+ status_message "Running post-cancel tasks"
316
+ run_callback(TavernaPlayer.run_cancelled_callback, @run)
317
+ end
318
+
319
+ @run.state = :cancelled
320
+ @run.finish_time = Time.now
321
+ status_message "Cancelled"
322
+ end
323
+
324
+ end
325
+ end