lib/cpee/instantiation.rb in cpee-1.3.228 vs lib/cpee/instantiation.rb in cpee-1.3.230

- old
+ new

@@ -21,13 +21,12 @@ module CPEE module Instantiation SERVER = File.expand_path(__dir__ + '/../instantiation.xml') - module Testset #{{{ - - def self::load(tdoc,cpee) + module Helpers #{{{ + def load_testset(tdoc,cpee) #{{{ ins = -1 XML::Smart.string(tdoc) do |doc| doc.register_namespace 'desc', 'http://cpee.org/ns/description/1.0' doc.register_namespace 'prop', 'http://riddl.org/ns/common-patterns/properties/1.0' @@ -68,78 +67,139 @@ end end end end return ins - end + end #}}} + private :load_testset + def handle_waiting(cpee,instance,behavior) #{{{ + if behavior =~ /^wait/ + condition = behavior.match(/_([^_]+)_/)&.[](1) || 'finished' + @headers << Riddl::Header.new('CPEE_CALLBACK','true') + cb = @h['CPEE_CALLBACK'] + if cb + srv = Riddl::Client.new(cpee, cpee + "?riddl-description") + status, response = srv.resource("/#{instance}/notifications/subscriptions/").post [ + Riddl::Parameter::Simple.new("topic","state"), + Riddl::Parameter::Simple.new("events","change"), + ] + key = response.first.value + + srv.resource("/#{instance}/notifications/subscriptions/#{key}/ws/").ws do |conn| + conn.on :message do |msg| + if JSON::parse(XML::Smart::string(msg.data).find('string(/event/notification)'))['state'] == condition + conn.close + Riddl::Client.new(cb).put [ + # TODO extract all dataelements from instance + Riddl::Parameter::Simple.new('instance',instance) + ] + end + end + end + end + end + end #}}} + private :handle_waiting + def handle_starting(cpee,instance,behavior) #{{{ + if behavior =~ /_running$/ + srv = Riddl::Client.new(cpee, cpee + "?riddl-description") + res = srv.resource("/#{instance}/properties/values") + status, response = res.put [ + Riddl::Parameter::Simple.new('name', 'state'), + Riddl::Parameter::Simple.new('value','running') + ] + end + end #}}} + private :handle_starting + def handle_data(cpee,instance,data) + if data + srv = Riddl::Client.new(cpee, cpee + "?riddl-description") + JSON::parse(data).each do |k,v| + res = srv.resource("/#{instance}/properties/values/dataelements/#{k}") + status, response = res.put [ + Riddl::Parameter::Simple.new('value',v) + ] + end rescue nil + end + end end #}}} - class Instantiate < Riddl::Implementation + class InstantiateUrl < Riddl::Implementation #{{{ + include Helpers + def response cpee = @a[0] - tdoc = case @p[@p.length - 1].name - when 'url' - status, res = Riddl::Client.new(@p[@p.length - 1].value).get - if status >= 200 && status < 300 - res[0].value.read - else - (@status = 500) && return - end - when 'xml' - if @p[@p.length - 1].additional =~ /base64/ - Base64.decode64(@p[@p.length - 1].value.read) - else - @p[@p.length - 1].value.read - end + status, res = Riddl::Client.new(@p[1].value).get + tdoc = if status >= 200 && status < 300 + res[0].value.read + else + (@status = 500) && return end - if (ins = Testset::load(tdoc,cpee)) == -1 + if (instance = load_testset(tdoc,cpee)) == -1 @status = 500 else - if @p[0].value =~ /^wait/ - @headers << Riddl::Header.new('CPEE_CALLBACK','true') - cb = @h['CPEE_CALLBACK'] + handle_data cpee, instance, @p[2]&.value + handle_waiting cpee, instance, @p[0].value + handle_starting cpee, instance, @p[0].value + return Riddl::Parameter::Simple.new("url",cpee + instance) + end + end + end #}}} - if cb - srv = Riddl::Client.new(cpee, cpee + "?riddl-description") - status, response = srv.resource("/#{ins}/notifications/subscriptions/").post [ - Riddl::Parameter::Simple.new("topic","state"), - Riddl::Parameter::Simple.new("events","change"), - ] - key = response.first.value + class InstantiateXML < Riddl::Implementation #{{{ + include Helpers - srv.resource("/#{ins}/notifications/subscriptions/#{key}/ws/").ws do |conn| - conn.on :message do |msg| - if JSON::parse(XML::Smart::string(msg.data).find('string(/event/notification)'))['state'] == 'finished' - conn.close - Riddl::Client.new(cb).put [ - # TODO extract all dataelements from instance - Riddl::Parameter::Simple.new('instance',ins) - ] - end - end - end - end - end - if @p.length > 1 && @p[0].value =~ /_running$/ - srv = Riddl::Client.new(cpee, cpee + "?riddl-description") - res = srv.resource("/#{ins}/properties/values") - status, response = res.put [ - Riddl::Parameter::Simple.new('name', 'state'), - Riddl::Parameter::Simple.new('value','running') - ] - end - return Riddl::Parameter::Simple.new("url",cpee + ins) + def response + cpee = @a[0] + behavior = @a[1] ? 'fork_ready' : @p[0].value + data = @a[1] ? 0 : 1 + tdoc = if @p[data].additional =~ /base64/ + Base64.decode64(@p[data].value.read) + else + @p[data].value.read end + + if (instance = load_testset(tdoc,cpee)) == -1 + @status = 500 + else + handle_data cpee, instance, @p[data+1]&.value + handle_waiting cpee, instance, behavior + handle_starting cpee, instance, behavior + return Riddl::Parameter::Simple.new("url",cpee + instance) + end end - end + end #}}} + class HandleInstance < Riddl::Implementation #{{{ + include Helpers + + def response + cpee = @a[0] + instance = @p[1].value + + handle_data cpee, instance, @p[2]&.value + handle_waiting cpee, instance, @p[0].value + handle_starting cpee, instance, @p[0].value + return Riddl::Parameter::Simple.new("url",cpee + instance) + end + end #}}} + def self::implementation(opts) opts[:cpee] ||= 'http://localhost:9298/' Proc.new do on resource do - run Instantiate, opts[:cpee] if post 'instantiate' + run InstantiateXML, opts[:cpee],true if post 'xmlsimple' + on resource 'xml' do + run InstantiateXML, opts[:cpee], false if post 'xml' + end + on resource 'url' do + run InstantiateUrl, opts[:cpee] if post 'url' + end + on resource 'instance' do + run HandleInstance, opts[:cpee] if post 'instance' + end end end end end