server/executionhandlers/ruby/connection.rb in cpee-2.1.70 vs server/executionhandlers/ruby/connection.rb in cpee-2.1.71
- old
+ new
@@ -34,22 +34,24 @@
controller.notify("state/change", :state => newstate)
end # }}}
def self::inform_syntax_error(arguments,err,code)# {{{
# TODO extract spot (code) where error happened for better error handling (ruby 3.1 only)
# https://github.com/rails/rails/pull/45818/commits/3beb2aff3be712e44c34a588fbf35b79c0246ca5
- puts err.message
- puts err.backtrace
controller = arguments[0]
- mess = err.backtrace ? err.backtrace[0].gsub(/([\w -_]+):(\d+):in.*/,'\\1, Line \2: ') : ''
- mess += err.message
- controller.notify("description/error", :message => mess)
+ begin
+ controller.notify("description/error", :message => err.backtrace[0].match(/(.*?)(, Line |:)(\d+):\s(.*)/)[4] + err.message, :line => err.backtrace[0].match(/(.*?)(, Line |:)(\d+):/)[3], :where => err.backtrace[0].match(/(.*?)(, Line |:)(\d+):/)[1])
+ rescue => e
+ controller.notify("description/error", :message => err.message)
+ end
end# }}}
def self::inform_connectionwrapper_error(arguments,err) # {{{
controller = arguments[0]
- puts err.message
- puts err.backtrace
- controller.notify("executionhandler/error", :message => err.backtrace[0].gsub(/([\w -_]+):(\d+):in.*/,'\\1, Line \2: ') + err.message)
+ begin
+ controller.notify("executionhandler/error", :message => err.backtrace[0].match(/(.*?)(, Line |:)(\d+):\s(.*)/)[4] + err.message, :line => err.backtrace[0].match(/(.*?)(, Line |:)(\d+):/)[3], :where => err.backtrace[0].match(/(.*?)(, Line |:)(\d+):/)[1])
+ rescue => e
+ controller.notify("executionhandler/error", :message => err.message)
+ end
end # }}}
def self::inform_position_change(arguments,ipc={}) # {{{
controller = arguments[0]
controller.notify("position/change", ipc)
end # }}}
@@ -72,10 +74,11 @@
:attributes => @controller.attributes,
:cpee => {
'base' => @controller.base_url,
'instance' => @controller.instance_id,
'instance_url' => @controller.instance_url,
+ 'instance_url_encoded' => Riddl::Protocols::Utils::escape(@controller.instance_url),
'instance_uuid' => @controller.uuid
},
:task => {
'label' => @label,
'id' => @handler_position
@@ -110,11 +113,11 @@
params << Riddl::Header.new("CPEE-INSTANCE-UUID",@controller.uuid)
params << Riddl::Header.new("CPEE-CALLBACK",File.join(@controller.instance_url,'callbacks',callback,'/'))
params << Riddl::Header.new("CPEE-CALLBACK-ID",callback)
params << Riddl::Header.new("CPEE-ACTIVITY",@handler_position)
params << Riddl::Header.new("CPEE-LABEL",@label||'')
- params << Riddl::Header.new("CPEE-TWIN-TARGET",@controller.attributes['twin_target']) if @controller.attributes['twin_target']
+ params << Riddl::Header.new("CPEE-SIM-TARGET",@controller.attributes['sim_target']) if @controller.attributes['sim_target']
@controller.attributes.each do |key,value|
params << Riddl::Header.new("CPEE-ATTR-#{key.to_s.gsub(/_/,'-')}",value)
end
status = result = headers = nil
@@ -129,15 +132,15 @@
status, result, headers = client.request type => params
@guard_files += result
if status == 561
- if @controller.attributes['twin_translate']
- gettrans = Riddl::Client.new(@controller.attributes['twin_translate'])
+ if @controller.attributes['sim_translate']
+ gettrans = Riddl::Client.new(@controller.attributes['sim_translate'])
gtstatus, gtresult, gtheaders = gettrans.get
if gtstatus >= 200 && gtstatus < 300
- transwhat = case headers['CPEE-TWIN-TASKTYPE']
+ transwhat = case headers['CPEE-SIM-TASKTYPE']
when 'i'; 'instantiation'
when 'ir'; 'ipc-receive'
when 'is'; 'ipc-send'
else
'instantiation'
@@ -186,14 +189,14 @@
if headers['CPEE_CALLBACK'] && headers['CPEE_CALLBACK'] == 'true' && result.any?
headers['CPEE_UPDATE'] = true
callback result, headers
elsif headers['CPEE_CALLBACK'] && headers['CPEE_CALLBACK'] == 'true' && result.empty?
if headers['CPEE_INSTANTIATION']
- @controller.notify("task/instantiation", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint, :received => CPEE::ValueHelper.parse(headers['CPEE_INSTANTIATION']))
+ @controller.notify("task/instantiation", :ecid => Thread.current.__id__, :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint, :received => CPEE::ValueHelper.parse(headers['CPEE_INSTANTIATION']))
end
if headers['CPEE_EVENT']
- @controller.notify("task/#{headers['CPEE_EVENT'].gsub(/[^\w_-]/,'')}", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint)
+ @controller.notify("task/#{headers['CPEE_EVENT'].gsub(/[^\w_-]/,'')}", :ecid => Thread.current.__id__, :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint)
end
# do nothing, later on things will happend
else
callback result, headers
end
@@ -203,11 +206,11 @@
def activity_handle(passthrough, parameters) # {{{
raise "Wrong endpoint" if @handler_endpoint.nil? || @handler_endpoint.empty?
@label = parameters[:label]
@anno = parameters.delete(:annotations) rescue nil
@controller.notify("status/resource_utilization", :mib => GetProcessMem.new.mb, **Process.times.to_h)
- @controller.notify("activity/calling", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :passthrough => passthrough, :endpoint => @handler_endpoint, :parameters => parameters, :annotations => @anno)
+ @controller.notify("activity/calling", :ecid => Thread.current.__id__, :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :passthrough => passthrough, :endpoint => @handler_endpoint, :parameters => parameters, :annotations => @anno)
if passthrough.to_s.empty?
proto_curl parameters
else
@controller.callback(self,passthrough,:'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position)
@handler_passthrough = passthrough
@@ -240,24 +243,22 @@
def activity_uuid #{{{
@handler_activity_uuid
end #}}}
def inform_activity_done # {{{
- @controller.notify("activity/done", :'activity-uuid' => @handler_activity_uuid, :endpoint => @handler_endpoint, :label => @label, :activity => @handler_position)
+ @controller.notify("activity/done", :ecid => Thread.current.__id__, :'activity-uuid' => @handler_activity_uuid, :endpoint => @handler_endpoint, :label => @label, :activity => @handler_position)
@controller.notify("status/resource_utilization", :mib => GetProcessMem.new.mb, **Process.times.to_h)
end # }}}
def inform_activity_manipulate # {{{
- @controller.notify("activity/manipulating", :'activity-uuid' => @handler_activity_uuid, :endpoint => @handler_endpoint, :label => @label, :activity => @handler_position)
+ @controller.notify("activity/manipulating", :ecid => Thread.current.__id__, :'activity-uuid' => @handler_activity_uuid, :endpoint => @handler_endpoint, :label => @label, :activity => @handler_position)
end # }}}
def inform_activity_failed(err) # {{{
- puts err.message
- puts err.backtrace
- @controller.notify("activity/failed", :'activity-uuid' => @handler_activity_uuid, :endpoint => @handler_endpoint, :label => @label, :activity => @handler_position, :message => err.message, :line => err.backtrace[0].match(/(.*?):(\d+):/)[2], :where => err.backtrace[0].match(/(.*?):(\d+):/)[1])
+ @controller.notify("activity/failed", :ecid => Thread.current.__id__, :'activity-uuid' => @handler_activity_uuid, :endpoint => @handler_endpoint, :label => @label, :activity => @handler_position, :message => err.backtrace[0].match(/(.*?):(\d+):\s(.*)/)[3], :line => err.backtrace[0].match(/(.*?):(\d+):/)[2], :where => err.backtrace[0].match(/(.*?):(\d+):/)[1])
end # }}}
def inform_manipulate_change(status,changed_dataelements,changed_endpoints,dataelements,endpoints) # {{{
unless status.nil?
- @controller.notify("status/change", :'activity-uuid' => @handler_activity_uuid, :endpoint => @handler_endpoint, :label => @label, :activity => @handler_position, :id => status.id, :message => status.message)
+ @controller.notify("status/change", :ecid => Thread.current.__id__, :'activity-uuid' => @handler_activity_uuid, :endpoint => @handler_endpoint, :label => @label, :activity => @handler_position, :id => status.id, :message => status.message)
end
unless changed_dataelements.nil? || changed_dataelements.empty?
de = dataelements.slice(*changed_dataelements).transform_values { |v| enc = CPEE::EvalRuby::Translation::detect_encoding(v); (enc == 'OTHER' ? v : (v.encode('UTF-8',enc) rescue CPEE::EvalRuby::Translation::convert_to_base64(v))) }
@controller.notify("dataelements/change", :'activity-uuid' => @handler_activity_uuid, :endpoint => @handler_endpoint, :label => @label, :activity => @handler_position, :changed => changed_dataelements, :values => de)
end
@@ -272,26 +273,33 @@
def vote_sync_before(parameters=nil) # {{{
@controller.vote("activity/syncing_before", :'activity-uuid' => @handler_activity_uuid, :endpoint => @handler_endpoint, :activity => @handler_position, :label => @label, :parameters => parameters)
end # }}}
def callback(result=nil,options={}) #{{{
- recv = CPEE::EvalRuby::Translation::structurize_result(result)
- @controller.notify("activity/receiving", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint, :received => recv, :annotations => @anno)
+ status, ret, headers = Riddl::Client.new(@controller.url_result_transformation).request 'put' => result
+ recv = if status >= 200 && status < 300
+ JSON::parse(ret[0].value.read)
+ else
+ nil
+ end
+ @controller.notify("activity/receiving", :ecid => Thread.current.__id__, :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint, :received => recv, :annotations => @anno)
+
@guard_files += result
+ @guard_files += ret
if options['CPEE_INSTANTIATION']
- @controller.notify("task/instantiation", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint, :received => CPEE::ValueHelper.parse(options['CPEE_INSTANTIATION']))
+ @controller.notify("task/instantiation", :ecid => Thread.current.__id__, :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint, :received => CPEE::ValueHelper.parse(options['CPEE_INSTANTIATION']))
end
if options['CPEE_EVENT']
- @controller.notify("task/#{options['CPEE_EVENT'].gsub(/[^\w_-]/,'')}", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint, :received => recv)
+ @controller.notify("task/#{options['CPEE_EVENT'].gsub(/[^\w_-]/,'')}", :ecid => Thread.current.__id__, :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint, :received => recv)
else
@handler_returnValue = recv
@handler_returnOptions = options
end
if options['CPEE_STATUS']
- @controller.notify("activity/status", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint, :status => options['CPEE_STATUS'])
+ @controller.notify("activity/status", :ecid => Thread.current.__id__, :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint, :status => options['CPEE_STATUS'])
end
if options['CPEE_UPDATE']
@handler_continue.continue WEEL::Signal::UpdateAgain
else
@controller.cancel_callback(@handler_passthrough)
@@ -316,50 +324,139 @@
true
end
GC.start
end #}}}
- def prepare(__lock,__dataelements,__endpoints,__status,__local,__additional,__code,__exec_endpoints,__exec_parameters) #{{{
- __struct = if __code
- manipulate(true,__lock,__dataelements,__endpoints,__status,__local,__additional,__code,'Parameter')
+ def code_error_handling(ret,where,what=RuntimeError) #{{{
+ sig = ret.find{|e| e.name == "signal" }.value
+ sigt = ret.find{|e| e.name == "signal_text" }.value
+ case sig
+ when 'Signal::Again'; throw WEEL::Signal::Again
+ when 'Signal::Error'; raise what, '', [where + ' ' + sigt]
+ when 'Signal::Stop'; raise WEEL::Signal::Stop
+ when 'Signal::SyntaxError'; raise SyntaxError, '', [where + ' ' + sigt]
+ else
+ raise 'something bad happened, but we dont know what.'
+ end
+ end #}}}
+
+ def argument_transform_value(obj, struct)
+ return nil unless obj.is_a?(Array) || obj.is_a?(Hash) || obj.is_a?(WEEL::ProcString)
+ case obj
+ when Hash
+ obj.each { |k, v| ret = argument_transform_value(v, struct); obj[k] = ret unless ret.nil? }
+ nil
+ when Array
+ obj.each_with_index { |v,i| ret = argument_transform_value(v, struct); obj[i] = ret unless ret.nil? }
+ nil
+ when WEEL::ProcString
+ argument_eval obj.code, struct
+ end
+ end
+
+ def argument_eval(code,struct)
+ send = []
+ send.push Riddl::Parameter::Simple::new('code',code)
+ send.push Riddl::Parameter::Complex::new('dataelements','application/json', JSON::generate(struct.data))
+ send.push Riddl::Parameter::Complex::new('local','application/json', JSON::generate(struct.local)) if struct.local
+ send.push Riddl::Parameter::Complex::new('endpoints','application/json', JSON::generate(struct.endpoints))
+ send.push Riddl::Parameter::Complex::new('additional','application/json', JSON::generate(struct.additional))
+
+ status, ret, headers = Riddl::Client.new(@controller.url_code).request 'put' => send
+ recv = if status >= 200 && status < 300
+ ret.empty? ? nil : JSON::parse(ret[0].value.read)
else
- WEEL::ReadStructure.new(__dataelements,__endpoints,__local,__additional)
+ code_error_handling ret, 'Parameter ' + code
end
- @handler_endpoint = __exec_endpoints.is_a?(Array) ? __exec_endpoints.map{ |ep| __struct.endpoints[ep] }.compact : __struct.endpoints[__exec_endpoints]
- if @controller.attributes['twin_engine']
+ recv
+ end
+
+ def prepare(lock,dataelements,endpoints,status,local,additional,code,exec_endpoints,exec_parameters) #{{{
+ struct = if code
+ manipulate(true,lock,dataelements,endpoints,status,local,additional,code,'prepare')
+ else
+ WEEL::ReadStructure.new(dataelements,endpoints,local,additional)
+ end
+ @handler_endpoint = exec_endpoints.is_a?(Array) ? exec_endpoints.map{ |ep| struct.endpoints[ep] }.compact : struct.endpoints[exec_endpoints]
+ if @controller.attributes['sim_engine']
@handler_endpoint_orig = @handler_endpoint
- @handler_endpoint = @controller.attributes['twin_engine'].to_s + '?original_endpoint=' + Riddl::Protocols::Utils::escape(@handler_endpoint)
+ @handler_endpoint = @controller.attributes['sim_engine'].to_s + '?original_endpoint=' + Riddl::Protocols::Utils::escape(@handler_endpoint)
end
- __params = __exec_parameters.dup
- __params[:arguments] = __params[:arguments].dup if __params[:arguments]
- __params[:arguments]&.map! do |__ele|
- __tmp = __ele.dup
- if __tmp.value.is_a?(WEEL::ProcString)
- __tmp.value = __struct.instance_eval __tmp.value.code, 'Parameter', 1
+ params = exec_parameters.dup
+ params[:arguments] = params[:arguments].dup if params[:arguments]
+ params[:arguments]&.map! do |ele|
+ t = ele.dup
+ if t.value.is_a?(WEEL::ProcString)
+ t.value = argument_eval t.value.code, struct
+ elsif t.value.is_a?(Array) || t.value.is_a?(Hash)
+ argument_transform_value t.value, struct
end
- __tmp
+ t
end
- __params
+ params
end #}}}
- def test_condition(__dataelements,__endpoints,__local,__additional,__code,__args={}) #{{{
- __struct = WEEL::ReadStructure.new(__dataelements,__endpoints,__local,__additional).instance_eval(__code,'Condition',1)
- @controller.notify("gateway/decide", :instance_uuid => @controller.uuid, :code => __code, :condition => (__struct ? "true" : "false"))
- __struct
- end #}}}
- def manipulate(__readonly,__lock,__dataelements,__endpoints,__status,__local,__additional,__code,__where,__result=nil,__options=nil) #{{{
- result = CPEE::EvalRuby::Translation::simplify_structurized_result(__result)
- __struct = if __readonly
- WEEL::ReadStructure.new(__dataelements,__endpoints,__local,__additional)
+ def test_condition(dataelements,endpoints,local,additional,code,args={}) #{{{
+ send = []
+ send.push Riddl::Parameter::Simple::new('code',code)
+ send.push Riddl::Parameter::Complex::new('dataelements','application/json', JSON::generate(dataelements))
+ send.push Riddl::Parameter::Complex::new('local','application/json', JSON::generate(local)) if local
+ send.push Riddl::Parameter::Complex::new('endpoints','application/json', JSON::generate(endpoints))
+ send.push Riddl::Parameter::Complex::new('additional','application/json', JSON::generate(additional))
+
+ status, ret, headers = Riddl::Client.new(@controller.url_code).request 'put' => send
+ recv = if status >= 200 && status < 300
+ ret.empty? ? nil : JSON::parse(ret[0].value.read)
else
- WEEL::ManipulateStructure.new(__dataelements,__endpoints,__status,__local,__additional)
+ code_error_handling ret, 'Condition ' + code, WEEL::Signal::Error
end
- __struct.instance_eval(__code,__where,1)
- __struct
+ recv = 'false' unless recv
+ recv = (recv == 'false' || recv == 'null' || recv == 'nil' || recv == false ? false : true)
+ @controller.notify("gateway/decide", :ecid => Thread.current.__id__, :instance_uuid => @controller.uuid, :code => code, :condition => recv)
+ recv
end #}}}
+ def manipulate(readonly,lock,dataelements,endpoints,status,local,additional,code,where,result=nil,options=nil) #{{{
+ lock.synchronize do
+ send = []
+ send.push Riddl::Parameter::Simple::new('code',code)
+ send.push Riddl::Parameter::Complex::new('dataelements','application/json', JSON::generate(dataelements))
+ send.push Riddl::Parameter::Complex::new('local','application/json', JSON::generate(local)) if local
+ send.push Riddl::Parameter::Complex::new('endpoints','application/json', JSON::generate(endpoints))
+ send.push Riddl::Parameter::Complex::new('additional','application/json', JSON::generate(additional))
+ send.push Riddl::Parameter::Complex::new('status','application/json', JSON::generate(status)) if status
+ send.push Riddl::Parameter::Complex::new('call_result','application/json', JSON::generate(result))
+ send.push Riddl::Parameter::Complex::new('call_headers','application/json', JSON::generate(options))
- def split_branches(branches) # factual, so for inclusive or [[a],[b],[c,d,e]]{{{
- @controller.notify("gateway/split", :instance_uuid => @controller.uuid, :branches => branches)
+ stat, ret, headers = Riddl::Client.new(@controller.url_code).request 'put' => send
+ if stat >= 200 && stat < 300
+ ret.shift # drop result
+ signal = changed_status = nil
+ changed_dataelements = changed_local = changed_endpoints = []
+ signal = ret.shift.value if ret.any? && ret[0].name == 'signal'
+ changed_dataelements = JSON::parse(ret.shift.value.read) if ret.any? && ret[0].name == 'changed_dataelements'
+ changed_endpoints = JSON::parse(ret.shift.value.read) if ret.any? && ret[0].name == 'changed_endpoints'
+ changed_status = JSON::parse(ret.shift.value.read) if ret.any? && ret[0].name == 'changed_status'
+
+ struct = if readonly
+ WEEL::ReadStructure.new(dataelements,endpoints,local,additional)
+ else
+ WEEL::ManipulateStructure.new(dataelements, endpoints, status, local, additional)
+ end
+ struct.update(changed_dataelements,changed_endpoints,changed_status)
+
+ struct
+ else
+ code_error_handling ret, where
+ end
+ end
end #}}}
- def join_branches(branches) # factual, so for inclusive or [[a],[b],[c,d,e]]{{{
- @controller.notify("gateway/join", :instance_uuid => @controller.uuid, :branches => branches)
+
+ def split_branches(id, branches = []) # factual, so for inclusive or [[a],[b],[c,d,e]] {{{
+ payload = { :instance_uuid => @controller.uuid, :ecid => id.to_s }
+ payload[:branches] = branches.length if branches.length > 0
+ @controller.notify("gateway/split", payload )
+ end #}}}
+ def join_branches(id, branches = []) # factual, so for inclusive or [[a],[b],[c,d,e]] {{{
+ payload = { :instance_uuid => @controller.uuid, :ecid => id.to_s }
+ payload[:branches] = branches.length if branches.length > 0
+ @controller.notify("gateway/join", payload )
end #}}}
end