summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMartin Gütlein <martin.guetlein@gmail.com>2010-04-23 14:20:40 +0200
committerMartin Gütlein <martin.guetlein@gmail.com>2010-04-23 14:20:40 +0200
commitad974c419a2efe4c0ceaa1f3e2346906b5783e52 (patch)
tree5c98d81de01a79f39ff9b01d991e9f6041802004 /lib
parent1926e43b9e2716e7f7248fe183a4d43da1209a1b (diff)
adjusted task to api, new owl
Diffstat (limited to 'lib')
-rw-r--r--lib/model.rb27
-rw-r--r--lib/owl.rb251
-rw-r--r--lib/rest_client_wrapper.rb109
-rw-r--r--lib/task.rb144
4 files changed, 294 insertions, 237 deletions
diff --git a/lib/model.rb b/lib/model.rb
index 3aae652..8b275ed 100644
--- a/lib/model.rb
+++ b/lib/model.rb
@@ -3,7 +3,7 @@ module OpenTox
class Generic
- attr_accessor :uri, :title, :source, :identifier, :predicted_variables, :independent_variables, :dependent_variables, :activity_dataset_uri, :feature_dataset_uri, :effects, :activities, :p_values, :fingerprints, :features, :algorithm
+ attr_accessor :uri, :title, :creator, :date, :format, :identifier, :predictedVariables, :independentVariables, :dependentVariables, :trainingDataset, :feature_dataset_uri, :effects, :activities, :p_values, :fingerprints, :features, :algorithm
def self.find(uri)
owl = OpenTox::Owl.from_uri(uri)
@@ -12,23 +12,16 @@ module OpenTox
protected
def initialize(owl)
- @title = owl.title
- @source = owl.source
- @identifier = owl.identifier.sub(/^\[/,'').sub(/\]$/,'')
- @uri = owl.uri.to_s #@identifier
- @algorithm = owl.algorithm
- @dependent_variables = owl.dependentVariables
- @independent_variables = owl.independentVariables
- @predicted_variables = owl.predictedVariables
-
- raise "invalid model:\n"+self.to_yaml+"\n" unless Utils.is_uri?(@uri) &&
- #@dependent_variables.to_s.size>0 &&
- #@independent_variables.to_s.size>0 &&
- @predicted_variables.to_s.size>0 if ENV['RACK_ENV'] =~ /test|debug/
+ [:uri, :date, :creator, :title, :format, :identifier, :algorithm,
+ :dependentVariables, :independentVariables, :predictedVariables, :trainingDataset].each do |a|
+ self.send("#{a.to_s}=".to_sym, owl.get(a.to_s))
+ end
+ RestClientWrapper.raise_uri_error "invalid model:\n"+
+ self.to_yaml+"\n",@uri.to_s unless (Utils.is_uri?(@uri) and
+ @dependentVariables and @independentVariables and @predictedVariables) if ENV['RACK_ENV'] =~ /test|debug/
end
end
-
class PredictionModel < Generic
def self.build( algorithm_uri, algorithm_params )
@@ -41,7 +34,7 @@ module OpenTox
LOGGER.debug "Build model, algorithm_uri:"+algorithm_uri.to_s+", algorithm_parms: "+algorithm_params.inspect.to_s
uri = OpenTox::RestClientWrapper.post(algorithm_uri,algorithm_params).to_s
- RestClientWrapper.illegal_result("Invalid build model result: "+uri.to_s, algorithm_uri, algorithm_params ) unless Utils.model_uri?(uri)
+ RestClientWrapper.raise_uri_error("Invalid build model result: "+uri.to_s, algorithm_uri, algorithm_params ) unless Utils.model_uri?(uri)
return PredictionModel.find(uri)
end
@@ -49,7 +42,7 @@ module OpenTox
LOGGER.debug "Predict dataset: "+dataset_uri.to_s+" with model "+@uri.to_s
uri = RestClientWrapper.post(@uri, {:dataset_uri=>dataset_uri})
- RestClientWrapper.illegal_result("Prediciton result no dataset uri: "+uri.to_s, @uri, {:dataset_uri=>dataset_uri} ) unless Utils.dataset_uri?(uri)
+ RestClientWrapper.raise_uri_error("Prediciton result no dataset uri: "+uri.to_s, @uri, {:dataset_uri=>dataset_uri} ) unless Utils.dataset_uri?(uri)
uri
end
diff --git a/lib/owl.rb b/lib/owl.rb
index ec8c699..40cd00d 100644
--- a/lib/owl.rb
+++ b/lib/owl.rb
@@ -1,5 +1,9 @@
class Redland::Literal
+ def self.create(value, datatype)
+ Redland::Literal.new(value,nil,Redland::Uri.new(datatype))
+ end
+
# the literal node of the ruby swig api provdides the 'value' of a literal but not the 'datatype'
# found solution in mailing list
def datatype()
@@ -12,33 +16,61 @@ end
module OpenTox
class Owl
-
- attr_accessor :uri, :ot_class, :model
+
+ # ot_class is the class of the object, e.g. "Model","Dataset", ...
+ # root_node is the root-object node in the rdf
+ # identifier is the uri of the object
+ attr_accessor :ot_class, :root_node, :identifier, :model
def initialize
@model = Redland::Model.new Redland::MemoryStore.new
end
- def self.create(ot_class,uri)
+ def self.create( ot_class, uri )
owl = OpenTox::Owl.new
- owl.ot_class = ot_class
- owl.uri = Redland::Uri.new(uri.chomp)
- owl.model.add owl.uri, RDF['type'], OT[owl.ot_class]
- owl.model.add owl.uri, DC['identifier'], owl.uri
+ owl.ot_class = ot_class
+ owl.root_node = Redland::Resource.new(uri.chomp+"XYZ")
+ owl.identifier = uri.chomp
+ owl.set("type",owl.ot_class)
+ owl.set('identifier', owl.identifier, "xsd:anyURI")
owl
end
- def self.from_data(data,uri)
+ def self.from_data(data,base_uri)
owl = OpenTox::Owl.new
parser = Redland::Parser.new
+
begin
- parser.parse_string_into_model(owl.model, data, uri)
+ parser.parse_string_into_model(owl.model, data, base_uri)
+
+ # getting object-(root)-node and identifier via identifier property
+ # PENDING easier solution?
+ owl.identifier = nil
+ owl.model.find(nil, owl.node('identifier'), nil) do |s,p,o|
+ #LOGGER.debug "ID Statements "+s.to_s+" . "+p.to_s+" -> "+o.to_s
+ root_id = true
+ owl.model.find(nil, nil, s) do |ss,pp,oo|
+ root_id = false
+ break
+ end
+ if root_id
+ if o.is_a?(Redland::Literal)
+ raise "cannot derieve object uri from rdf, more than one identifier" if owl.identifier
+ owl.root_node = s
+ owl.identifier = o.value
+ else
+ raise "illegal identifier, not a literal: "+o.to_s
+ end
+ end
+ end
+ raise "Illegal RDF: root identifier missing" unless owl.identifier
+ owl.ot_class = owl.get("type")
+ LOGGER.debug "RDF loaded, uri/identifier:"+owl.identifier+", ot-class: "+owl.ot_class.to_s+", root-node:"+owl.root_node.to_s
+ owl
rescue => e
- raise "Error parsing #{uri}: "+e.message
+ RestClientWrapper.raise_uri_error(e.message, base_uri)
end
- owl.uri = Redland::Uri.new(uri.chomp)
- owl
end
def self.from_uri(uri)
@@ -47,53 +79,49 @@ module OpenTox
def rdf
@model.to_string
- end
-
- def method_missing(name, *args)
- methods = ['title', 'source', 'identifier', 'algorithm', 'independentVariables', 'dependentVariables', 'predictedVariables', 'date','trainingDataset', 'hasStatus', "percentageCompleted" ]
- if methods.include? name.to_s.sub(/=/,'')
- if /=/ =~ name.to_s # setter
- name = name.to_s.sub(/=/,'')
- begin # delete existing entry
- t = @model.object(@uri, DC[name])
- @model.delete @uri, DC[name], t
- rescue
- end
- @model.add @uri, DC[name], args.first
- else # getter
- #HACK for reading Panteli's models
- if @uri.to_s =~ /194.141.0.136.*model|ambit2.*model|ntua.*model|tu-muenchen.*model/ and !["title", "source", "identifier"].include?(name.to_s)
- begin
- me = @model.subject(RDF['type'],OT['Model'])
- return @model.object(me, OT[name.to_s]).uri.to_s
- rescue
- LOGGER.warn "cannot get "+name.to_s+" from model"
- return nil
- end
- elsif @uri.to_s =~ /ambit.*task/ and ["hasStatus", "percentageCompleted"].include?(name.to_s)
- me = @model.subject(RDF['type'],OT['Task'])
- return @model.object(me, OT[name.to_s]).literal.value.to_s
- end
- #raise "stop there "+name.to_s
- val = @model.object(@uri, DC[name.to_s])
- if val.is_a?(Redland::Literal)
- return val.value
- else
- return val.to_s
- end
- end
- else
- raise "Method '#{name.to_s}' not found."
- end
- end
+ end
+
+ def uri
+ @identifier
+ end
+
+ def get(name)
+ property_node = node(name.to_s)
+ raise "Method '#{name.to_s}' not found." unless property_node
+ val = @model.object(@root_node, property_node)
+ return nil unless val
+ if val.is_a?(Redland::Literal)
+ return val.value
+ else
+ return val.uri.to_s
+ end
+ end
+
+ def set(name, value, datatype=nil)
+ property_node = node(name.to_s)
+ raise "Method '#{name.to_s}' not found." unless property_node
+ begin # delete existing entry
+ t = @model.object(@root_node, property_node)
+ @model.delete @root_node, property_node, t
+ rescue
+ end
+ if value.first.is_a?(Redland::Node)
+ raise "not nil datatype not allowed when setting redland node as value" if datatype
+ @model.add @root_node, property_node, value
+ elsif datatype
+ @model.add @root_node, property_node, Redland::Literal.create(value, datatype)
+ else
+ @model.add @root_node, property_node, value
+ end
+ end
def parameters=(params)
params.each do |name, settings|
parameter = @model.create_resource
- @model.add parameter, RDF['type'], OT['Parameter']
- @model.add parameter, DC['title'], name
- @model.add parameter, OT['paramScope'], settings[:scope]
- @model.add parameter, OT['paramValue'], settings[:value]
+ @model.add parameter, node('type'), node('Parameter')
+ @model.add parameter, node('title'), name
+ @model.add parameter, node('paramScope'), settings[:scope]
+ @model.add parameter, node('paramValue'), settings[:value]
end
end
@@ -102,8 +130,8 @@ module OpenTox
compound = @model.subject(DC["identifier"], compound_uri)
if compound.nil?
compound = @model.create_resource(compound_uri)
- @model.add compound, RDF['type'], OT["Compound"]
- @model.add compound, DC["identifier"], compound_uri
+ @model.add compound, node('type'), node("Compound")
+ @model.add compound, node("identifier"), compound_uri
end
features.each do |f|
f.each do |feature_uri,value|
@@ -112,51 +140,51 @@ module OpenTox
if value.class.to_s == 'Hash'
# create tuple
tuple = @model.create_resource
- @model.add tuple, RDF['type'], OT["Tuple"]
- @model.add tuple, OT['feature'], feature
+ @model.add tuple, node('type'), node("Tuple")
+ @model.add tuple, node('feature'), feature
value.each do |uri,v|
f = find_or_create_feature uri
complex_value = @model.create_resource
- @model.add tuple, OT['complexValue'], complex_value
- @model.add complex_value, RDF['type'], OT["FeatureValue"]
- @model.add complex_value, OT['feature'], f
- @model.add complex_value, OT['value'], v.to_s
+ @model.add tuple, node('complexValue'), complex_value
+ @model.add complex_value, node('type'), node("FeatureValue")
+ @model.add complex_value, node('feature'), f
+ @model.add complex_value, node('value'), v.to_s
end
# add data entry
- data_entry = @model.subject OT['compound'], compound
+ data_entry = @model.subject node('compound'), compound
if data_entry.nil?
data_entry = @model.create_resource
- @model.add @uri, OT['dataEntry'], data_entry
- @model.add data_entry, RDF['type'], OT["DataEntry"]
- @model.add data_entry, OT['compound'], compound
+ @model.add @root_node, node('dataEntry'), data_entry
+ @model.add data_entry, node('type'), node("DataEntry")
+ @model.add data_entry, node('compound'), compound
end
- @model.add data_entry, OT['values'], tuple
+ @model.add data_entry, node('values'), tuple
else
- data_entry = @model.subject OT['compound'], compound
+ data_entry = @model.subject node('compound'), compound
if data_entry.nil?
data_entry = @model.create_resource
- @model.add @uri, OT['dataEntry'], data_entry
- @model.add data_entry, RDF['type'], OT["DataEntry"]
- @model.add data_entry, OT['compound'], compound
+ @model.add @root_node, node('dataEntry'), data_entry
+ @model.add data_entry,node('type'), node("DataEntry")
+ @model.add data_entry, node('compound'), compound
end
values = @model.create_resource
- @model.add data_entry, OT['values'], values
- @model.add values, RDF['type'], OT['FeatureValue']
- @model.add values, OT['feature'], feature
- @model.add values, OT['value'], value.to_s
+ @model.add data_entry, node('values'), values
+ @model.add values, node('type'), node('FeatureValue')
+ @model.add values, node('feature'), feature
+ @model.add values, node('value'), value.to_s
end
end
end
end
def find_or_create_feature(feature_uri)
- feature = @model.subject(DC["identifier"], feature_uri)
+ feature = @model.subject(node("identifier"), feature_uri)
if feature.nil?
feature = @model.create_resource(feature_uri)
- @model.add feature, RDF['type'], OT["Feature"]
- @model.add feature, DC["identifier"], feature_uri
- @model.add feature, DC["title"], File.basename(feature_uri).split(/#/)[1]
- @model.add feature, DC['source'], feature_uri
+ @model.add feature, node('type'), node("Feature")
+ @model.add feature, node("identifier"), feature_uri
+ @model.add feature, node("title"), File.basename(feature_uri).split(/#/)[1]
+ @model.add feature, node('creator'), feature_uri
end
feature
end
@@ -164,15 +192,13 @@ module OpenTox
# feature values are not loaded for performance reasons
# loading compounds and features into arrays that are given as params
def load_dataset( compounds, features )
- ot_compound = OT['compound']
- dc_identifier = DC['identifier']
- @model.subjects(RDF['type'], OT['DataEntry']).each do |data_entry|
- compound_node = @model.object(data_entry, ot_compound)
- compound_uri = @model.object(compound_node, dc_identifier).to_s
+ @model.subjects(node('type'), node('DataEntry')).each do |data_entry|
+ compound_node = @model.object(data_entry, node('compound'))
+ compound_uri = @model.object(compound_node, node('identifier')).to_s
compounds << compound_uri
end
- @model.subjects(RDF['type'], OT['Feature']).each do |feature|
- feature_literal = @model.object(feature, dc_identifier)
+ @model.subjects(node('type'), node('Feature')).each do |feature|
+ feature_literal = @model.object(feature, node('identifier'))
raise "feature is no literal" unless feature_literal.is_a?(Redland::Literal)
# PENDING: to be able to recreate literal nodes for features, the datatype is stored
@@feature_datatype = feature_literal.datatype
@@ -194,24 +220,16 @@ module OpenTox
# values are stored in the data-hash, hash has a key for each compound
compounds.each{|c| data[c] = [] unless data[c]}
- ot_values = OT['values']
- ot_feature = OT['feature']
- ot_compound = OT['compound']
- dc_identifier = DC['identifier']
- ot_value = OT['value']
- rdf_type = RDF['type']
- ot_feature_value = OT['FeatureValue']
-
load_all_features = feature_uri==nil
feature_node = nil
# create feature node for feature uri if specified
unless load_all_features
feature_literal = Redland::Literal.new(feature_uri,nil,Redland::Uri.new(@@feature_datatype))
- feature_node = @model.subject(dc_identifier, feature_literal)
+ feature_node = @model.subject(node('identifier'), feature_literal)
# remark: solution without creating the literal node:
#@model.subjects(RDF['type'], OT['Feature']).each do |feature|
- # f_uri = @model.object(feature, dc_identifier).value
+ # f_uri = @model.object(feature, node('identifier')).value
# if feature_uri==f_uri
# feature_node = feature
# break
@@ -230,14 +248,14 @@ module OpenTox
# feature_node is either nil, i.e. a wildcard or specified
@model.find(nil, ot_feature, feature_node) do |feature_value_node,p,o|
- # get compound_uri by "backtracking" to values node (property is 'ot_values'), then get compound_node via 'ot_compound'
- value_nodes = @model.subjects(ot_values,feature_value_node)
+ # get compound_uri by "backtracking" to values node (property is 'values'), then get compound_node via 'compound'
+ value_nodes = @model.subjects(node('values'),feature_value_node)
raise "more than one value node "+value_nodes.size.to_s unless value_nodes.size==1
value_node = value_nodes[0]
- compound_node = @model.object(value_node, ot_compound)
+ compound_node = @model.object(value_node, node('compound'))
compound_uri = compound_uri_store[compound_node.to_s]
unless compound_uri
- compound_uri = @model.object(compound_node, dc_identifier).to_s
+ compound_uri = @model.object(compound_node, node('identifier')).to_s
compound_uri_store[compound_node.to_s] = compound_uri
end
@@ -245,16 +263,16 @@ module OpenTox
# if load all features, feautre_uri is not specified, derieve from feature_node
feature_uri = feature_uri_store[o.to_s]
unless feature_uri
- feature_literal = @model.object(o, dc_identifier)
+ feature_literal = @model.object(o, node('identifier'))
raise "feature is no literal" unless feature_literal.is_a?(Redland::Literal)
feature_uri = feature_literal.value
feature_uri_store[o.to_s] = feature_uri
end
end
- value_node_type = @model.object(feature_value_node, rdf_type)
- if (value_node_type == ot_feature_value)
- value_literal = @model.object( feature_value_node, ot_value)
+ value_node_type = @model.object(feature_value_node, node('type'))
+ if (value_node_type == node('FeatureValue'))
+ value_literal = @model.object( feature_value_node, node('value'))
raise "feature value no literal" unless value_literal.is_a?(Redland::Literal)
case value_literal.datatype
@@ -273,7 +291,27 @@ module OpenTox
end
LOGGER.debug "loaded "+count.to_s+" feature values"
+ end
+
+ @@property_nodes = { "type" => RDF["type"],
+ "title" => DC["title"],
+ "creator" => DC["creator"],
+ "uri" => DC["identifier"],
+ "identifier" => DC["identifier"],
+ "date" => DC["date"],
+ "format" => DC["format"]}
+
+ # this method has to purposes:
+ # * distinguishing ot-properties from dc- and rdf- properties
+ # * caching nodes, as creating nodes is costly
+ def node(name)
+ n = @@property_nodes[name]
+ unless n
+ n = OT[name]
+ @@property_nodes[name] = n
end
+ return n
+ end
=begin
def data
@@ -341,3 +379,4 @@ module OpenTox
end
end
+
diff --git a/lib/rest_client_wrapper.rb b/lib/rest_client_wrapper.rb
index eaf6616..5a6362b 100644
--- a/lib/rest_client_wrapper.rb
+++ b/lib/rest_client_wrapper.rb
@@ -1,3 +1,5 @@
+
+
module OpenTox
#PENDING: implement ot error api, move to own file
@@ -28,7 +30,11 @@ module OpenTox
end
- module RestClientWrapper
+ class WrapperResult < String
+ attr_accessor :content_type
+ end
+
+ class RestClientWrapper
# PENDING: remove as soon as redirect tasks are remove from partner webservices
def self.redirect_task( uri )
@@ -53,77 +59,88 @@ module OpenTox
return uri
end
- def self.get(uri, headers=nil, curl_hack=false)
- execute( "get", uri, headers, nil, curl_hack )
+ def self.get(uri, headers=nil)
+ execute( "get", uri, headers)
end
- def self.post(uri, headers, payload=nil, curl_hack=false)
- raise "payload and headers switched" if payload.is_a?(Hash) and headers==nil
- raise "illegal headers" unless headers==nil || headers.is_a?(Hash)
- execute( "post", uri, headers, payload, curl_hack )
+ def self.post(uri, headers, payload=nil, wait=true)
+ execute( "post", uri, headers, payload, wait )
+ end
+
+ def self.put(uri, headers, payload=nil )
+ execute( "put", uri, headers, payload )
end
- def self.delete(uri, headers=nil, curl_hack=false)
- execute( "delete", uri, headers, nil, curl_hack )
+ def self.delete(uri, headers=nil)
+ execute( "delete", uri, headers, nil)
end
- def self.illegal_result(error_msg, uri, headers, payload=nil)
+ def self.raise_uri_error(error_msg, uri, headers=nil, payload=nil)
do_halt( "-", error_msg, uri, headers, payload )
end
private
- def self.execute( rest_call, uri, headers, payload=nil, curl_hack=false )
+ def self.execute( rest_call, uri, headers, payload=nil, wait=true )
do_halt 400,"uri is null",uri,headers,payload unless uri
- do_halt 400,"not an uri",uri,headers,payload unless Utils.is_uri?(uri)
+ do_halt 400,"not a uri",uri,headers,payload unless Utils.is_uri?(uri)
do_halt 400,"headers are no hash",uri,headers,payload unless headers==nil or headers.is_a?(Hash)
headers.each{ |k,v| headers.delete(k) if v==nil } if headers #remove keys with empty values, as this can cause problems
begin
- unless curl_hack
-
- #LOGGER.debug "RestCall: "+rest_call.to_s+" "+uri.to_s+" "+headers.inspect
- resource = RestClient::Resource.new(uri, :timeout => 60)
- if payload
- result = resource.send(rest_call, payload, headers).to_s
- #result = RestClient.send(rest_call, uri, payload, headers).to_s
- elsif headers
- #result = RestClient.send(rest_call, uri, headers).to_s
- result = resource.send(rest_call, headers).to_s
- else
- result = resource.send(rest_call).to_s
- end
+ #LOGGER.debug "RestCall: "+rest_call.to_s+" "+uri.to_s+" "+headers.inspect
+ resource = RestClient::Resource.new(uri,{:timeout => 60, :user => @@users[:users].keys[0], :password => @@users[:users].values[0]})
+ if payload
+ result = resource.send(rest_call, payload, headers)
+ elsif headers
+ result = resource.send(rest_call, headers)
else
- result = ""
- cmd = " curl -v -X "+rest_call.upcase+" "+payload.collect{|k,v| "-d "+k.to_s+"='"+v.to_s+"' "}.join("")+" "+uri.to_s
- LOGGER.debug "CURL HACK: "+cmd
- IO.popen(cmd+" 2> /dev/null") do |f|
- while line = f.gets
- result += line
- end
+ result = resource.send(rest_call)
+ end
+
+ # result is a string, with the additional filed content_type
+ res = WrapperResult.new(result.to_s)
+ res.content_type = result.headers[:content_type]
+
+ # get result cannot be a task
+ return res if rest_call=="get" or !wait
+ return res if res.strip.size==0
+
+ # try to load task from result (maybe task-uri, or task-object)
+ task = nil
+ case res.content_type
+ when /application\/rdf\+xml|text\/x-yaml/
+ task = OpenTox::Task.from_data(res, res.content_type, uri)
+ when /text\//
+ return res if res.content_type=~/text\/uri-list/ and
+ res.split("\n").size > 1 #if uri list contains more then one uri, its not a task
+ # HACK for redirect tasks
+ if res =~ /ambit.*task|tu-muenchen.*task/
+ res = WrapperResult.new(redirect_task(res))
+ res.content_type = "text/uri-list"
+ return res
end
- result.chomp!("\n")
- LOGGER.debug "CURL -> "+result.to_s
- raise "curl call failed "+result if $?!=0
- #raise "STOP "+result
+ task = OpenTox::Task.find(res) if Utils.task_uri?(res)
+ else
+ raise "unknown content-type when checking for task: "+res.content_type+" content: "+res[0..200]
end
-
- if result.to_s =~ /ambit.*task|tu-muenchen.*task/
- result = redirect_task(result)
- elsif Utils.task_uri?(result)
- task = OpenTox::Task.find(result)
+
+ # task could be loaded, wait for task to finish
+ if task
+ LOGGER.debug "result is a task "+task.uri.to_s+", wait for completion"
task.wait_for_completion
- raise task.description if task.failed?
- result = task.resource
+ raise task.description if task.error?
+ res = WrapperResult.new(task.resultURI)
+ res.content_type = "text/uri-list"
end
- return result
+ return res
rescue RestClient::RequestFailed => ex
do_halt ex.http_code,ex.http_body,uri,headers,payload
rescue RestClient::RequestTimeout => ex
do_halt 408,ex.message,uri,headers,payload
rescue => ex
- #raise ex
+ #raise ex.message+" uri: "+uri.to_s
begin
code = ex.http_code
msg = ex.http_body
@@ -145,7 +162,7 @@ module OpenTox
error = [Error.new(code, body, uri, payload, headers)]
end
-# debug utility: write error to file
+ ##debug utility: write error to file
#error_dir = "/tmp/ot_errors"
#FileUtils.mkdir(error_dir) unless File.exist?(error_dir)
#raise "could not create error dir" unless File.exist?(error_dir) and File.directory?(error_dir)
diff --git a/lib/task.rb b/lib/task.rb
index 29fb4fe..dee8a86 100644
--- a/lib/task.rb
+++ b/lib/task.rb
@@ -4,96 +4,105 @@ module OpenTox
class Task
- attr_accessor :uri
+ TASK_ATTRIBS = [ :uri, :date, :title, :creator, :title, :description, :hasStatus, :percentageCompleted, :resultURI ]
+ TASK_ATTRIBS.each{ |a| attr_accessor(a) }
- def initialize(uri)
- @uri = uri.chomp
- end
-
- def self.create
- resource = RestClient::Resource.new(@@config[:services]["opentox-task"], :user => @@users[:users].keys[0], :password => @@users[:users].values[0])
- uri = resource.post({}).chomp
- Task.new(uri.chomp)
+ private
+ def initialize(uri)
+ @uri = uri
+ end
+
+ public
+ def self.create
+ task_uri = RestClientWrapper.post(@@config[:services]["opentox-task"], nil, nil, false).to_s
+ Task.find(task_uri.chomp)
end
def self.find(uri)
- Task.new(uri)
- end
-
- def self.base_uri
- @@config[:services]["opentox-task"]
- end
-
- def self.all
- task_uris = RestClient.get(@@config[:services]["opentox-task"]).chomp.split(/\n/)
- task_uris.collect{|uri| Task.new(uri)}
- end
-
- def created_at
- RestClient.get File.join(@uri, 'created_at')
- end
-
- def finished_at
- RestClient.get File.join(@uri, 'finished_at')
- end
-
- def description
- RestClient.get File.join(@uri, 'description')
+ task = Task.new(uri)
+ task.reload
+ return task
end
- def status
- RestClient.get File.join(@uri, 'status')
- end
-
- def resource
- RestClient.get File.join(@uri, 'resource')
- end
-
- def started
- LOGGER.info File.join(@uri,'started')
- resource = RestClient::Resource.new(File.join(@uri,'started'), :user => @@users[:users].keys[0], :password => @@users[:users].values[0])
- resource.put({})
- end
+ def self.from_data(data, content_type, base_uri)
+ begin
+ task = Task.new(nil)
+ task.reload_from_data(data, content_type, base_uri)
+ return task
+ rescue
+ return nil
+ end
+ end
+
+ def reload
+ result = RestClientWrapper.get(uri)
+ reload_from_data(result, result.content_type)
+ end
+
+ def reload_from_data( data=nil, content_type=nil, base_uri=nil )
+ case content_type
+ when /text\/x-yaml/
+ task = YAML.load data
+ raise "yaml data is no task" if task.is_a?(Task)
+ TASK_ATTRIBS.each{ |a| send("#{a.to_s}=".to_sym,task[a]) }
+ when /application\/rdf\+xml/
+ base_uri = uri unless base_uri
+ owl = OpenTox::Owl.from_data(data,base_uri)
+ raise "not a task" if owl.ot_class=="Task"
+ TASK_ATTRIBS.each{|a| self.send("#{a.to_s}=".to_sym, owl.get(a.to_s))}
+ else
+ raise "content type for tasks not supported: "+content_type.to_s
+ end
+ end
+
+
+ # invalid: getters in task.rb should work for non-internal tasks as well
+ #
+ #def self.base_uri
+ # @@config[:services]["opentox-task"]
+ #end
+ #def self.all
+ # task_uris = RestClientWrapper.get(@@config[:services]["opentox-task"]).chomp.split(/\n/)
+ # task_uris.collect{|uri| Task.new(uri)}
+ #end
def cancel
- resource = RestClient::Resource.new(File.join(@uri,'cancelled'), :user => @@users[:users].keys[0], :password => @@users[:users].values[0])
- resource.put({})
+ RestClientWrapper.put(File.join(@uri,'Cancelled'))
+ reload
end
def completed(uri)
- resource = RestClient::Resource.new(File.join(@uri,'completed'), :user => @@users[:users].keys[0], :password => @@users[:users].values[0])
- resource.put :resource => uri
+ RestClientWrapper.put(File.join(@uri,'Completed'),{:resultURI => uri})
+ reload
end
- def failed(description)
- resource = RestClient::Resource.new(File.join(@uri,'failed'), :user => @@users[:users].keys[0], :password => @@users[:users].values[0])
- resource.put :description => description
- #resource.put({})
+ def error(description)
+ RestClientWrapper.put(File.join(@uri,'Error'),{:description => description})
+ reload
end
def parent=(task)
- #RestClient.put File.join(@uri,'parent'), {:uri => task.uri}
- resource = RestClient::Resource.new(File.join(@uri,'parent'), :user => @@users[:users].keys[0], :password => @@users[:users].values[0])
- LOGGER.debug "task.rb: #{resource}"
- resource.put :uri => task.uri
+ RestClientWrapper.put(File.join(@uri,'parent'), {:uri => task.uri})
+ reload
end
def pid=(pid)
- resource = RestClient::Resource.new(File.join(@uri,'pid'), :user => @@users[:users].keys[0], :password => @@users[:users].values[0])
- resource.put :pid => pid
+ RestClientWrapper.put(File.join(@uri,'pid'), {:pid => pid})
+ reload
end
def completed?
- self.status.to_s == 'completed'
+ @hasStatus.to_s == 'Completed'
end
- def failed?
- self.status.to_s == 'failed'
+ def error?
+ @hasStatus.to_s == 'Error'
end
def wait_for_completion(dur=0.1)
- until self.completed? or self.failed?
+ until self.completed? or self.error?
sleep dur
+ reload
end
end
@@ -102,29 +111,28 @@ module OpenTox
task = OpenTox::Task.create
task.parent = parent_task if parent_task
- LOGGER.debug "Starting task"
pid = Spork.spork(:logger => LOGGER) do
- task.started
LOGGER.debug "Task #{task.uri} started #{Time.now}"
begin
result = catch(:halt) do
yield task
+ LOGGER.debug "Task #{task.uri} done #{Time.now}"
end
if result && result.is_a?(Array) && result.size==2 && result[0]>202
# halted while executing task
LOGGER.error "task was halted: "+result.inspect
- task.failed(result[1])
+ task.error(result[1])
throw :halt,result
end
task.completed(result)
rescue => ex
#raise ex
LOGGER.error "task failed: "+ex.message
- task.failed(ex.message)
+ task.error(ex.message)
end
- raise "Invalid task state" unless task.completed? || task.failed?
+ raise "Invalid task state" unless task.completed? || task.error?
end
- LOGGER.debug "task PID: " + pid.to_s
+ LOGGER.debug "Started task with PID: " + pid.to_s
task.pid = pid
task.uri
end