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.
- 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
|