summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Helma <helma@in-silico.ch>2011-03-10 12:13:42 +0100
committerChristoph Helma <helma@in-silico.ch>2011-03-10 12:13:42 +0100
commita8bcd368193d82f5d8fc0eb7140d2d104b566e02 (patch)
treed04345e52a24d4606f177180903a8a3eb25fb868
parentea2d915efcf54150449755b3ee31974c655eb482 (diff)
parent97821ad3851177f54e1999159ebf0b9987d40a27 (diff)
Merge branch 'release/v1.0.0'v1.0.0
-rw-r--r--README11
-rw-r--r--application.rb210
-rw-r--r--config.ru4
3 files changed, 164 insertions, 61 deletions
diff --git a/README b/README
index 9eb993f..7122ccf 100644
--- a/README
+++ b/README
@@ -4,7 +4,8 @@ OpenTox Task
* An OpenTox REST Webservice (http://www.opentox.org)
* Does _not_ comply to the (incomplete) OpenTox API
-REST operations:
+REST operations
+---------------
Get a list of all tasks GET / - Task URIs 200
Get the status of a task GET /{id}/status - created|started|completed|cancelled 200,404
@@ -17,10 +18,12 @@ Cancel a task PUT /{id}/cancelled "" -
Delete a task DELETE /{id} - - 200, 404
Delete all tasks DELETE / - - 200
-IMPORTANT NOTE: My framework does not accept empty PUT requests. Please send an empty parameter (e.g. with -d '' for curl) or you will receive a "411 Length Required" error.
+IMPORTANT NOTE: Our framework does not accept empty PUT requests. Please send an empty parameter (e.g. with -d '' for curl) or you will receive a "411 Length Required" error.
-More documentation: Source code (application.rb)
+API documentation
+-----------------
-Copyright (c) 2009 Christoph Helma. See LICENSE for details.
+http://rdoc.info/github/opentox/task
+Copyright (c) 2009-2011 Christoph Helma, Martin Guetlein, Micha Rautenberg, Andreas Maunz, David Vorgrimmler, Denis Gebele. See LICENSE for details.
diff --git a/application.rb b/application.rb
index fe3d593..673cc4d 100644
--- a/application.rb
+++ b/application.rb
@@ -1,53 +1,88 @@
require 'rubygems'
-gem "opentox-ruby-api-wrapper", "= 1.6.5"
-require 'opentox-ruby-api-wrapper'
-#require "dm-is-tree"
-
-class Task
- include DataMapper::Resource
- property :id, Serial
- property :uri, String, :length => 255
- property :created_at, DateTime
-
- property :finished_at, DateTime
- property :due_to_time, DateTime
- property :pid, Integer
-
- property :resultURI, String, :length => 255
- property :percentageCompleted, Float, :default => 0
- property :hasStatus, String, :default => "Running" #possible states are: "Cancelled", "Completed", "Running", "Error"
- property :title, String, :length => 255
- property :creator, String, :length => 255
- property :description, Text
+gem "opentox-ruby", "~> 1"
+require 'opentox-ruby'
+
+set :lock, true
+
+class Task < Ohm::Model
+
+ attribute :uri
+ attribute :created_at
+
+ attribute :finished_at
+ attribute :due_to_time
+ attribute :pid
+
+ attribute :resultURI
+ attribute :percentageCompleted
+ attribute :hasStatus
+ attribute :title
+ attribute :creator
+ attribute :description
+
+ attribute :waiting_for
+
+ attribute :errorReport
+
+ def metadata
+ {
+ DC.creator => creator,
+ DC.title => title,
+ DC.date => created_at,
+ OT.hasStatus => hasStatus,
+ OT.resultURI => resultURI,
+ OT.percentageCompleted => percentageCompleted.to_f,
+ #text fields are lazy loaded, using member variable can cause description to be nil
+ DC.description => description
+ #:due_to_time => @due_to_timer
+ }
+ end
+
end
-DataMapper.auto_upgrade!
+#DataMapper.auto_upgrade!
+# Get a list of all tasks
+# @return [text/uri-list] List of all tasks
get '/?' do
- response['Content-Type'] = 'text/uri-list'
- Task.all(params).collect{|t| t.uri}.join("\n") + "\n"
+ LOGGER.debug "list all tasks "+params.inspect
+ if request.env['HTTP_ACCEPT'] =~ /html/
+ response['Content-Type'] = 'text/html'
+ OpenTox.text_to_html Task.all.collect{|t| t.uri}.join("\n") + "\n"
+ else
+ response['Content-Type'] = 'text/uri-list'
+ Task.all.collect{|t| t.uri}.join("\n") + "\n"
+ end
end
+# Get task representation
+# @param [Header] Accept Mime type of accepted representation, may be one of `application/rdf+xml,application/x-yaml,text/uri-list`
+# @return [application/rdf+xml,application/x-yaml,text/uri-list] Task representation in requested format, Accept:text/uri-list returns URI of the created resource if task status is "Completed"
get '/:id/?' do
- task = Task.get(params[:id])
+ task = Task[params[:id]]
halt 404, "Task '#{params[:id]}' not found." unless task
-
- task_content = {:creator => task.creator, :title => task.title, :date => task.created_at, :hasStatus => task.hasStatus,
- :resultURI => task.resultURI, :percentageCompleted => task.percentageCompleted, :description => task.description,
- :due_to_time => task.due_to_time }
-
code = task.hasStatus == "Running" ? 202 : 200
case request.env['HTTP_ACCEPT']
- when /application\/x-yaml|\*\/\*/ # matches 'application/x-yaml', '*/*'
+ when /yaml/
response['Content-Type'] = 'application/x-yaml'
- task_content[:uri] = task.uri
- halt code, task_content.to_yaml
- when /application\/rdf\+xml|\*\/\*/
+ metadata = task.metadata
+ metadata[OT.waitingFor] = task.waiting_for
+ metadata[OT.errorReport] = task.errorReport if task.errorReport
+ halt code, metadata.to_yaml
+ #halt code, task.created_at
+ when /html/
+ response['Content-Type'] = 'text/html'
+ metadata = task.metadata
+ metadata[OT.waitingFor] = task.waiting_for
+ metadata[OT.errorReport] = task.errorReport if task.errorReport
+ halt code, OpenTox.text_to_html(metadata.to_yaml)
+ when /application\/rdf\+xml|\*\/\*/ # matches 'application/x-yaml', '*/*'
response['Content-Type'] = 'application/rdf+xml'
- owl = OpenTox::Owl.create 'Task', task.uri
- task_content.each{ |k,v| owl.set(k.to_s,v)}
- halt code, owl.rdf
+ t = OpenTox::Task.new task.uri
+ t.add_metadata task.metadata
+ t.add_error_report task.errorReport
+ halt t.to_rdfxml
when /text\/uri\-list/
response['Content-Type'] = 'text/uri-list'
halt code, task.resultURI
@@ -56,32 +91,75 @@ get '/:id/?' do
end
end
-# dynamic access to Task properties
+
+# Get Task properties. Works for
+# - /task/id
+# - /task/uri
+# - /task/created_at
+# - /task/finished_at
+# - /task/due_to_time
+# - /task/pid
+# - /task/resultURI
+# - /task/percentageCompleted
+# - /task/hasStatus
+# - /task/title
+# - /task/creator
+# - /task/description
+# @return [String] Task property
get '/:id/:property/?' do
response['Content-Type'] = 'text/plain'
- task = Task.get(params[:id])
+ task = Task[params[:id]]
halt 404,"Task #{params[:id]} not found." unless task
- eval("task.#{params[:property]}").to_s
+ begin
+ eval("task.#{params[:property]}").to_s
+ rescue
+ halt 404,"Unknown task property #{params[:property]}."
+ end
end
+# Create a new task
+# @param [optional,String] max_duration
+# @param [optional,String] pid
+# @param [optional,String] resultURI
+# @param [optional,String] percentageCompleted
+# @param [optional,String] hasStatus
+# @param [optional,String] title
+# @param [optional,String] creator
+# @param [optional,String] description
+# @return [text/uri-list] URI for new task
post '/?' do
LOGGER.debug "Creating new task with params "+params.inspect
max_duration = params.delete(:max_duration.to_s) if params.has_key?(:max_duration.to_s)
- task = Task.new(params)
- task.save # needed to create id
- task.uri = url_for("/#{task.id}", :full)
- task.due_to_time = DateTime.parse((Time.parse(task.created_at.to_s) + max_duration.to_f).to_s) if max_duration
- raise "could not save" unless task.save
+ params[:created_at] = Time.now
+ params[:hasStatus] = "Running" unless params[:hasStatus]
+ task = Task.create params
+ task.update :uri => url_for("/#{task.id}", :full)
+ #task.due_to_time = DateTime.parse((Time.parse(task.created_at.to_s) + max_duration.to_f).to_s) if max_duration
+ #raise "Could not save task #{task.uri}" unless task.save
response['Content-Type'] = 'text/uri-list'
task.uri + "\n"
end
+# Change task status. Possible URIs are: `
+# - /task/Cancelled
+# - /task/Completed: requires taskURI argument
+# - /task/Running
+# - /task/Error
+# - /task/pid: requires pid argument
+# IMPORTANT NOTE: Rack does not accept empty PUT requests. Please send an empty parameter (e.g. with -d '' for curl) or you will receive a "411 Length Required" error.
+# @param [optional, String] resultURI URI of created resource, required for /task/Completed
+# @param [optional, String] pid Task PID, required for /task/pid
+# @param [optional, String] description Task description
+# @param [optional, String] percentageCompleted progress value, can only be set while running
+# @return [] nil
put '/:id/:hasStatus/?' do
- task = Task.get(params[:id])
+ task = Task[params[:id]]
halt 404,"Task #{params[:id]} not found." unless task
task.hasStatus = params[:hasStatus] unless /pid/ =~ params[:hasStatus]
task.description = params[:description] if params[:description]
+ #task.errorReport = YAML.load(params[:errorReport]) if params[:errorReport]
+ task.errorReport = params[:errorReport] if params[:errorReport]
case params[:hasStatus]
when "Completed"
@@ -89,43 +167,63 @@ put '/:id/:hasStatus/?' do
halt 402,"no param resultURI when completing task" unless params[:resultURI]
task.resultURI = params[:resultURI]
task.finished_at = DateTime.now
+ task.percentageCompleted = 100
task.pid = nil
when "pid"
task.pid = params[:pid]
+ when "Running"
+ halt 400,"Task cannot be set to running after not running anymore" if task.hasStatus!="Running"
+ task.waiting_for = params[:waiting_for] if params.has_key?("waiting_for")
+ if params.has_key?("percentageCompleted")
+ task.percentageCompleted = params[:percentageCompleted].to_f
+ #LOGGER.debug "Task " + params[:id].to_s + " set percentage completed to: "+params[:percentageCompleted].to_s
+ end
when /Cancelled|Error/
- Process.kill(9,task.pid) unless task.pid.nil?
+ if task.waiting_for and task.waiting_for.uri?
+ # try cancelling the child task
+ begin
+ w = OpenTox::Task.find(task.waiting_for)
+ w.cancel if w.running?
+ rescue
+ end
+ end
+ LOGGER.debug("Aborting task "+task.uri.to_s)
+ Process.kill(9,task.pid.to_i) unless task.pid.nil?
task.pid = nil
else
halt 402,"Invalid value for hasStatus: '"+params[:hasStatus].to_s+"'"
end
halt 500,"could not save task" unless task.save
-
+
end
+# Delete a task
+# @return [text/plain] Status message
delete '/:id/?' do
- task = Task.get(params[:id])
+ task = Task[params[:id]]
halt 404, "Task #{params[:id]} not found." unless task
begin
Process.kill(9,task.pid) unless task.pid.nil?
+ task.delete
+ response['Content-Type'] = 'text/plain'
+ "Task #{params[:id]} deleted."
rescue
halt 500,"Cannot kill task with pid #{task.pid}"
end
- task.destroy!
- response['Content-Type'] = 'text/plain'
- "Task #{params[:id]} deleted."
end
+# Delete all tasks
+# @return [text/plain] Status message
delete '/?' do
Task.all.each do |task|
begin
- Process.kill(9,task.pid) unless task.pid.nil?
+ Process.kill(9,task.pid.to_i) unless task.pid.nil?
+ task.delete
+ response['Content-Type'] = 'text/plain'
+ "All tasks deleted."
rescue
"Cannot kill task with pid #{task.pid}"
end
- #task.destroy!
end
- Task.auto_migrate!
- response['Content-Type'] = 'text/plain'
- "All tasks deleted."
end
diff --git a/config.ru b/config.ru
index 489932f..8603270 100644
--- a/config.ru
+++ b/config.ru
@@ -1,5 +1,7 @@
require 'rubygems'
-require 'opentox-ruby-api-wrapper'
+require 'opentox-ruby'
require 'config/config_ru'
run Sinatra::Application
+set :raise_errors, false
+set :show_exceptions, false