taverna-player 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/Gemfile +18 -0
- data/LICENCE.rdoc +29 -0
- data/README.rdoc +663 -0
- data/Rakefile +65 -0
- data/app/assets/javascripts/taverna_player/application.js +14 -0
- data/app/assets/javascripts/taverna_player/runs.js +42 -0
- data/app/assets/stylesheets/scaffold.css +56 -0
- data/app/assets/stylesheets/taverna_player/application.css +13 -0
- data/app/assets/stylesheets/taverna_player/coderay.css +120 -0
- data/app/controllers/taverna_player/application_controller.rb +16 -0
- data/app/controllers/taverna_player/runs_controller.rb +18 -0
- data/app/controllers/taverna_player/service_credentials_controller.rb +18 -0
- data/app/helpers/taverna_player/application_helper.rb +55 -0
- data/app/helpers/taverna_player/runs_helper.rb +84 -0
- data/app/models/taverna_player/interaction.rb +25 -0
- data/app/models/taverna_player/run.rb +117 -0
- data/app/models/taverna_player/run_port.rb +148 -0
- data/app/models/taverna_player/service_credential.rb +56 -0
- data/app/views/layouts/taverna_player/embedded.html.erb +27 -0
- data/app/views/taverna_player/runs/_button.html.erb +19 -0
- data/app/views/taverna_player/runs/_info.html.erb +56 -0
- data/app/views/taverna_player/runs/_info.json.jbuilder +2 -0
- data/app/views/taverna_player/runs/_inputs.html.erb +34 -0
- data/app/views/taverna_player/runs/_inputs.json.jbuilder +8 -0
- data/app/views/taverna_player/runs/_interaction.html.erb +68 -0
- data/app/views/taverna_player/runs/_outputs.html.erb +41 -0
- data/app/views/taverna_player/runs/_poll.html.erb +27 -0
- data/app/views/taverna_player/runs/create.json.jbuilder +3 -0
- data/app/views/taverna_player/runs/embedded/_button.html.erb +19 -0
- data/app/views/taverna_player/runs/embedded/_info.html.erb +25 -0
- data/app/views/taverna_player/runs/embedded/_inputs.html.erb +32 -0
- data/app/views/taverna_player/runs/embedded/_outputs.html.erb +32 -0
- data/app/views/taverna_player/runs/embedded/new.html.erb +58 -0
- data/app/views/taverna_player/runs/embedded/show.html.erb +39 -0
- data/app/views/taverna_player/runs/embedded/show.js.erb +35 -0
- data/app/views/taverna_player/runs/index.html.erb +40 -0
- data/app/views/taverna_player/runs/index.json.jbuilder +1 -0
- data/app/views/taverna_player/runs/new.html.erb +56 -0
- data/app/views/taverna_player/runs/new.json.jbuilder +1 -0
- data/app/views/taverna_player/runs/show.html.erb +29 -0
- data/app/views/taverna_player/runs/show.js.erb +25 -0
- data/app/views/taverna_player/runs/show.json.jbuilder +25 -0
- data/app/views/taverna_player/service_credentials/_form.html.erb +53 -0
- data/app/views/taverna_player/service_credentials/edit.html.erb +18 -0
- data/app/views/taverna_player/service_credentials/index.html.erb +41 -0
- data/app/views/taverna_player/service_credentials/new.html.erb +17 -0
- data/app/views/taverna_player/service_credentials/show.html.erb +36 -0
- data/config/routes.rb +34 -0
- data/db/migrate/20130313105546_create_taverna_player_runs.rb +16 -0
- data/db/migrate/20130315163019_create_taverna_player_run_ports.rb +15 -0
- data/db/migrate/20130318170744_add_attachment_file_to_taverna_player_run_ports.rb +6 -0
- data/db/migrate/20130319183634_create_delayed_jobs.rb +22 -0
- data/db/migrate/20130320102600_add_status_message_to_taverna_player_runs.rb +5 -0
- data/db/migrate/20130321100110_add_depth_and_metadata_to_taverna_player_run_ports.rb +6 -0
- data/db/migrate/20130704095504_add_attachment_results_to_taverna_player_runs.rb +5 -0
- data/db/migrate/20130705142704_add_embedded_to_taverna_player_runs.rb +5 -0
- data/db/migrate/20130714140911_create_taverna_player_interactions.rb +13 -0
- data/db/migrate/20130717083653_add_proxy_to_taverna_player_runs.rb +6 -0
- data/db/migrate/20130717155415_add_stop_to_taverna_player_runs.rb +5 -0
- data/db/migrate/20130811152840_add_attachment_log_to_taverna_player_runs.rb +5 -0
- data/db/migrate/20130811211725_change_taverna_player_runs_state_column.rb +5 -0
- data/db/migrate/20130812155839_add_name_to_taverna_player_runs.rb +5 -0
- data/db/migrate/20130918135348_create_taverna_player_service_credentials.rb +15 -0
- data/db/migrate/20130919154200_add_displayed_to_taverna_player_interactions.rb +5 -0
- data/db/migrate/20131007153209_add_job_ref_to_taverna_player_runs.rb +13 -0
- data/db/migrate/20131010094537_add_reply_caching_to_taverna_player_interactions.rb +19 -0
- data/db/migrate/20131017141514_add_failure_message_to_taverna_player_run.rb +5 -0
- data/db/migrate/20131018152940_add_serial_number_to_taverna_player_interactions.rb +5 -0
- data/db/migrate/20131018160715_add_parent_run_id_to_taverna_player_runs.rb +5 -0
- data/db/migrate/20131102113933_add_page_uri_to_taverna_player_interaction.rb +5 -0
- data/db/migrate/20131105115218_remove_proxy_from_taverna_player_runs.rb +11 -0
- data/db/migrate/20131105141934_change_taverna_player_interactions_output_value_column_name.rb +5 -0
- data/db/migrate/20131112165520_add_user_to_taverna_player_run.rb +5 -0
- data/lib/generators/taverna_player/callbacks_generator.rb +25 -0
- data/lib/generators/taverna_player/controllers_generator.rb +30 -0
- data/lib/generators/taverna_player/install_generator.rb +30 -0
- data/lib/generators/taverna_player/job_generator.rb +26 -0
- data/lib/generators/taverna_player/models_generator.rb +27 -0
- data/lib/generators/taverna_player/renderers_generator.rb +26 -0
- data/lib/generators/taverna_player/views_generator.rb +27 -0
- data/lib/generators/templates/ReadMe.txt +118 -0
- data/lib/generators/templates/callbacks/render_callbacks.rb +56 -0
- data/lib/generators/templates/callbacks/worker_callbacks.rb +31 -0
- data/lib/generators/templates/controllers/runs_controller.rb +20 -0
- data/lib/generators/templates/controllers/service_credentials_controller.rb +20 -0
- data/lib/generators/templates/initializer.rb +154 -0
- data/lib/generators/templates/models/run.rb +20 -0
- data/lib/tasks/delete-cancelled-runs.rake +26 -0
- data/lib/tasks/delete-old-embedded-runs.rake +26 -0
- data/lib/taverna-player.rb +139 -0
- data/lib/taverna_player/concerns/controllers/runs_controller.rb +281 -0
- data/lib/taverna_player/concerns/controllers/service_credentials_controller.rb +89 -0
- data/lib/taverna_player/concerns/models/run.rb +205 -0
- data/lib/taverna_player/engine.rb +23 -0
- data/lib/taverna_player/model_proxy.rb +51 -0
- data/lib/taverna_player/output_renderer.rb +96 -0
- data/lib/taverna_player/render_callbacks.rb +41 -0
- data/lib/taverna_player/version.rb +15 -0
- data/lib/taverna_player/worker.rb +325 -0
- data/script/delayed_job +5 -0
- data/script/rails +8 -0
- data/taverna_player.gemspec +46 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +16 -0
- data/test/dummy/app/assets/stylesheets/application.css +14 -0
- data/test/dummy/app/controllers/application_controller.rb +15 -0
- data/test/dummy/app/controllers/home_controller.rb +16 -0
- data/test/dummy/app/controllers/taverna_player/runs_controller.rb +25 -0
- data/test/dummy/app/controllers/taverna_player/service_credentials_controller.rb +25 -0
- data/test/dummy/app/controllers/workflows_controller.rb +17 -0
- data/test/dummy/app/models/user.rb +15 -0
- data/test/dummy/app/models/workflow.rb +32 -0
- data/test/dummy/app/views/home/index.html.erb +18 -0
- data/test/dummy/app/views/layouts/application.html.erb +43 -0
- data/test/dummy/app/views/workflows/index.html.erb +35 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +58 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/taverna_player.example.rb +40 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +22 -0
- data/test/dummy/db/migrate/20130314103555_create_workflows.rb +12 -0
- data/test/dummy/db/migrate/20130318141557_create_taverna_player_runs.taverna_player.rb +17 -0
- data/test/dummy/db/migrate/20130318141558_create_taverna_player_run_ports.taverna_player.rb +16 -0
- data/test/dummy/db/migrate/20130318173013_add_attachment_file_to_taverna_player_run_ports.taverna_player.rb +7 -0
- data/test/dummy/db/migrate/20130319183816_create_delayed_jobs.taverna_player.rb +23 -0
- data/test/dummy/db/migrate/20130320102635_add_status_message_to_taverna_player_runs.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20130321161859_add_depth_and_metadata_to_taverna_player_run_ports.taverna_player.rb +7 -0
- data/test/dummy/db/migrate/20130704100146_add_attachment_results_to_taverna_player_runs.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20130705142816_add_embedded_to_taverna_player_runs.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20130714142144_create_taverna_player_interactions.taverna_player.rb +14 -0
- data/test/dummy/db/migrate/20130717084809_add_proxy_to_taverna_player_runs.taverna_player.rb +7 -0
- data/test/dummy/db/migrate/20130718102707_add_stop_to_taverna_player_runs.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20130811204449_add_attachment_log_to_taverna_player_runs.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20130811212709_change_taverna_player_runs_state_column.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20130812161152_add_name_to_taverna_player_runs.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20130918155525_create_taverna_player_service_credentials.taverna_player.rb +16 -0
- data/test/dummy/db/migrate/20130919155202_add_displayed_to_taverna_player_interactions.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20131007153659_add_job_ref_to_taverna_player_runs.taverna_player.rb +14 -0
- data/test/dummy/db/migrate/20131016123941_add_reply_caching_to_taverna_player_interactions.taverna_player.rb +20 -0
- data/test/dummy/db/migrate/20131017141614_add_failure_message_to_taverna_player_run.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20131018153316_add_serial_number_to_taverna_player_interactions.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20131018164614_add_parent_run_id_to_taverna_player_runs.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20131102114343_add_page_uri_to_taverna_player_interaction.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20131105115724_remove_proxy_from_taverna_player_runs.taverna_player.rb +12 -0
- data/test/dummy/db/migrate/20131105142417_change_taverna_player_interactions_output_value_column_name.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20131112165815_add_user_to_taverna_player_run.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20131114130937_create_users.rb +10 -0
- data/test/dummy/db/schema.rb +123 -0
- data/test/dummy/lib/callbacks.rb +35 -0
- data/test/dummy/log/.gitkeep +0 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/delayed_job +5 -0
- data/test/dummy/script/rails +6 -0
- data/test/dummy/test/functional/home_controller_test.rb +28 -0
- data/test/dummy/test/functional/workflows_controller_test.rb +21 -0
- data/test/fixtures/files/crassostrea_gigas.csv +737 -0
- data/test/fixtures/taverna_player/interactions.yml +32 -0
- data/test/fixtures/taverna_player/run_ports.yml +54 -0
- data/test/fixtures/taverna_player/runs.yml +69 -0
- data/test/fixtures/taverna_player/service_credentials.yml +25 -0
- data/test/fixtures/users.yml +16 -0
- data/test/fixtures/workflows.yml +32 -0
- data/test/functional/taverna_player/runs_controller_test.rb +316 -0
- data/test/functional/taverna_player/service_credentials_controller_test.rb +99 -0
- data/test/taverna_player_test.rb +25 -0
- data/test/test_helper.rb +33 -0
- data/test/unit/helpers/taverna_player/application_helper_test.rb +70 -0
- data/test/unit/helpers/taverna_player/runs_helper_test.rb +45 -0
- data/test/unit/taverna_player/interaction_test.rb +47 -0
- data/test/unit/taverna_player/run_port_test.rb +309 -0
- data/test/unit/taverna_player/run_test.rb +196 -0
- data/test/unit/taverna_player/service_credential_test.rb +64 -0
- data/test/workflows/hello.t2flow +164 -0
- data/test/workflows/list_with_errors.t2flow +107 -0
- data/test/workflows/pass_through.t2flow +12 -0
- 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
|