taverna-player 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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,281 @@
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
+ module Concerns
15
+ module Controllers
16
+ module RunsController
17
+
18
+ extend ActiveSupport::Concern
19
+
20
+ included do
21
+ respond_to :html, :json, :js
22
+
23
+ before_filter :find_runs, :only => [ :index ]
24
+ before_filter :find_run, :except => [ :index, :new, :create ]
25
+ before_filter :find_workflow, :only => [ :new ]
26
+ before_filter :setup_new_run, :only => :new
27
+ before_filter :set_run_user, :only => :create
28
+ before_filter :filter_update_parameters, :only => :update
29
+ before_filter :find_interaction, :only => [ :read_interaction, :write_interaction ]
30
+
31
+ layout :choose_layout
32
+
33
+ private
34
+
35
+ def find_runs
36
+ select = { :embedded => false }
37
+ select[:workflow_id] = params[:workflow_id] if params[:workflow_id]
38
+ @runs = Run.where(select).all
39
+ end
40
+
41
+ def find_run
42
+ @run = Run.find(params[:id])
43
+ end
44
+
45
+ def find_workflow
46
+ @workflow = TavernaPlayer.workflow_proxy.class_name.find(params[:workflow_id])
47
+ end
48
+
49
+ def setup_new_run
50
+ @run = Run.new(:workflow_id => @workflow.id)
51
+ @run.embedded = true if params[:embedded] == "true"
52
+ end
53
+
54
+ def set_run_user
55
+ return if params[:run][:embedded] == "true" || TavernaPlayer.user_proxy.nil?
56
+
57
+ unless TavernaPlayer.current_user_callback.blank?
58
+ user = method(TavernaPlayer.current_user_callback).call
59
+ params[:run][:user_id] = user.id unless user.nil?
60
+ end
61
+ end
62
+
63
+ def filter_update_parameters
64
+ name = params[:run][:name]
65
+ @update_parameters = { :name => name } unless name.blank?
66
+ end
67
+
68
+ def find_interaction
69
+ @interaction = Interaction.find_by_unique_id(params[:int_id])
70
+ end
71
+
72
+ # Read the data from the results zip file.
73
+ def read_from_zip(file)
74
+ Zip::ZipFile.open(@run.results.path) do |zip|
75
+ zip.read(file)
76
+ end
77
+ end
78
+
79
+ # This is here because of Taverna's infinitely deep output ports :-(
80
+ def recurse_into_lists(list, indexes)
81
+ return list if indexes.empty? || !list.is_a?(Array)
82
+ i = indexes.shift
83
+ return recurse_into_lists(list[i], indexes)
84
+ end
85
+
86
+ # Choose a layout for the page depending on action and embedded status.
87
+ def choose_layout
88
+ if (action_name == "new" || action_name == "show") && @run.embedded?
89
+ "taverna_player/embedded"
90
+ else
91
+ ApplicationController.new.send(:_layout).virtual_path
92
+ end
93
+ end
94
+
95
+ end # included
96
+
97
+ # GET /runs
98
+ def index
99
+
100
+ end
101
+
102
+ # GET /runs/1
103
+ def show
104
+ if @run.running?
105
+ @interaction = Interaction.find_by_run_id_and_replied(@run.id, false)
106
+ unless @interaction.nil?
107
+ unless @interaction.displayed
108
+ @new_interaction = true
109
+ @interaction.displayed = true
110
+ @interaction.save
111
+ end
112
+ end
113
+ end
114
+
115
+ respond_with(@run) do |format|
116
+ # Render show.{html|js}.erb unless the run is embedded.
117
+ format.any(:html, :js) do
118
+ render "taverna_player/runs/embedded/show" if @run.embedded
119
+ end
120
+ end
121
+ end
122
+
123
+ # GET /runs/new
124
+ def new
125
+ respond_with(@run) do |format|
126
+ # Render new.html.erb unless the run is embedded.
127
+ format.html do
128
+ render "taverna_player/runs/embedded/new" if @run.embedded
129
+ end
130
+ end
131
+ end
132
+
133
+ # POST /runs
134
+ def create
135
+ @run = Run.new(params[:run])
136
+ if @run.save
137
+ flash[:notice] = "Run was successfully created."
138
+ end
139
+
140
+ respond_with(@run, :status => :created, :location => @run)
141
+ end
142
+
143
+ # PUT /runs/1
144
+ def update
145
+ @run.update_attributes(@update_parameters)
146
+
147
+ respond_with(@run)
148
+ end
149
+
150
+ # DELETE /runs/1
151
+ def destroy
152
+ if @run.destroy
153
+ flash[:notice] = "Run was deleted."
154
+ respond_with(@run)
155
+ else
156
+ flash[:error] = "Run must be cancelled before deletion."
157
+ respond_with(@run, :nothing => true, :status => :forbidden) do |format|
158
+ format.html { redirect_to :back }
159
+ end
160
+ end
161
+ end
162
+
163
+ # PUT /runs/1/cancel
164
+ def cancel
165
+ @run.cancel unless @run.complete?
166
+
167
+ respond_with(@run, :action => :show) do |format|
168
+ format.html do
169
+ if @run.embedded?
170
+ redirect_to view_context.new_embedded_run_path(@run)
171
+ else
172
+ redirect_to :back
173
+ end
174
+ end
175
+ end
176
+ end
177
+
178
+ # GET /runs/1/download/log
179
+ def download_log
180
+ send_file @run.log.path, :type => "text/plain",
181
+ :filename => "#{@run.name}-log.txt"
182
+ end
183
+
184
+ # GET /runs/1/download/results
185
+ def download_results
186
+ send_file @run.results.path, :type => "application/zip",
187
+ :filename => "#{@run.name}-all-results.zip"
188
+ end
189
+
190
+ # GET /runs/1/download/output/:port
191
+ def download_output
192
+ output = RunPort::Output.find_by_run_id_and_name(@run.id, params[:port])
193
+
194
+ # If there is no such output port then return a 404.
195
+ raise ActionController::RoutingError.new('Not Found') if output.nil?
196
+
197
+ if output.file.blank?
198
+ send_data output.value, :type => "text/plain",
199
+ :filename => "#{@run.name}-#{output.name}.txt"
200
+ else
201
+ send_file output.file.path, :type => output.file.content_type,
202
+ :filename => "#{@run.name}-#{output.file_file_name}"
203
+ end
204
+ end
205
+
206
+ # GET /runs/1/input/*
207
+ def input
208
+ input = RunPort::Input.find_by_run_id_and_name(@run.id, params[:port])
209
+
210
+ # If there is no such input port then return a 404.
211
+ raise ActionController::RoutingError.new('Not Found') if input.nil?
212
+
213
+ if input.file.blank?
214
+ send_data input.value, :disposition => "inline"
215
+ else
216
+ send_file input.file.path, :disposition => "inline"
217
+ end
218
+ end
219
+
220
+ # GET /runs/1/output/*
221
+ def output
222
+ # We need to parse out the path into a list of numbers here so we have
223
+ # a list of indices into the file structure.
224
+ path = []
225
+ unless params[:path].nil?
226
+ path = params[:path].split("/").map { |p| p.to_i }
227
+ end
228
+
229
+ output = RunPort::Output.find_by_run_id_and_name(@run.id, params[:port])
230
+
231
+ # If there is no such output port or the path is the wrong depth then
232
+ # return a 404.
233
+ if output.nil? || path.length != output.depth
234
+ raise ActionController::RoutingError.new('Not Found')
235
+ end
236
+
237
+ # A singleton should just return the value (if it's small enough) or the
238
+ # file if it's bigger. If it's a value in the database then it'll always
239
+ # be a text value, although not necessarily "plain".
240
+ if output.depth == 0 && !output.value.blank?
241
+ send_data output.value, :disposition => "inline",
242
+ :type => output.metadata[:type]
243
+ else
244
+ # We need to rebuild the path indices into a string here (and can't
245
+ # re-use the params[:path] variable directly) because files are
246
+ # indexed from one in the zip we get back from Server, not zero.
247
+ path_s = path.map { |p| p += 1 }.join("/")
248
+ file = path_s.blank? ? "#{output.name}" : "#{output.name}/#{path_s}"
249
+ type = recurse_into_lists(output.metadata[:type], path)
250
+
251
+ # If it's an error, then we need to further hack the file path and
252
+ # content type.
253
+ if type == "application/x-error"
254
+ file += ".error"
255
+ type = "text/plain"
256
+ end
257
+
258
+ send_data read_from_zip(file), :type => type,
259
+ :disposition => "inline"
260
+ end
261
+ end
262
+
263
+ # GET /runs/1/interaction/:int_id
264
+ def read_interaction
265
+ send_data @interaction.page, :type => "text/html",
266
+ :disposition => "inline"
267
+ end
268
+
269
+ # POST /runs/1/interaction/:int_id
270
+ def write_interaction
271
+ @interaction.data = request.body.read
272
+ @interaction.feed_reply = request.headers["X-Taverna-Interaction-Reply"]
273
+ @interaction.save
274
+
275
+ render :nothing => true, :status => 201
276
+ end
277
+
278
+ end
279
+ end
280
+ end
281
+ end
@@ -0,0 +1,89 @@
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
+ module Concerns
15
+ module Controllers
16
+ module ServiceCredentialsController
17
+
18
+ extend ActiveSupport::Concern
19
+
20
+ included do
21
+ respond_to :html
22
+
23
+ before_filter :find_creds, :only => [ :index ]
24
+ before_filter :find_cred, :except => [ :index, :new, :create ]
25
+
26
+ private
27
+
28
+ def find_creds
29
+ @service_credentials = ServiceCredential.all
30
+ end
31
+
32
+ def find_cred
33
+ @service_credential = ServiceCredential.find(params[:id])
34
+ end
35
+ end
36
+
37
+ # GET /service_credentials
38
+ def index
39
+
40
+ end
41
+
42
+ # GET /service_credentials/1
43
+ def show
44
+
45
+ end
46
+
47
+ # GET /service_credentials/new
48
+ def new
49
+ @service_credential = ServiceCredential.new
50
+ end
51
+
52
+ # GET /service_credentials/1/edit
53
+ def edit
54
+
55
+ end
56
+
57
+ # POST /service_credentials
58
+ def create
59
+ @service_credential = ServiceCredential.new(params[:service_credential])
60
+
61
+ if @service_credential.save
62
+ flash[:notice] = "Service credential was successfully created."
63
+ end
64
+
65
+ respond_with(@service_credential)
66
+ end
67
+
68
+ # PUT /service_credentials/1
69
+ def update
70
+ if @service_credential.update_attributes(params[:service_credential])
71
+ flash[:notice] = "Service credential was successfully updated."
72
+ end
73
+
74
+ respond_with(@service_credential)
75
+ end
76
+
77
+ # DELETE /service_credentials/1
78
+ def destroy
79
+ if @service_credential.destroy
80
+ flash[:notice] = "Service credential was deleted."
81
+ end
82
+
83
+ respond_with(@service_credential)
84
+ end
85
+
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,205 @@
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
+ module Concerns
15
+ module Models
16
+ module Run
17
+
18
+ extend ActiveSupport::Concern
19
+
20
+ included do
21
+ attr_accessible :create_time, :delayed_job, :embedded, :finish_time,
22
+ :inputs_attributes, :log, :name, :parent_id, :results, :run_id,
23
+ :start_time, :status_message, :user_id, :workflow_id
24
+
25
+ # Each run is spawned from a workflow. This provides the link to the
26
+ # workflow model in the parent app, whatever it calls its model.
27
+ belongs_to :workflow, :class_name => TavernaPlayer.workflow_proxy.class_name.to_s
28
+
29
+ unless TavernaPlayer.user_proxy.nil?
30
+ belongs_to :user, :class_name => TavernaPlayer.user_proxy.class_name.to_s
31
+ end
32
+
33
+ has_many :inputs, :class_name => "TavernaPlayer::RunPort::Input",
34
+ :dependent => :destroy
35
+ has_many :outputs, :class_name => "TavernaPlayer::RunPort::Output",
36
+ :dependent => :destroy
37
+ has_many :interactions, :class_name => "TavernaPlayer::Interaction",
38
+ :dependent => :destroy
39
+ belongs_to :delayed_job, :class_name => "::Delayed::Job"
40
+
41
+ # A run can have children, which are runs.
42
+ # A run can have a parent, which is another run.
43
+ has_many :children, :class_name => "TavernaPlayer::Run",
44
+ :foreign_key => "parent_id", :dependent => :nullify
45
+ belongs_to :parent, :class_name => "TavernaPlayer::Run"
46
+
47
+ accepts_nested_attributes_for :inputs
48
+
49
+ STATES = ["pending", "initialized", "running", "finished", "cancelled", "failed"]
50
+
51
+ validates :workflow_id, :presence => true
52
+ validates :name, :presence => true
53
+
54
+ # There is a :cancelled state but it can only be set if the run has
55
+ # previously had its stop flag set. This is to avoid race conditions.
56
+ # If we used a state to tell the delayed job worker to cancel a run
57
+ # it could be overwritten when the worker itself moves the run
58
+ # between states, thus losing the cancel request from the user.
59
+ validates :saved_state, :inclusion => { :in => STATES }
60
+ validates :stop, :presence => true, :if => :cancelled?
61
+
62
+ # A parent must have an "older" run id than its children. This only
63
+ # needs to be checked on update because on create we don't have an
64
+ # id for ourself.
65
+ validates :parent_id, :numericality => { :less_than => :id,
66
+ :message => "Parents must have lower ids than children" },
67
+ :allow_nil => true, :on => :update
68
+
69
+ has_attached_file :log,
70
+ :path => File.join(TavernaPlayer.file_store, ":class/:attachment/:id/:filename"),
71
+ :url => "/runs/:id/download/log",
72
+ :default_url => ""
73
+
74
+ has_attached_file :results,
75
+ :path => File.join(TavernaPlayer.file_store, ":class/:attachment/:id/:filename"),
76
+ :url => "/runs/:id/download/results",
77
+ :default_url => ""
78
+
79
+ after_initialize :initialize_child_run, :if => "new_record? && has_parent?"
80
+ after_create :populate_child_inputs, :if => :has_parent?
81
+ after_create :enqueue
82
+ before_destroy :complete?
83
+
84
+ private
85
+
86
+ # A child run MUST have the same workflow as its parent.
87
+ def initialize_child_run
88
+ self.workflow = parent.workflow
89
+ end
90
+
91
+ # For each input on the parent run, make sure we have an equivalent
92
+ # on the child. Copy the values/files of inputs that are missing.
93
+ def populate_child_inputs
94
+ parent.inputs.each do |i|
95
+ input = TavernaPlayer::RunPort::Input.find_or_initialize_by_run_id_and_name(id, i.name)
96
+ if input.new_record?
97
+ input.value = i.value
98
+ input.file = i.file
99
+ input.depth = i.depth
100
+ input.save
101
+ end
102
+ end
103
+ end
104
+
105
+ def enqueue
106
+ worker = TavernaPlayer::Worker.new(self)
107
+ job = Delayed::Job.enqueue worker, :queue => "player"
108
+ update_attributes(:delayed_job => job, :status_message => "Queued")
109
+ end
110
+
111
+ end # included
112
+
113
+ # Get the original ancestor of this run. In practice this is the first
114
+ # run in the chain without a parent.
115
+ def root_ancestor
116
+ has_parent? ? parent.root_ancestor : self
117
+ end
118
+
119
+ # There are two courses of action here:
120
+ #
121
+ # * If the run is already running then cancel this run by setting the
122
+ # stop flag. This is done to allow the delayed job that is
123
+ # monitoring the run to delete it and clean up Taverna Server
124
+ # gracefully.
125
+ # * If the run is still in the queue, destroy the queue object. This
126
+ # is checked in a transaction so that we don't get hit with a race
127
+ # condition between checking the queued status of the run and
128
+ # actually removing it from the queue.
129
+ #
130
+ # In both cases the stop flag is set to mark the run as cancelled
131
+ # internally.
132
+ #
133
+ # See the note above about the :cancelled state.
134
+ def cancel
135
+ return if complete?
136
+
137
+ # If the run has a delayed job (still) and it hasn't been locked yet
138
+ # then we just remove it from the queue directly and mark the run as
139
+ # cancelled.
140
+ unless delayed_job.nil?
141
+ delayed_job.with_lock do
142
+ if delayed_job.locked_by.nil?
143
+ delayed_job.destroy
144
+ update_attribute(:saved_state, "cancelled")
145
+ update_attribute(:status_message, "Cancelled")
146
+ end
147
+ end
148
+ end
149
+
150
+ update_attribute(:stop, true)
151
+ end
152
+
153
+ # Return state as a symbol. If a run is running, but has been asked to
154
+ # stop, then it is :cancelling. This is a pseudo-state to avoid race
155
+ # conditions when cancelling a run so is specifically NOT in the list
156
+ # of allowed states above.
157
+ def state
158
+ s = self[:saved_state].to_sym
159
+ if s == :running
160
+ stop ? :cancelling : :running
161
+ else
162
+ s
163
+ end
164
+ end
165
+
166
+ # Save state as a downcased string. See the note above about why a
167
+ # state cannot be used to actually cancel a run.
168
+ def state=(state)
169
+ s = state.to_s.downcase
170
+ return if s == "cancelled" && !stop
171
+ self[:saved_state] = s
172
+ end
173
+
174
+ def running?
175
+ state == :running
176
+ end
177
+
178
+ def finished?
179
+ state == :finished
180
+ end
181
+
182
+ def cancelled?
183
+ state == :cancelled
184
+ end
185
+
186
+ def cancelling?
187
+ state == :cancelling
188
+ end
189
+
190
+ def failed?
191
+ state == :failed
192
+ end
193
+
194
+ # This is used as a catch-all for finished, cancelled and failed
195
+ def complete?
196
+ finished? || cancelled? || failed?
197
+ end
198
+
199
+ def has_parent?
200
+ !parent_id.nil?
201
+ end
202
+ end
203
+ end
204
+ end
205
+ end