cpee 2.1.29 → 2.1.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +1 -1
- data/cockpit/config.json +1 -1
- data/cockpit/css/graph.css +13 -0
- data/cockpit/css/track.css +1 -1
- data/cockpit/css/wfadaptor.css +9 -2
- data/cockpit/edit.html +1 -1
- data/cockpit/graph.html +1 -0
- data/cockpit/index.html +2 -2
- data/cockpit/js/details.js +2 -2
- data/cockpit/js/instance.js +162 -112
- data/cockpit/js/wfadaptor.js +20 -14
- data/cockpit/js_libs.zip +0 -0
- data/cockpit/templates/Coopis 2010.xml +109 -14
- data/cockpit/templates/Frames.xml +297 -0
- data/cockpit/templates/Subprocess.xml +54 -6
- data/cockpit/templates/Wait.xml +5 -11
- data/cockpit/templates/Worklist.xml +58 -26
- data/cockpit/themes/compact/rngs/call.rng +127 -86
- data/cockpit/themes/compact/rngs/callmanipulate.rng +32 -7
- data/cockpit/themes/compact/rngs/closed_loop_control.rng +2 -2
- data/cockpit/themes/compact/rngs/closed_loop_measuring.rng +3 -3
- data/cockpit/themes/compact/rngs/start.rng +110 -72
- data/cockpit/themes/compact/symbols/call_sensor.svg +9 -0
- data/cockpit/themes/compact/symbols/callmanipulate.svg +3 -3
- data/cockpit/themes/compact/symbols/callmanipulate_sensor.svg +11 -0
- data/cockpit/themes/compact/symbols/delete.svg +4 -0
- data/cockpit/themes/compact/symbols/start_event.svg +5 -0
- data/cockpit/themes/compact/symbols/test.svg +74 -0
- data/cockpit/themes/compact/theme.js +105 -9
- data/cockpit/themes/control/rngs/call.rng +127 -86
- data/cockpit/themes/control/rngs/callmanipulate.rng +32 -7
- data/cockpit/themes/control/rngs/closed_loop_control.rng +2 -2
- data/cockpit/themes/control/rngs/closed_loop_measuring.rng +3 -3
- data/cockpit/themes/control/rngs/start.rng +110 -72
- data/cockpit/themes/control/symbols/call_sensor.svg +9 -0
- data/cockpit/themes/control/symbols/callmanipulate.svg +3 -3
- data/cockpit/themes/control/symbols/callmanipulate_sensor.svg +11 -0
- data/cockpit/themes/control/symbols/delete.svg +4 -0
- data/cockpit/themes/control/symbols/start_event.svg +5 -0
- data/cockpit/themes/control/symbols/test.svg +74 -0
- data/cockpit/themes/control/theme.js +53 -7
- data/cockpit/themes/default/rngs/call.rng +127 -86
- data/cockpit/themes/default/rngs/callmanipulate.rng +32 -7
- data/cockpit/themes/default/rngs/closed_loop_control.rng +2 -2
- data/cockpit/themes/default/rngs/closed_loop_measuring.rng +3 -3
- data/cockpit/themes/default/rngs/start.rng +110 -72
- data/cockpit/themes/default/symbols/call_sensor.svg +9 -0
- data/cockpit/themes/default/symbols/callmanipulate.svg +3 -3
- data/cockpit/themes/default/symbols/callmanipulate_sensor.svg +11 -0
- data/cockpit/themes/default/symbols/delete.svg +4 -0
- data/cockpit/themes/default/symbols/start_event.svg +5 -0
- data/cockpit/themes/default/symbols/test.svg +74 -0
- data/cockpit/themes/default/theme.js +105 -9
- data/cockpit/themes/extended/rngs/call.rng +127 -86
- data/cockpit/themes/extended/rngs/callmanipulate.rng +32 -7
- data/cockpit/themes/extended/rngs/closed_loop_control.rng +2 -2
- data/cockpit/themes/extended/rngs/closed_loop_measuring.rng +3 -3
- data/cockpit/themes/extended/rngs/start.rng +110 -72
- data/cockpit/themes/extended/symbols/call_sensor.svg +9 -0
- data/cockpit/themes/extended/symbols/callmanipulate.svg +3 -3
- data/cockpit/themes/extended/symbols/callmanipulate_sensor.svg +11 -0
- data/cockpit/themes/extended/symbols/delete.svg +4 -0
- data/cockpit/themes/extended/symbols/start_event.svg +5 -0
- data/cockpit/themes/extended/symbols/test.svg +74 -0
- data/cockpit/themes/extended/theme.js +105 -9
- data/cockpit/themes/model/symbols/call_sensor.svg +9 -0
- data/cockpit/themes/model/symbols/callmanipulate.svg +3 -3
- data/cockpit/themes/model/symbols/callmanipulate_sensor.svg +11 -0
- data/cockpit/themes/model/symbols/delete.svg +4 -0
- data/cockpit/themes/model/symbols/start_event.svg +5 -0
- data/cockpit/themes/model/symbols/test.svg +74 -0
- data/cockpit/themes/model/theme.js +50 -4
- data/cockpit/themes/packed/rngs/call.rng +127 -86
- data/cockpit/themes/packed/rngs/callmanipulate.rng +32 -7
- data/cockpit/themes/packed/rngs/closed_loop_control.rng +2 -2
- data/cockpit/themes/packed/rngs/closed_loop_measuring.rng +3 -3
- data/cockpit/themes/packed/rngs/start.rng +110 -72
- data/cockpit/themes/packed/symbols/call_sensor.svg +9 -0
- data/cockpit/themes/packed/symbols/callmanipulate.svg +3 -3
- data/cockpit/themes/packed/symbols/callmanipulate_sensor.svg +11 -0
- data/cockpit/themes/packed/symbols/delete.svg +4 -0
- data/cockpit/themes/packed/symbols/start_event.svg +5 -0
- data/cockpit/themes/packed/symbols/test.svg +74 -0
- data/cockpit/themes/packed/theme.js +105 -9
- data/cockpit/themes/preset/rngs/call.rng +127 -86
- data/cockpit/themes/preset/rngs/callmanipulate.rng +32 -7
- data/cockpit/themes/preset/rngs/closed_loop_control.rng +2 -2
- data/cockpit/themes/preset/rngs/closed_loop_measuring.rng +3 -3
- data/cockpit/themes/preset/rngs/start.rng +110 -72
- data/cockpit/themes/preset/symbols/call_sensor.svg +9 -0
- data/cockpit/themes/preset/symbols/callmanipulate.svg +3 -3
- data/cockpit/themes/preset/symbols/callmanipulate_sensor.svg +11 -0
- data/cockpit/themes/preset/symbols/delete.svg +4 -0
- data/cockpit/themes/preset/symbols/start_event.svg +5 -0
- data/cockpit/themes/preset/symbols/test.svg +74 -0
- data/cockpit/themes/preset/theme.js +105 -9
- data/cpee.gemspec +6 -5
- data/lib/cpee/fail.rb +23 -0
- data/lib/cpee/implementation.rb +144 -49
- data/lib/cpee/implementation_callbacks.rb +11 -10
- data/lib/cpee/implementation_notifications.rb +4 -3
- data/lib/cpee/implementation_properties.rb +2 -2
- data/lib/cpee/message.rb +49 -15
- data/lib/cpee/persistence.rb +34 -12
- data/lib/cpee.xml +1 -1
- data/server/executionhandlers/ruby/backend/instance.template +1 -1
- data/server/executionhandlers/ruby/backend/run +4 -4
- data/server/executionhandlers/ruby/connection.rb +93 -34
- data/server/executionhandlers/ruby/controller.rb +29 -19
- data/server/executionhandlers/ruby/desc.xml +107 -0
- data/server/executionhandlers/ruby/dsl_to_dslx.xsl +67 -24
- data/server/executionhandlers/ruby/execution.rb +1 -0
- data/server/resources/states.xml +3 -0
- data/server/resources/test.pdf +0 -0
- data/server/resources/topics.xml +4 -2
- data/server/routing/end.pid +1 -0
- data/server/routing/end.rb +3 -2
- data/server/routing/forward-events-00.pid +1 -0
- data/server/routing/forward-events.rb +26 -13
- data/server/routing/forward-votes.pid +1 -0
- data/server/routing/forward-votes.rb +4 -4
- data/server/routing/persist.pid +1 -0
- data/server/routing/persist.rb +41 -31
- data/server/server.pid +1 -0
- data/tools/cpee +99 -24
- metadata +80 -32
- data/cockpit/templates/Coopis 2010.xml.active +0 -1
- data/cockpit/templates/Coopis 2010.xml.active-uuid +0 -1
- data/cockpit/templates/Subprocess.xml.active +0 -1
- data/cockpit/templates/Subprocess.xml.active-uuid +0 -1
- data/cockpit/templates/Track Test.xml.active +0 -1
- data/cockpit/templates/Track Test.xml.active-uuid +0 -1
- data/cockpit/templates/UR-VUE 2020 Solution Baseline.xml.active +0 -1
- data/cockpit/templates/UR-VUE 2020 Solution Baseline.xml.active-uuid +0 -1
- data/cockpit/templates/Wait.xml.active +0 -1
- data/cockpit/templates/Wait.xml.active-uuid +0 -1
- data/cockpit/templates/Wait.xml.attrs +0 -13
- data/server/executionhandlers/ruby/test.xml +0 -43
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# <http://www.gnu.org/licenses/>.
|
|
14
14
|
|
|
15
15
|
require 'json'
|
|
16
|
+
require_relative 'fail'
|
|
16
17
|
|
|
17
18
|
module CPEE
|
|
18
19
|
module Callbacks
|
|
@@ -54,13 +55,13 @@ module CPEE
|
|
|
54
55
|
opts = @a[1]
|
|
55
56
|
callback = @r[-1]
|
|
56
57
|
|
|
57
|
-
if
|
|
58
|
+
if CPEE::Persistence::is_member?(id,opts,'callbacks',callback)
|
|
58
59
|
res = {}
|
|
59
|
-
res[:uuid]
|
|
60
|
-
res[:type]
|
|
61
|
-
res[:position] = opts
|
|
62
|
-
res[:label]
|
|
63
|
-
if sub = opts
|
|
60
|
+
res[:uuid] = CPEE::Persistence::extract_item(id,opts,"callback/#{callback}/uuid")
|
|
61
|
+
res[:type] = CPEE::Persistence::extract_item(id,opts,"callback/#{callback}/type")
|
|
62
|
+
res[:position] = CPEE::Persistence::extract_item(id,opts,"callback/#{callback}/position")
|
|
63
|
+
res[:label] = CPEE::Persistence::extract_item(id,opts,"callback/#{callback}/label")
|
|
64
|
+
if sub = CPEE::Persistence::extract_item(id,opts,"callback/#{callback}/subscription")
|
|
64
65
|
res[:subscription] = sub
|
|
65
66
|
end
|
|
66
67
|
|
|
@@ -77,7 +78,7 @@ module CPEE
|
|
|
77
78
|
opts = @a[1]
|
|
78
79
|
callback = @r[-1]
|
|
79
80
|
|
|
80
|
-
if opts
|
|
81
|
+
if CPEE::Persistence::extract_item(id,opts,"callback/#{callback}/type") == 'callback'
|
|
81
82
|
CPEE::Message::send(
|
|
82
83
|
:'callback-end',
|
|
83
84
|
callback,
|
|
@@ -88,7 +89,7 @@ module CPEE
|
|
|
88
89
|
{},
|
|
89
90
|
opts[:redis]
|
|
90
91
|
)
|
|
91
|
-
elsif opts
|
|
92
|
+
elsif CPEE::Persistence::extract_item(id,opts,"callback/#{callback}/type") == 'vote'
|
|
92
93
|
CPEE::Message::send(
|
|
93
94
|
:'vote-response',
|
|
94
95
|
callback,
|
|
@@ -112,7 +113,7 @@ module CPEE
|
|
|
112
113
|
opts = @a[1]
|
|
113
114
|
callback = @r[-1]
|
|
114
115
|
|
|
115
|
-
if opts
|
|
116
|
+
if CPEE::Persistence::extract_item(id,opts,"callback/#{callback}/type") == 'callback'
|
|
116
117
|
ret = {}
|
|
117
118
|
ret['values'] = @p.map{ |e|
|
|
118
119
|
[e.name, e.class == Riddl::Parameter::Simple ? [:simple,e.value] : [:complex,e.mimetype,e.value.path] ]
|
|
@@ -129,7 +130,7 @@ module CPEE
|
|
|
129
130
|
ret,
|
|
130
131
|
opts[:redis]
|
|
131
132
|
)
|
|
132
|
-
elsif opts
|
|
133
|
+
elsif CPEE::Persistence::extract_item(id,opts,"callback/#{callback}/type") == 'vote'
|
|
133
134
|
if @p.length == 1 && @p[0].name == 'continue' && @p[0].class == Riddl::Parameter::Simple
|
|
134
135
|
CPEE::Message::send(
|
|
135
136
|
:'vote-response',
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# <http://www.gnu.org/licenses/>.
|
|
14
14
|
|
|
15
15
|
require 'json'
|
|
16
|
+
require_relative 'fail'
|
|
16
17
|
|
|
17
18
|
module CPEE
|
|
18
19
|
module Notifications
|
|
@@ -188,7 +189,7 @@ module CPEE
|
|
|
188
189
|
on.pmessage do |pat, what, message|
|
|
189
190
|
if pat == 'forward:*'
|
|
190
191
|
id, key = what.match(/forward:([^\/]+)\/(.+)/).captures
|
|
191
|
-
if sse = opts.dig(:sse_connections,id
|
|
192
|
+
if sse = opts.dig(:sse_connections,id,key)
|
|
192
193
|
sse.send message
|
|
193
194
|
else
|
|
194
195
|
DeleteSubscription::set(id,opts,key)
|
|
@@ -197,7 +198,7 @@ module CPEE
|
|
|
197
198
|
mess = JSON.parse(message[message.index(' ')+1..-1])
|
|
198
199
|
state = mess.dig('content','state')
|
|
199
200
|
if state == 'finished' || state == 'abandoned'
|
|
200
|
-
opts.dig(:sse_connections,mess.dig('instance').
|
|
201
|
+
opts.dig(:sse_connections,mess.dig('instance').to_s)&.each do |key,sse|
|
|
201
202
|
EM.add_timer(10) do # just to be sure that all messages arrived. 10 seconds should be enough ... we think ... therefore we are (not sure)
|
|
202
203
|
sse.close
|
|
203
204
|
end
|
|
@@ -218,7 +219,7 @@ module CPEE
|
|
|
218
219
|
class SSE < Riddl::SSEImplementation #{{{
|
|
219
220
|
def onopen
|
|
220
221
|
@opts = @a[1]
|
|
221
|
-
@id = @a[0]
|
|
222
|
+
@id = @a[0].to_s
|
|
222
223
|
@key = @r[-2]
|
|
223
224
|
if CPEE::Persistence::exists_handler?(@id,@opts,@key)
|
|
224
225
|
@opts[:sse_connections][@id] ||= {}
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# <http://www.gnu.org/licenses/>.
|
|
14
14
|
|
|
15
15
|
require_relative 'attributes_helper'
|
|
16
|
+
require_relative 'fail'
|
|
16
17
|
require_relative 'value_helper'
|
|
17
18
|
require 'json'
|
|
18
19
|
require 'erb'
|
|
@@ -226,7 +227,7 @@ module CPEE
|
|
|
226
227
|
end #}}}
|
|
227
228
|
class PutState < Riddl::Implementation #{{{
|
|
228
229
|
def self::set(id,opts,state)
|
|
229
|
-
CPEE::Persistence::set_item(id,opts,'state',:state => state, :
|
|
230
|
+
CPEE::Persistence::set_item(id,opts,'state',:state => state, :attributes => CPEE::Persistence::extract_list(id,opts,'attributes').to_h)
|
|
230
231
|
end
|
|
231
232
|
|
|
232
233
|
def self::run(id,opts,state)
|
|
@@ -241,7 +242,6 @@ module CPEE
|
|
|
241
242
|
PutState::set id, opts, 'stopped'
|
|
242
243
|
end
|
|
243
244
|
else
|
|
244
|
-
### Most probably this is never needed. Lets see.
|
|
245
245
|
PutState::set id, opts, state
|
|
246
246
|
end
|
|
247
247
|
end
|
data/lib/cpee/message.rb
CHANGED
|
@@ -15,28 +15,62 @@
|
|
|
15
15
|
module CPEE
|
|
16
16
|
|
|
17
17
|
module Message
|
|
18
|
+
WHO = 'cpee'
|
|
19
|
+
TYPE = 'instance'
|
|
18
20
|
|
|
19
|
-
def self::
|
|
21
|
+
def self::set_workers(workers)
|
|
22
|
+
@@tworkers = (workers < 1 && workers > 99 ? 1 : workers).freeze
|
|
23
|
+
@@last = -1
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self::target
|
|
27
|
+
@@last < @@tworkers-1 ? @@last += 1 : @@last = 0
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self::send(type, event, cpee, instance, instance_uuid, instance_name, content={}, backend=nil)
|
|
31
|
+
target = '%02i' % CPEE::Message::target
|
|
20
32
|
topic = ::File::dirname(event)
|
|
21
33
|
name = ::File::basename(event)
|
|
22
|
-
|
|
34
|
+
payload = {
|
|
35
|
+
WHO => cpee,
|
|
36
|
+
TYPE + '-url' => File.join(cpee,instance.to_s),
|
|
37
|
+
TYPE => instance,
|
|
38
|
+
'topic' => topic,
|
|
39
|
+
'type' => type,
|
|
40
|
+
'name' => name,
|
|
41
|
+
'timestamp' => Time.now.xmlschema(3),
|
|
42
|
+
'content' => content
|
|
43
|
+
}
|
|
44
|
+
payload[TYPE + '-uuid'] = instance_uuid if instance_uuid
|
|
45
|
+
payload[TYPE + '-name'] = instance_name if instance_name
|
|
46
|
+
|
|
47
|
+
backend.publish(type.to_s + ':' + target + ':' + event.to_s,
|
|
23
48
|
instance.to_s + ' ' +
|
|
24
|
-
JSON::generate(
|
|
25
|
-
{ 'cpee' => cpee,
|
|
26
|
-
'instance-url' => File.join(cpee,instance.to_s),
|
|
27
|
-
'instance-uuid' => instance_uuid,
|
|
28
|
-
'instance-name' => instance_name,
|
|
29
|
-
'instance' => instance,
|
|
30
|
-
'topic' => topic,
|
|
31
|
-
'type' => type,
|
|
32
|
-
'name' => name,
|
|
33
|
-
'timestamp' => Time.now.xmlschema(3),
|
|
34
|
-
'content' => content
|
|
35
|
-
}
|
|
36
|
-
)
|
|
49
|
+
JSON::generate(payload)
|
|
37
50
|
)
|
|
38
51
|
end
|
|
39
52
|
|
|
53
|
+
def self::send_url(type, event, cpee, content={}, backend)
|
|
54
|
+
EM.defer do
|
|
55
|
+
topic = ::File::dirname(event)
|
|
56
|
+
name = ::File::basename(event)
|
|
57
|
+
payload = {
|
|
58
|
+
WHO => cpee,
|
|
59
|
+
'topic' => topic,
|
|
60
|
+
'type' => type,
|
|
61
|
+
'name' => name,
|
|
62
|
+
'timestamp' => Time.now.xmlschema(3),
|
|
63
|
+
'content' => content
|
|
64
|
+
}
|
|
65
|
+
client = Riddl::Client.new(backend)
|
|
66
|
+
client.post [
|
|
67
|
+
Riddl::Parameter::Simple::new('type',type),
|
|
68
|
+
Riddl::Parameter::Simple::new('topic',topic),
|
|
69
|
+
Riddl::Parameter::Simple::new('event',name),
|
|
70
|
+
Riddl::Parameter::Complex::new('notification','application/json',JSON::generate(payload))
|
|
71
|
+
]
|
|
72
|
+
end
|
|
73
|
+
end
|
|
40
74
|
end
|
|
41
75
|
|
|
42
76
|
end
|
data/lib/cpee/persistence.rb
CHANGED
|
@@ -15,6 +15,11 @@
|
|
|
15
15
|
module CPEE
|
|
16
16
|
|
|
17
17
|
module Persistence
|
|
18
|
+
@@obj = 'instance'
|
|
19
|
+
def self::obj #{{{
|
|
20
|
+
@@obj
|
|
21
|
+
end #}}}
|
|
22
|
+
|
|
18
23
|
def self::set_list(id,opts,item,values,deleted=[]) #{{{
|
|
19
24
|
ah = AttributesHelper.new
|
|
20
25
|
attributes = Persistence::extract_list(id,opts,'attributes').to_h
|
|
@@ -30,20 +35,20 @@ module CPEE
|
|
|
30
35
|
{
|
|
31
36
|
:changed => values.keys,
|
|
32
37
|
:deleted => deleted,
|
|
33
|
-
:values => values,
|
|
38
|
+
:values => values.transform_values{|val| JSON::parse(val) rescue val },
|
|
34
39
|
:attributes => ah.translate(attributes,dataelements,endpoints),
|
|
35
40
|
},
|
|
36
41
|
opts[:redis]
|
|
37
42
|
)
|
|
38
43
|
end #}}}
|
|
39
44
|
def self::extract_set(id,opts,item) #{{{
|
|
40
|
-
opts[:redis].smembers("
|
|
41
|
-
[e,opts[:redis].get("
|
|
45
|
+
opts[:redis].smembers(@@obj + ":#{id}/#{item}").map do |e|
|
|
46
|
+
[e,opts[:redis].get(@@obj + ":#{id}/#{item}/#{e}")]
|
|
42
47
|
end
|
|
43
48
|
end #}}}
|
|
44
49
|
def self::extract_list(id,opts,item) #{{{
|
|
45
|
-
opts[:redis].zrange("
|
|
46
|
-
[e,opts[:redis].get("
|
|
50
|
+
opts[:redis].zrange(@@obj + ":#{id}/#{item}",0,-1).map do |e|
|
|
51
|
+
[e,opts[:redis].get(@@obj + ":#{id}/#{item}/#{e}")]
|
|
47
52
|
end
|
|
48
53
|
end #}}}
|
|
49
54
|
|
|
@@ -60,15 +65,32 @@ module CPEE
|
|
|
60
65
|
)
|
|
61
66
|
end #}}}
|
|
62
67
|
def self::extract_item(id,opts,item) #{{{
|
|
63
|
-
opts[:redis].get("
|
|
68
|
+
opts[:redis].get(@@obj + ":#{id}/#{item}")
|
|
64
69
|
end #}}}
|
|
65
70
|
|
|
66
71
|
def self::exists?(id,opts) #{{{
|
|
67
|
-
opts[:redis].exists?("
|
|
72
|
+
opts[:redis].exists?(@@obj + ":#{id}/state")
|
|
68
73
|
end #}}}
|
|
74
|
+
def self::is_member?(id,opts,item,value) #{{{
|
|
75
|
+
opts[:redis].sismember(@@obj + ":#{id}/#{item}",value)
|
|
76
|
+
end #}}}
|
|
77
|
+
|
|
78
|
+
def self::each_object(opts)
|
|
79
|
+
opts[:redis].zrevrange(@@obj + 's',0,-1).each do |instance|
|
|
80
|
+
yield instance
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def self::new_object(opts)
|
|
85
|
+
opts[:redis].zrevrange(@@obj + 's', 0, 0).first.to_i + 1
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def self::keys(id,opts,item=nil)
|
|
89
|
+
opts[:redis].keys(File.join(@@obj + ":#{id}",item.to_s,'*'))
|
|
90
|
+
end
|
|
69
91
|
|
|
70
92
|
def self::set_handler(id,opts,key,url,values,update=false) #{{{
|
|
71
|
-
exis = opts[:redis].smembers("
|
|
93
|
+
exis = opts[:redis].smembers(@@obj + ":#{id}/handlers/#{key}")
|
|
72
94
|
|
|
73
95
|
if update == false && exis.length > 0
|
|
74
96
|
return 405
|
|
@@ -101,14 +123,14 @@ module CPEE
|
|
|
101
123
|
200
|
|
102
124
|
end #}}}
|
|
103
125
|
def self::extract_handler(id,opts,key) #{{{
|
|
104
|
-
opts[:redis].smembers("
|
|
126
|
+
opts[:redis].smembers(@@obj + ":#{id}/handlers/#{key}")
|
|
105
127
|
end #}}}
|
|
106
128
|
def self::exists_handler?(id,opts,key) #{{{
|
|
107
|
-
opts[:redis].exists?("
|
|
129
|
+
opts[:redis].exists?(@@obj + ":#{id}/handlers/#{key}")
|
|
108
130
|
end #}}}
|
|
109
131
|
def self::extract_handlers(id,opts) #{{{
|
|
110
|
-
opts[:redis].smembers("
|
|
111
|
-
[e, opts[:redis].get("
|
|
132
|
+
opts[:redis].smembers(@@obj + ":#{id}/handlers").map do |e|
|
|
133
|
+
[e, opts[:redis].get(@@obj + ":#{id}/handlers/#{e}/url")]
|
|
112
134
|
end
|
|
113
135
|
end #}}}
|
|
114
136
|
end
|
data/lib/cpee.xml
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
CPEE is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
9
9
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
10
|
-
PARTICULAR PURPOSE.
|
|
10
|
+
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
11
11
|
|
|
12
12
|
You should have received a copy of the GNU General Public License along with
|
|
13
13
|
CPEE (file COPYING in the main directory). If not, see
|
|
@@ -11,7 +11,7 @@ class Instance < WEEL
|
|
|
11
11
|
<% end -%>
|
|
12
12
|
|
|
13
13
|
<% unless positions.nil? || positions.empty? -%>
|
|
14
|
-
search <% positions.each_with_index { |de,i| %><%= (i > 0 ? ', ' : '') %>Position.new(:<%= de[0] %>, :<%=de[1] %>, <%= de[2].nil? || de[2].strip.empty? ? 'nil' : '"' + de[2] + '"' %>)<% } %>
|
|
14
|
+
search <% positions.each_with_index { |de,i| %><%= (i > 0 ? ', ' : '') %>Position.new(:<%= de[0] %>, 0, :<%=de[1] %>, <%= de[2].nil? || de[2].strip.empty? ? 'nil' : '"' + de[2] + '"' %>)<% } %>
|
|
15
15
|
<% end -%>
|
|
16
16
|
|
|
17
17
|
<%= dsl.strip.gsub(/\n/,"\n ") %>
|
|
@@ -6,17 +6,17 @@ opts[:pid] = Process.pid
|
|
|
6
6
|
|
|
7
7
|
global_controller = File.join(opts[:global_executionhandlers],opts[:executionhandler],'controller.rb')
|
|
8
8
|
controller = File.join(opts[:executionhandlers], opts[:executionhandler],'controller.rb')
|
|
9
|
-
if File.
|
|
9
|
+
if File.exist? global_controller
|
|
10
10
|
require global_controller
|
|
11
|
-
elsif File.
|
|
11
|
+
elsif File.exist? controller
|
|
12
12
|
require controller
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
global_connectionhandler = File.join(opts[:global_executionhandlers],opts[:executionhandler],'connection.rb')
|
|
16
16
|
connectionhandler = File.join(opts[:executionhandlers], opts[:executionhandler],'connection.rb')
|
|
17
|
-
if File.
|
|
17
|
+
if File.exist? global_connectionhandler
|
|
18
18
|
require global_connectionhandler
|
|
19
|
-
elsif File.
|
|
19
|
+
elsif File.exist? connectionhandler
|
|
20
20
|
require connectionhandler
|
|
21
21
|
end
|
|
22
22
|
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
require 'charlock_holmes'
|
|
16
16
|
require 'mimemagic'
|
|
17
17
|
require 'base64'
|
|
18
|
+
require 'get_process_mem'
|
|
18
19
|
|
|
19
20
|
class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
20
21
|
def self::loop_guard(arguments,id,count) # {{{
|
|
@@ -31,14 +32,18 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
31
32
|
controller.notify("state/change", :state => newstate)
|
|
32
33
|
end # }}}
|
|
33
34
|
def self::inform_syntax_error(arguments,err,code)# {{{
|
|
35
|
+
# TODO extract spot (code) where error happened for better error handling (ruby 3.1 only)
|
|
36
|
+
# https://github.com/rails/rails/pull/45818/commits/3beb2aff3be712e44c34a588fbf35b79c0246ca5
|
|
34
37
|
controller = arguments[0]
|
|
35
|
-
|
|
38
|
+
mess = err.backtrace ? err.backtrace[0].gsub(/([\w -_]+):(\d+):in.*/,'\\1, Line \2: ') : ''
|
|
39
|
+
mess += err.message
|
|
40
|
+
controller.notify("description/error", :message => mess)
|
|
36
41
|
end# }}}
|
|
37
42
|
def self::inform_connectionwrapper_error(arguments,err) # {{{
|
|
38
43
|
controller = arguments[0]
|
|
39
44
|
p err.message
|
|
40
45
|
p err.backtrace
|
|
41
|
-
controller.notify("executionhandler/error", :message => err.message)
|
|
46
|
+
controller.notify("executionhandler/error", :message => err.backtrace[0].gsub(/([\w -_]+):(\d+):in.*/,'\\1, Line \2: ') + err.message)
|
|
42
47
|
end # }}}
|
|
43
48
|
def self::inform_position_change(arguments,ipc={}) # {{{
|
|
44
49
|
controller = arguments[0]
|
|
@@ -59,10 +64,10 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
59
64
|
end # }}}
|
|
60
65
|
|
|
61
66
|
def prepare(readonly, endpoints, parameters, replay=false) #{{{
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
@handler_endpoint =
|
|
67
|
+
@handler_endpoint = endpoints.is_a?(Array) ? endpoints.map{ |ep| readonly.endpoints[ep] }.compact : readonly.endpoints[endpoints]
|
|
68
|
+
if @controller.attributes['mock']
|
|
69
|
+
@handler_endpoint_orig = @handler_endpoint
|
|
70
|
+
@handler_endpoint = @controller.attributes['mock'].to_s + '?original_endpoint=' + Riddl::Protocols::Utils::escape(@handler_endpoint)
|
|
66
71
|
end
|
|
67
72
|
params = parameters.dup
|
|
68
73
|
params[:arguments] = params[:arguments].dup if params[:arguments]
|
|
@@ -77,7 +82,19 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
77
82
|
end #}}}
|
|
78
83
|
|
|
79
84
|
def additional #{{{
|
|
80
|
-
{
|
|
85
|
+
{
|
|
86
|
+
:attributes => @controller.attributes,
|
|
87
|
+
:cpee => {
|
|
88
|
+
'base' => @controller.base_url,
|
|
89
|
+
'instance' => @controller.instance_id,
|
|
90
|
+
'instance_url' => @controller.instance_url,
|
|
91
|
+
'instance_uuid' => @controller.uuid
|
|
92
|
+
},
|
|
93
|
+
:task => {
|
|
94
|
+
'label' => @label,
|
|
95
|
+
'id' => @handler_position
|
|
96
|
+
}
|
|
97
|
+
}
|
|
81
98
|
end #}}}
|
|
82
99
|
|
|
83
100
|
def proto_curl(parameters) #{{{
|
|
@@ -114,31 +131,46 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
114
131
|
params << Riddl::Header.new("CPEE-ATTR-#{key.to_s.gsub(/_/,'-')}",value)
|
|
115
132
|
end
|
|
116
133
|
|
|
117
|
-
|
|
118
|
-
|
|
134
|
+
status = result = headers = nil
|
|
135
|
+
begin
|
|
136
|
+
tendpoint = @handler_endpoint.sub(/^http(s)?-(get|put|post|delete):/,'http\\1:')
|
|
137
|
+
type = $2 || parameters[:method] || 'post'
|
|
119
138
|
|
|
120
|
-
|
|
139
|
+
client = Riddl::Client.new(tendpoint)
|
|
121
140
|
|
|
122
|
-
|
|
123
|
-
|
|
141
|
+
@handler_passthrough = callback
|
|
142
|
+
@controller.callback(self,callback,:'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position)
|
|
143
|
+
|
|
144
|
+
status, result, headers = client.request type => params
|
|
145
|
+
if status == 561
|
|
146
|
+
@handler_endpoint = @handler_endpoint_orig
|
|
147
|
+
params.delete_if { |p| p.name == 'original_endpoint' }
|
|
148
|
+
params.each do |p|
|
|
149
|
+
if p.name == 'attributes'
|
|
150
|
+
t = JSON::parse(p.value) rescue {}
|
|
151
|
+
t['mock'] = @controller.attributes['mock']
|
|
152
|
+
p.value = t.to_json
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end while status == 561
|
|
124
157
|
|
|
125
|
-
status, result, headers = client.request type => params
|
|
126
158
|
if status < 200 || status >= 300
|
|
127
159
|
headers['CPEE_SALVAGE'] = true
|
|
128
160
|
c = result[0]&.value
|
|
129
161
|
c = c.read if c.respond_to? :read
|
|
130
162
|
callback([ Riddl::Parameter::Complex.new('error','application/json',StringIO.new(JSON::generate({ 'status' => status, 'error' => c }))) ], headers)
|
|
131
163
|
else
|
|
132
|
-
if headers['CPEE_INSTANTIATION']
|
|
133
|
-
@controller.notify("task/instantiation", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint, :received => CPEE::ValueHelper.parse(headers['CPEE_INSTANTIATION']))
|
|
134
|
-
end
|
|
135
|
-
if headers['CPEE_EVENT']
|
|
136
|
-
@controller.notify("task/#{headers['CPEE_EVENT'].gsub(/[^\w_-]/,'')}", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint)
|
|
137
|
-
end
|
|
138
164
|
if headers['CPEE_CALLBACK'] && headers['CPEE_CALLBACK'] == 'true' && result.any?
|
|
139
165
|
headers['CPEE_UPDATE'] = true
|
|
140
166
|
callback result, headers
|
|
141
167
|
elsif headers['CPEE_CALLBACK'] && headers['CPEE_CALLBACK'] == 'true' && result.empty?
|
|
168
|
+
if headers['CPEE_INSTANTIATION']
|
|
169
|
+
@controller.notify("task/instantiation", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint, :received => CPEE::ValueHelper.parse(headers['CPEE_INSTANTIATION']))
|
|
170
|
+
end
|
|
171
|
+
if headers['CPEE_EVENT']
|
|
172
|
+
@controller.notify("task/#{headers['CPEE_EVENT'].gsub(/[^\w_-]/,'')}", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint)
|
|
173
|
+
end
|
|
142
174
|
# do nothing, later on things will happend
|
|
143
175
|
else
|
|
144
176
|
callback result, headers
|
|
@@ -150,6 +182,7 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
150
182
|
raise "Wrong endpoint" if @handler_endpoint.nil? || @handler_endpoint.empty?
|
|
151
183
|
@label = parameters[:label]
|
|
152
184
|
@anno = parameters.delete(:annotations) rescue nil
|
|
185
|
+
@controller.notify("status/resource_utilization", :mib => GetProcessMem.new.mb, **Process.times.to_h)
|
|
153
186
|
@controller.notify("activity/calling", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :passthrough => passthrough, :endpoint => @handler_endpoint, :parameters => parameters, :annotations => @anno)
|
|
154
187
|
if passthrough.to_s.empty?
|
|
155
188
|
proto_curl parameters
|
|
@@ -182,8 +215,13 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
182
215
|
true
|
|
183
216
|
end # }}}
|
|
184
217
|
|
|
218
|
+
def activity_uuid
|
|
219
|
+
@handler_activity_uuid
|
|
220
|
+
end
|
|
221
|
+
|
|
185
222
|
def inform_activity_done # {{{
|
|
186
223
|
@controller.notify("activity/done", :'activity-uuid' => @handler_activity_uuid, :endpoint => @handler_endpoint, :label => @label, :activity => @handler_position)
|
|
224
|
+
@controller.notify("status/resource_utilization", :mib => GetProcessMem.new.mb, **Process.times.to_h)
|
|
187
225
|
end # }}}
|
|
188
226
|
def inform_activity_manipulate # {{{
|
|
189
227
|
@controller.notify("activity/manipulating", :'activity-uuid' => @handler_activity_uuid, :endpoint => @handler_endpoint, :label => @label, :activity => @handler_position)
|
|
@@ -220,6 +258,10 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
220
258
|
elsif result[0].is_a? Riddl::Parameter::Complex
|
|
221
259
|
if result[0].mimetype == 'application/json'
|
|
222
260
|
result = JSON::parse(result[0].value.read) rescue nil
|
|
261
|
+
elsif result[0].mimetype == 'text/csv'
|
|
262
|
+
result = result[0].value.read
|
|
263
|
+
elsif result[0].mimetype == 'text/yaml'
|
|
264
|
+
result = YAML::load(result[0].value.read) rescue nil
|
|
223
265
|
elsif result[0].mimetype == 'application/xml' || result[0].mimetype == 'text/xml'
|
|
224
266
|
result = XML::Smart::string(result[0].value.read) rescue nil
|
|
225
267
|
elsif result[0].mimetype == 'text/plain'
|
|
@@ -238,8 +280,15 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
238
280
|
result = result[0]
|
|
239
281
|
end
|
|
240
282
|
end
|
|
283
|
+
else
|
|
284
|
+
Riddl::Parameter::Array[*result]
|
|
285
|
+
end
|
|
286
|
+
if result.is_a? String
|
|
287
|
+
enc = detect_encoding(result)
|
|
288
|
+
enc == 'OTHER' ? result : (result.encode('UTF-8',enc) rescue convert_to_base64(result))
|
|
289
|
+
else
|
|
290
|
+
result
|
|
241
291
|
end
|
|
242
|
-
result
|
|
243
292
|
end
|
|
244
293
|
|
|
245
294
|
def detect_encoding(text)
|
|
@@ -271,13 +320,13 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
271
320
|
{ 'name' => r.name, 'data' => r.value }
|
|
272
321
|
elsif r.is_a? Riddl::Parameter::Complex
|
|
273
322
|
res = if r.mimetype == 'application/json'
|
|
274
|
-
ttt =
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
323
|
+
ttt = r.value.read
|
|
324
|
+
enc = detect_encoding(ttt)
|
|
325
|
+
enc == 'OTHER' ? ttt.inspect : (ttt.encode('UTF-8',enc) rescue convert_to_base64(ttt))
|
|
326
|
+
elsif r.mimetype == 'text/csv'
|
|
327
|
+
ttt = r.value.read
|
|
328
|
+
enc = detect_encoding(ttt)
|
|
329
|
+
enc == 'OTHER' ? ttt.inspect : (ttt.encode('UTF-8',enc) rescue convert_to_base64(ttt))
|
|
281
330
|
elsif r.mimetype == 'text/plain' || r.mimetype == 'text/html'
|
|
282
331
|
ttt = r.value.read
|
|
283
332
|
ttt = ttt.to_f if ttt == ttt.to_f.to_s
|
|
@@ -286,7 +335,6 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
286
335
|
enc == 'OTHER' ? ttt.inspect : (ttt.encode('UTF-8',enc) rescue convert_to_base64(ttt))
|
|
287
336
|
else
|
|
288
337
|
convert_to_base64(r.value.read)
|
|
289
|
-
r.value.rewind
|
|
290
338
|
end
|
|
291
339
|
|
|
292
340
|
tmp = {
|
|
@@ -301,10 +349,17 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
301
349
|
end
|
|
302
350
|
|
|
303
351
|
def callback(result=nil,options={})
|
|
304
|
-
|
|
352
|
+
recv = structurize_result(result)
|
|
353
|
+
@controller.notify("activity/receiving", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint, :received => recv, :annotations => @anno)
|
|
305
354
|
@guard_files += result
|
|
306
355
|
@handler_returnValue = simplify_result(result)
|
|
307
356
|
@handler_returnOptions = options
|
|
357
|
+
if options['CPEE_INSTANTIATION']
|
|
358
|
+
@controller.notify("task/instantiation", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint, :received => CPEE::ValueHelper.parse(options['CPEE_INSTANTIATION']))
|
|
359
|
+
end
|
|
360
|
+
if options['CPEE_EVENT']
|
|
361
|
+
@controller.notify("task/#{options['CPEE_EVENT'].gsub(/[^\w_-]/,'')}", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint, :received => recv)
|
|
362
|
+
end
|
|
308
363
|
if options['CPEE_UPDATE']
|
|
309
364
|
if options['CPEE_UPDATE_STATUS']
|
|
310
365
|
@controller.notify("activity/status", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint, :status => options['CPEE_UPDATE_STATUS'])
|
|
@@ -315,6 +370,8 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
315
370
|
@handler_passthrough = nil
|
|
316
371
|
if options['CPEE_SALVAGE']
|
|
317
372
|
@handler_continue.continue WEEL::Signal::Salvage
|
|
373
|
+
elsif options['CPEE_STOP']
|
|
374
|
+
@handler_continue.continue WEEL::Signal::Stop
|
|
318
375
|
else
|
|
319
376
|
@handler_continue.continue
|
|
320
377
|
end
|
|
@@ -331,15 +388,17 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
331
388
|
end
|
|
332
389
|
end #}}}
|
|
333
390
|
|
|
334
|
-
def test_condition(mr,code)
|
|
335
|
-
res = mr.instance_eval(code)
|
|
336
|
-
@controller.notify("
|
|
391
|
+
def test_condition(mr,code,args)
|
|
392
|
+
res = mr.instance_eval(code,'Condition',1)
|
|
393
|
+
@controller.notify("gateway/decide", :instance_uuid => @controller.uuid, :code => code, :condition => (res ? "true" : "false"))
|
|
337
394
|
res
|
|
338
395
|
end
|
|
339
396
|
|
|
340
|
-
def
|
|
341
|
-
|
|
397
|
+
def join_branches(branches) # factual, so for inclusive or [[a],[b],[c,d,e]]
|
|
398
|
+
@controller.notify("gateway/join", :instance_uuid => @controller.uuid, :branches => branches)
|
|
399
|
+
end
|
|
342
400
|
|
|
401
|
+
def simulate(type,nesting,tid,parent,parameters={}) #{{{
|
|
343
402
|
@controller.vote("simulating/step",
|
|
344
403
|
:'activity-uuid' => @handler_activity_uuid,
|
|
345
404
|
:label => @label,
|