From 1d49fe0da8e7d4dfc57fdbfffdc4e32db2ef0647 Mon Sep 17 00:00:00 2001 From: Christoph Helma Date: Wed, 2 May 2012 20:06:16 +0000 Subject: initial task service --- lib/error.rb | 38 ++++++++++++++++++++++++++++++++------ lib/opentox-client.rb | 2 ++ lib/opentox.rb | 9 +++++---- lib/overwrite.rb | 3 ++- lib/rest-client-wrapper.rb | 6 ++++-- lib/task.rb | 23 +++++++++++++++++++---- 6 files changed, 64 insertions(+), 17 deletions(-) (limited to 'lib') diff --git a/lib/error.rb b/lib/error.rb index 579f42b..58b9816 100644 --- a/lib/error.rb +++ b/lib/error.rb @@ -7,12 +7,38 @@ class RuntimeError super message @uri = uri @http_code ||= 500 - $logger.error "\n"+self.report.to_turtle + $logger.error "\n"+self.to_turtle end - def report - # TODO: remove kludge for old task services - OpenTox::ErrorReport.new(@http_code, self) + # define to_ and self.from_ methods for various rdf formats + RDF_FORMATS.each do |format| + + send :define_method, "to_#{format}".to_sym do + rdf = RDF::Writer.for(format).buffer do |writer| + # TODO: not used for turtle + # http://rdf.rubyforge.org/RDF/Writer.html# + writer.prefix :ot, RDF::URI('http://www.opentox.org/api/1.2#') + writer.prefix :ot1_1, RDF::URI('http://www.opentox.org/api/1.1#') + subject = RDF::Node.new + writer << [subject, RDF.type, RDF::OT.ErrorReport] + writer << [subject, RDF::OT.actor, @uri.to_s] + writer << [subject, RDF::OT.message, @message.to_s] + writer << [subject, RDF::OT.statusCode, @http_code] + writer << [subject, RDF::OT.errorCode, self.class.to_s] + + # cut backtrace + backtrace = caller.collect{|line| line unless line =~ /#{File.dirname(__FILE__)}/}.compact + cut_index = backtrace.find_index{|line| line.match /sinatra|minitest/} + cut_index ||= backtrace.size + cut_index -= 1 + cut_index = backtrace.size-1 if cut_index < 0 + details = backtrace[0..cut_index].join("\n") + details += "REST paramenters:\n#{@request.args.inspect}" if @request + writer << [subject, RDF::OT.errorCause, details] + end + rdf + end + end end @@ -61,6 +87,7 @@ module OpenTox end end +=begin # TODO: create reports directly from errors, requires modified task service class ErrorReport def initialize http_code, error @@ -103,7 +130,6 @@ module OpenTox rdf end -=begin define_singleton_method "from_#{format}".to_sym do |rdf| report = ErrorReport.new RDF::Reader.for(format).new(rdf) do |reader| @@ -111,7 +137,7 @@ module OpenTox end report end -=end end end +=end end diff --git a/lib/opentox-client.rb b/lib/opentox-client.rb index dec3512..0546634 100644 --- a/lib/opentox-client.rb +++ b/lib/opentox-client.rb @@ -7,6 +7,7 @@ require 'uri' require 'yaml' require 'json' require 'logger' +require "securerandom" # define constants and global variables #TODO: switch services to 1.2 @@ -17,6 +18,7 @@ RDF::OTA = RDF::Vocabulary.new 'http://www.opentox.org/algorithmTypes.owl#' #CLASSES = ["Compound", "Feature", "Dataset", "Algorithm", "Model", "Validation", "Task", "ErrorReport", "Investigation"] CLASSES = ["Generic", "Compound", "Feature", "Dataset", "Algorithm", "Model", "Validation", "Task", "Investigation"] RDF_FORMATS = [:rdfxml,:ntriples,:turtle] +#$default_rdf = "text/plain" $default_rdf = "application/rdf+xml" # Regular expressions for parsing classification data diff --git a/lib/opentox.rb b/lib/opentox.rb index 6ce439d..2682258 100644 --- a/lib/opentox.rb +++ b/lib/opentox.rb @@ -22,7 +22,8 @@ module OpenTox # Load metadata from service def pull # TODO generic method for all formats - parse_rdfxml RestClientWrapper.get(@uri,{},{:accept => $default_rdf, :subjectid => @subjectid}) + #parse_rdfxml RestClientWrapper.get(@uri,{},{:accept => $default_rdf, :subjectid => @subjectid}) + parse_ntriples RestClientWrapper.get(@uri,{},{:accept => "text/plain", :subjectid => @subjectid}) end # Get object metadata @@ -48,7 +49,7 @@ module OpenTox # Save object at service def save #TODO: dynamic assignment - post self.to_rdfxml, { :content_type => $default_rdf} + put self.to_rdfxml, { :content_type => $default_rdf} end RDF_FORMATS.each do |format| @@ -111,7 +112,7 @@ module OpenTox end def create service_uri, subjectid=nil - #uri = uri(SecureRandom.uuid) + #uri = File.join(service_uri,SecureRandom.uuid) uri = RestClientWrapper.post(service_uri, {}, {:accept => 'text/uri-list', :subjectid => subjectid}) URI.task?(service_uri) ? from_uri(uri, subjectid, false) : from_uri(uri, subjectid) end @@ -126,7 +127,7 @@ module OpenTox uri.chomp! # TODO add waiting task - if URI.task? uri and wait + if URI.task?(uri) and wait t = OpenTox::Task.new(uri) t.wait uri = t.resultURI diff --git a/lib/overwrite.rb b/lib/overwrite.rb index d98769e..37c0bb3 100644 --- a/lib/overwrite.rb +++ b/lib/overwrite.rb @@ -15,7 +15,8 @@ module URI end def self.task? uri - uri =~ /task/ and URI.valid? uri + #TODO remove localhost + (uri =~ /task/ or uri =~ /localhost/) and URI.valid? uri end def self.dataset? uri, subjectid=nil diff --git a/lib/rest-client-wrapper.rb b/lib/rest-client-wrapper.rb index 3071432..af1ba42 100644 --- a/lib/rest-client-wrapper.rb +++ b/lib/rest-client-wrapper.rb @@ -19,7 +19,7 @@ module OpenTox @subjectid = headers[:subjectid] ? headers[:subjectid] : nil bad_request_error "Invalid URI: '#{uri}'" unless URI.valid? uri #TODO fix for internal installations - #not_found_error "URI '#{uri}' not found." unless URI.accessible?(uri, @subjectid) unless URI.ssl?(uri) + not_found_error "URI '#{uri}' not found." unless URI.accessible?(uri, @subjectid) unless URI.ssl?(uri) bad_request_error "Headers are not a hash: #{headers.inspect}" unless headers==nil or headers.is_a?(Hash) # make sure that no header parameters are set in the payload [:accept,:content_type,:subjectid].each do |header| @@ -44,7 +44,9 @@ module OpenTox if [301, 302, 307].include? response.code and request.method == :get response.follow_redirection(request, result) else - raise OpenTox::RestCallError.new response.to_s, request, uri unless response.code < 400 or URI.task? uri + #TODO Reactivate for external services + #raise OpenTox::RestCallError.new response.to_s, request, uri unless response.code < 400 or URI.task? uri + rest_call_error response.to_s, request, uri unless response.code < 400 or URI.task? uri response end end diff --git a/lib/task.rb b/lib/task.rb index bcf806e..4cdbb51 100644 --- a/lib/task.rb +++ b/lib/task.rb @@ -8,13 +8,27 @@ module OpenTox def self.create service_uri, params={} - task = Task.new RestClientWrapper.post(service_uri,params).chomp + uri = RDF::URI.new File.join(service_uri,SecureRandom.uuid) + #uri = RestClientWrapper.post service_uri + #puts uri + task = Task.new uri + #task.pull + #puts task.to_turtle + task.rdf << RDF::Statement.new(uri, RDF.type, RDF::OT.Task) + task.rdf << RDF::Statement.new(uri, RDF::DC.date, RDF::Literal.new(DateTime.now)) + task.rdf << RDF::Statement.new(uri, RDF::OT.hasStatus, RDF::Literal.new("Running")) + params.each {|k,v| task.rdf << RDF::Statement.new(uri, k, v)} + task.save pid = fork do begin result_uri = yield task.completed result_uri rescue - RestClientWrapper.put(File.join(task.uri,'Error'),{:errorReport => $!.report.to_yaml}) if $!.respond_to? :report + if $!.respond_to? :to_ntriples + RestClientWrapper.put(File.join(task.uri,'Error'),:errorReport => $!.to_ntriples,:content_type => 'text/plain') + else + RestClientWrapper.put(File.join(task.uri,'Error')) #if $!.respond_to? :report + end task.kill end end @@ -58,7 +72,8 @@ module OpenTox end def completed(uri) - #not_found_error "Result URI \"#{uri}\" does not exist." unless URI.accessible? uri + #TODO fix for https rewrites + not_found_error "Result URI \"#{uri}\" does not exist." unless URI.accessible? uri RestClientWrapper.put(File.join(@uri,'Completed'),{:resultURI => uri}) end @@ -68,7 +83,7 @@ module OpenTox def wait start_time = Time.new due_to_time = start_time + DEFAULT_TASK_MAX_DURATION - dur = 0 + dur = 0.3 while running? sleep dur dur = [[(Time.new - start_time)/20.0,0.3].max,300.0].min -- cgit v1.2.3