# This file is part of CPEE. # # CPEE is free software: you can redistribute it and/or modify it under the terms # of the GNU General Public License as published by the Free Software Foundation, # either version 3 of the License, or (at your option) any later version. # # CPEE is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # CPEE (file COPYING in the main directory). If not, see # . class LogHandlerWrapper < WEEL::HandlerWrapperBase LOGTEMPLATE = <<-END END def initialize(arguments,endpoint=nil,position=nil,continue=nil) # {{{ @controller = arguments[0] @log_hash = {} @handler_continue = continue @handler_endpoint = endpoint @handler_position = position @handler_passthrough = nil @handler_returnValue = nil instancenr=@controller.instance.split('/').last instance_dir = @controller.instance_variable_get(:@opts)[:instances] XML::Smart.modify(instance_dir+'/'+instancenr+'/log.xes',LOGTEMPLATE) do |xml| trace = xml.find("/xmlns:log/xmlns:trace").first trace.add 'string', :key => "concept:name", :value => "Instance #{instancenr}" end end # }}} def activity_handle(passthrough, parameters) # {{{ @controller.notify("activity/calling", :instance => @controller.instance, :activity => @handler_position, :passthrough => passthrough, :endpoint => @handler_endpoint, :parameters => parameters, :log_hash => @log_hash) instancenr=@controller.instance.split('/').last instance_dir = @controller.instance_variable_get(:@opts)[:instances] unless File.exist?(instance_dir+'/'+instancenr+'/log.xes') FileUtils.cp(instance_dir+'/template.xes', instance_dir+'/'+instancenr+'/log.xes') XML::Smart.modify(instance_dir+'/'+instancenr+'/log.xes') do |xml| trace = xml.find("/xmlns:log/xmlns:trace").first trace.add 'string', :key => "concept:name", :value => "Instance #{instancenr}" end end @log_hash[:label]||=parameters[:label] @log_hash[:data_send]||=parameters[:arguments] unless parameters[:arguments].nil? result = [] if passthrough.nil? params = [] callback = Digest::MD5.hexdigest(Kernel::rand().to_s) (parameters[:arguments] || {}).each do |k,v| if v.is_a?(Struct) if v.respond_to?(:mimetype) params << Riddl::Parameter::Complex.new("#{k}",v.mimetype,v.value) else params << Riddl::Parameter::Simple.new("#{k}",CPEE::ValueHelper::generate(v.value)) end else params << Riddl::Parameter::Simple.new("#{k}",CPEE::ValueHelper::generate(v)) end end params << Riddl::Header.new("CPEE_BASE",@controller.base_url) params << Riddl::Header.new("CPEE_INSTANCE",@controller.instance_url) params << Riddl::Header.new("CPEE_CALLBACK",@controller.instance_url + '/callbacks/' + callback) params << Riddl::Header.new("CPEE_ACTIVITY",@handler_position) params << Riddl::Header.new("CPEE_LABEL",parameters[:label]) @controller.attributes.each do |key,value| params << Riddl::Header.new("CPEE_ATTR_#{key}",value) end type = parameters[:method] || 'post' client = Riddl::Client.new(@handler_endpoint) status, result, headers = client.request type => params raise "Could not #{parameters[:method] || 'post'} #{@handler_endpoint}" if status != 200 if headers["CPEE_CALLBACK"] && headers["CPEE_CALLBACK"] == 'true' @controller.callbacks[callback] = CPEE::Callback.new("callback activity: #{@handler_position}",self,:callback,nil,nil,:http) @handler_passthrough = callback else callback result end else @controller.callbacks[passthrough] = CPEE::Callback.new("callback activity: #{@handler_position}",self,:callback,nil,nil,:http) @handler_passthrough = passthrough end end # }}} def activity_result_status # {{{ WEEL::Status.new(1, "everything okay") end # }}} def activity_result_value # {{{ @handler_returnValue end # }}} def activity_stop # {{{ unless @handler_passthrough.nil? @controller.callbacks.delete(@handler_passthrough) end end # }}} def activity_passthrough_value # {{{ @handler_passthrough end # }}} def activity_no_longer_necessary # {{{ true end # }}} def inform_activity_done # {{{ @controller.notify("activity/done", :endpoint => @handler_endpoint, :instance => @controller.instance, :activity => @handler_position,:log_hash => @log_hash) time_added=false XML::Smart.modify(@controller.instance_variable_get(:@opts)[:instances]+'/'+@controller.instance.split('/').last+'/log.xes') do |xml| trace = xml.find("/xmlns:log/xmlns:trace").first event = trace.add "event" event.add 'string', :key => "concept:name", :value => @log_hash[:label] if @log_hash.has_key?(:data_send) list = event.add 'list', :key => "data_send" @log_hash[:data_send].each do |k,v| list.add 'string', :key => k , :value => v end end if @log_hash.has_key?(:data_received) @log_hash[:data_received].delete_if do |e| if e.keys[0]=="timestamp" event.add 'date', :key => "time:timestamp", :value => e.values[0] time_added=true true else false end end if @log_hash[:data_received].length > 0 list = event.add 'list', :key => "data_received" @log_hash[:data_received].each{|e| list.add 'string', :key => e.keys[0] , :value => e.values[0]} end end event.add 'date', :key => "time:timestamp", :value => Time.now unless time_added end end # }}} def inform_activity_manipulate # {{{ @controller.notify("activity/manipulating", :endpoint => @handler_endpoint, :instance => @controller.instance, :activity => @handler_position) end # }}} def inform_activity_failed(err) # {{{ puts err.message puts err.backtrace @controller.notify("activity/failed", :endpoint => @handler_endpoint, :instance => @controller.instance, :activity => @handler_position, :message => err.message, :line => err.backtrace[0].match(/(.*?):(\d+):/)[2], :where => err.backtrace[0].match(/(.*?):(\d+):/)[1]) end # }}} def inform_syntax_error(err,code)# {{{ @controller.notify("description/error", :instance => @controller.instance, :message => err.message) end# }}} def inform_manipulate_change(status,changed_dataelements,changed_endpoints,dataelements,endpoints) # {{{ unless status.nil? @controller.serialize_status! @controller.notify("status/change", :endpoint => @handler_endpoint, :instance => @controller.instance, :activity => @handler_position, :id => status.id, :message => status.message) end unless changed_dataelements.nil? @controller.serialize_dataelements! @controller.notify("dataelements/change", :endpoint => @handler_endpoint, :instance => @controller.instance, :activity => @handler_position, :changed => changed_dataelements) end unless changed_endpoints.nil? @controller.serialize_endpoints! @controller.notify("endpoints/change", :endpoint => @handler_endpoint, :instance => @controller.instance, :activity => @handler_position, :changed => changed_endpoints) end end # }}} def inform_position_change(ipc={}) # {{{ @controller.serialize_positions! ipc[:instance] = @controller.instance @controller.notify("position/change", ipc) end # }}} def inform_state_change(newstate) # {{{ if @controller @controller.serialize_state! @controller.notify("state/change", :instance => @controller.instance, :state => newstate) end end # }}} def vote_sync_after # {{{ @controller.call_vote("activity/syncing_after", :endpoint => @handler_endpoint, :instance => @controller.instance, :activity => @handler_position) end # }}} def vote_sync_before(parameters=nil) # {{{ @controller.call_vote("activity/syncing_before", :endpoint => @handler_endpoint, :instance => @controller.instance, :activity => @handler_position) end # }}} def simplify_result(result) tmp = result.map do |r| if r.is_a? Riddl::Parameter::Simple {r.name => r.value} elsif r.is_a? Riddl::Parameter::Complex if r.mimetype == 'application/json' x = JSON::parse(r.value.read) r.value.rewind x elsif r.mimetype == 'application/xml' || r.mimetype == 'text/xml' x = {"xml" => XML::Smart::string(result[0].value.read)} x elsif r.mimetype == 'text/plain' {"plain_text" => r.value.read} elsif r.mimetype == 'text/html' {"html_text" => r.value.read} else r end end end if result.length == 1 if result[0].is_a? Riddl::Parameter::Simple result = result[0].value elsif result[0].is_a? Riddl::Parameter::Complex if result[0].mimetype == 'application/json' result = JSON::parse(result[0].value.read) elsif result[0].mimetype == 'application/xml' || result[0].mimetype == 'text/xml' result = XML::Smart::string(result[0].value.read) elsif result[0].mimetype == 'text/plain' result = result[0].value.read elsif result[0].mimetype == 'text/html' result[0].value.read else result = result[0] end end end [result,tmp] end def callback(result=nil,options={}) result,notify_result = simplify_result(result) @controller.notify("activity/change", :instance => @controller.instance, :activity => @handler_position, :endpoint => @handler_endpoint, :params => notify_result) @log_hash[:data_received]||=notify_result unless notify_result.nil? if options['CPEE_UPDATE'] @handler_returnValue = result if options['CPEE_UPDATE_STATUS'] @controller.notify("activity/status", :instance => @controller.instance, :activity => @handler_position, :endpoint => @handler_endpoint, :status => options['CPEE_UPDATE_STATUS']) end @handler_continue.continue WEEL::Signal::Again else @controller.callbacks.delete(@handler_passthrough) @handler_returnValue = result @handler_passthrough = nil @handler_continue.continue end end def simulate(type,nesting,tid,parent,parameters={}) #{{{ pp "#{type} - #{nesting} - #{tid} - #{parent} - #{parameters.inspect}" @controller.call_vote("simulating/step", :endpoint => @handler_endpoint, :instance => @controller.instance, :activity => tid, :type => type, :nesting => nesting, :parent => parent, :parameters => parameters ) end #}}} end