diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | lib/error.rb | 87 | ||||
-rw-r--r-- | lib/opentox-client.rb | 3 | ||||
-rw-r--r-- | lib/opentox.rb | 14 | ||||
-rw-r--r-- | lib/rest-client-wrapper.rb | 3 | ||||
-rw-r--r-- | lib/task.rb | 28 |
6 files changed, 58 insertions, 79 deletions
@@ -1,5 +1,5 @@ +Gemfile.lock *.gem .bundle -Gemfile.lock pkg/* *~ diff --git a/lib/error.rb b/lib/error.rb index 579f42b..64b0fb1 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,57 +87,4 @@ module OpenTox end end - # TODO: create reports directly from errors, requires modified task service - class ErrorReport - def initialize http_code, error - @http_code = http_code - @report = {} - @report[RDF::OT.actor] = error.uri.to_s - @report[RDF::OT.message] = error.message.to_s - @report[RDF::OT.statusCode] = @http_code - @report[RDF::OT.errorCode] = error.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 - @report[RDF::OT.errorDetails] = backtrace[0..cut_index].join("\n") - @report[RDF::OT.errorDetails] += "REST paramenters:\n#{error.request.args.inspect}" if defined? error.request - #@report[RDF::OT.message] += "\n" + error.response.body.to_s if defined? error.response - # TODO fix Error cause - # should point to another errorReport, but errorReports do not have URIs - # create a separate service? - #report[RDF::OT.errorCause] = @report if defined?(@report) - end - - # 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 - @report.each do |predicate,object| - writer << [subject, predicate, object] if object - end - end - rdf - end - -=begin - define_singleton_method "from_#{format}".to_sym do |rdf| - report = ErrorReport.new - RDF::Reader.for(format).new(rdf) do |reader| - reader.each_statement{ |statement| report.rdf << statement } - end - report - end -=end - end - end end diff --git a/lib/opentox-client.rb b/lib/opentox-client.rb index dec3512..8c19225 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 @@ -14,10 +15,8 @@ RDF::OT = RDF::Vocabulary.new 'http://www.opentox.org/api/1.2#' RDF::OT1 = RDF::Vocabulary.new 'http://www.opentox.org/api/1.1#' 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 = "application/rdf+xml" # Regular expressions for parsing classification data TRUE_REGEXP = /^(true|active|1|1.0|tox|activating|carcinogen|mutagenic)$/i diff --git a/lib/opentox.rb b/lib/opentox.rb index 6ce439d..f79b51b 100644 --- a/lib/opentox.rb +++ b/lib/opentox.rb @@ -21,8 +21,9 @@ 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_ntriples RestClientWrapper.get(@uri,{},{:accept => "text/plain", :subjectid => @subjectid}) + rescue # fall back to rdfxml + parse_rdfxml RestClientWrapper.get(@uri,{},{:accept => "application/rdf+xml", :subjectid => @subjectid}) end # Get object metadata @@ -47,8 +48,9 @@ module OpenTox # Save object at service def save - #TODO: dynamic assignment - post self.to_rdfxml, { :content_type => $default_rdf} + put self.to_ntriples, { :content_type => "text/plain"} + rescue # fall back to rdfxml + put self.to_rdfxml, { :content_type => "application/rdf+xml"} end RDF_FORMATS.each do |format| @@ -111,7 +113,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 +128,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/rest-client-wrapper.rb b/lib/rest-client-wrapper.rb index 3071432..479d5a5 100644 --- a/lib/rest-client-wrapper.rb +++ b/lib/rest-client-wrapper.rb @@ -18,8 +18,7 @@ module OpenTox # check input @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| diff --git a/lib/task.rb b/lib/task.rb index bcf806e..d45b0d2 100644 --- a/lib/task.rb +++ b/lib/task.rb @@ -6,15 +6,25 @@ module OpenTox attr_accessor :pid, :observer_pid - def self.create service_uri, params={} - - task = Task.new RestClientWrapper.post(service_uri,params).chomp + def self.create service_uri, subjectid=nil, params={} + + uri = RDF::URI.new File.join(service_uri,SecureRandom.uuid) + task = Task.new uri, subjectid + 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')) + end task.kill end end @@ -58,7 +68,8 @@ module OpenTox end def completed(uri) - #not_found_error "Result URI \"#{uri}\" does not exist." unless URI.accessible? uri + #puts uri + #not_found_error "Result URI \"#{uri}\" does not exist." unless URI.accessible? uri, @subjectid RestClientWrapper.put(File.join(@uri,'Completed'),{:resultURI => uri}) end @@ -68,7 +79,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 @@ -96,11 +107,6 @@ module OpenTox code >= 400 and code != 503 end - def errorReport - # TODO: fix rdf output at task service - not_implemented_error "RDF output of errorReports has to be fixed at task service" - end - [:hasStatus, :resultURI].each do |method| define_method method do response = self.[](RDF::OT[method]) |