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.
Files changed (139) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -1
  3. data/cockpit/config.json +1 -1
  4. data/cockpit/css/graph.css +13 -0
  5. data/cockpit/css/track.css +1 -1
  6. data/cockpit/css/wfadaptor.css +9 -2
  7. data/cockpit/edit.html +1 -1
  8. data/cockpit/graph.html +1 -0
  9. data/cockpit/index.html +2 -2
  10. data/cockpit/js/details.js +2 -2
  11. data/cockpit/js/instance.js +162 -112
  12. data/cockpit/js/wfadaptor.js +20 -14
  13. data/cockpit/js_libs.zip +0 -0
  14. data/cockpit/templates/Coopis 2010.xml +109 -14
  15. data/cockpit/templates/Frames.xml +297 -0
  16. data/cockpit/templates/Subprocess.xml +54 -6
  17. data/cockpit/templates/Wait.xml +5 -11
  18. data/cockpit/templates/Worklist.xml +58 -26
  19. data/cockpit/themes/compact/rngs/call.rng +127 -86
  20. data/cockpit/themes/compact/rngs/callmanipulate.rng +32 -7
  21. data/cockpit/themes/compact/rngs/closed_loop_control.rng +2 -2
  22. data/cockpit/themes/compact/rngs/closed_loop_measuring.rng +3 -3
  23. data/cockpit/themes/compact/rngs/start.rng +110 -72
  24. data/cockpit/themes/compact/symbols/call_sensor.svg +9 -0
  25. data/cockpit/themes/compact/symbols/callmanipulate.svg +3 -3
  26. data/cockpit/themes/compact/symbols/callmanipulate_sensor.svg +11 -0
  27. data/cockpit/themes/compact/symbols/delete.svg +4 -0
  28. data/cockpit/themes/compact/symbols/start_event.svg +5 -0
  29. data/cockpit/themes/compact/symbols/test.svg +74 -0
  30. data/cockpit/themes/compact/theme.js +105 -9
  31. data/cockpit/themes/control/rngs/call.rng +127 -86
  32. data/cockpit/themes/control/rngs/callmanipulate.rng +32 -7
  33. data/cockpit/themes/control/rngs/closed_loop_control.rng +2 -2
  34. data/cockpit/themes/control/rngs/closed_loop_measuring.rng +3 -3
  35. data/cockpit/themes/control/rngs/start.rng +110 -72
  36. data/cockpit/themes/control/symbols/call_sensor.svg +9 -0
  37. data/cockpit/themes/control/symbols/callmanipulate.svg +3 -3
  38. data/cockpit/themes/control/symbols/callmanipulate_sensor.svg +11 -0
  39. data/cockpit/themes/control/symbols/delete.svg +4 -0
  40. data/cockpit/themes/control/symbols/start_event.svg +5 -0
  41. data/cockpit/themes/control/symbols/test.svg +74 -0
  42. data/cockpit/themes/control/theme.js +53 -7
  43. data/cockpit/themes/default/rngs/call.rng +127 -86
  44. data/cockpit/themes/default/rngs/callmanipulate.rng +32 -7
  45. data/cockpit/themes/default/rngs/closed_loop_control.rng +2 -2
  46. data/cockpit/themes/default/rngs/closed_loop_measuring.rng +3 -3
  47. data/cockpit/themes/default/rngs/start.rng +110 -72
  48. data/cockpit/themes/default/symbols/call_sensor.svg +9 -0
  49. data/cockpit/themes/default/symbols/callmanipulate.svg +3 -3
  50. data/cockpit/themes/default/symbols/callmanipulate_sensor.svg +11 -0
  51. data/cockpit/themes/default/symbols/delete.svg +4 -0
  52. data/cockpit/themes/default/symbols/start_event.svg +5 -0
  53. data/cockpit/themes/default/symbols/test.svg +74 -0
  54. data/cockpit/themes/default/theme.js +105 -9
  55. data/cockpit/themes/extended/rngs/call.rng +127 -86
  56. data/cockpit/themes/extended/rngs/callmanipulate.rng +32 -7
  57. data/cockpit/themes/extended/rngs/closed_loop_control.rng +2 -2
  58. data/cockpit/themes/extended/rngs/closed_loop_measuring.rng +3 -3
  59. data/cockpit/themes/extended/rngs/start.rng +110 -72
  60. data/cockpit/themes/extended/symbols/call_sensor.svg +9 -0
  61. data/cockpit/themes/extended/symbols/callmanipulate.svg +3 -3
  62. data/cockpit/themes/extended/symbols/callmanipulate_sensor.svg +11 -0
  63. data/cockpit/themes/extended/symbols/delete.svg +4 -0
  64. data/cockpit/themes/extended/symbols/start_event.svg +5 -0
  65. data/cockpit/themes/extended/symbols/test.svg +74 -0
  66. data/cockpit/themes/extended/theme.js +105 -9
  67. data/cockpit/themes/model/symbols/call_sensor.svg +9 -0
  68. data/cockpit/themes/model/symbols/callmanipulate.svg +3 -3
  69. data/cockpit/themes/model/symbols/callmanipulate_sensor.svg +11 -0
  70. data/cockpit/themes/model/symbols/delete.svg +4 -0
  71. data/cockpit/themes/model/symbols/start_event.svg +5 -0
  72. data/cockpit/themes/model/symbols/test.svg +74 -0
  73. data/cockpit/themes/model/theme.js +50 -4
  74. data/cockpit/themes/packed/rngs/call.rng +127 -86
  75. data/cockpit/themes/packed/rngs/callmanipulate.rng +32 -7
  76. data/cockpit/themes/packed/rngs/closed_loop_control.rng +2 -2
  77. data/cockpit/themes/packed/rngs/closed_loop_measuring.rng +3 -3
  78. data/cockpit/themes/packed/rngs/start.rng +110 -72
  79. data/cockpit/themes/packed/symbols/call_sensor.svg +9 -0
  80. data/cockpit/themes/packed/symbols/callmanipulate.svg +3 -3
  81. data/cockpit/themes/packed/symbols/callmanipulate_sensor.svg +11 -0
  82. data/cockpit/themes/packed/symbols/delete.svg +4 -0
  83. data/cockpit/themes/packed/symbols/start_event.svg +5 -0
  84. data/cockpit/themes/packed/symbols/test.svg +74 -0
  85. data/cockpit/themes/packed/theme.js +105 -9
  86. data/cockpit/themes/preset/rngs/call.rng +127 -86
  87. data/cockpit/themes/preset/rngs/callmanipulate.rng +32 -7
  88. data/cockpit/themes/preset/rngs/closed_loop_control.rng +2 -2
  89. data/cockpit/themes/preset/rngs/closed_loop_measuring.rng +3 -3
  90. data/cockpit/themes/preset/rngs/start.rng +110 -72
  91. data/cockpit/themes/preset/symbols/call_sensor.svg +9 -0
  92. data/cockpit/themes/preset/symbols/callmanipulate.svg +3 -3
  93. data/cockpit/themes/preset/symbols/callmanipulate_sensor.svg +11 -0
  94. data/cockpit/themes/preset/symbols/delete.svg +4 -0
  95. data/cockpit/themes/preset/symbols/start_event.svg +5 -0
  96. data/cockpit/themes/preset/symbols/test.svg +74 -0
  97. data/cockpit/themes/preset/theme.js +105 -9
  98. data/cpee.gemspec +6 -5
  99. data/lib/cpee/fail.rb +23 -0
  100. data/lib/cpee/implementation.rb +144 -49
  101. data/lib/cpee/implementation_callbacks.rb +11 -10
  102. data/lib/cpee/implementation_notifications.rb +4 -3
  103. data/lib/cpee/implementation_properties.rb +2 -2
  104. data/lib/cpee/message.rb +49 -15
  105. data/lib/cpee/persistence.rb +34 -12
  106. data/lib/cpee.xml +1 -1
  107. data/server/executionhandlers/ruby/backend/instance.template +1 -1
  108. data/server/executionhandlers/ruby/backend/run +4 -4
  109. data/server/executionhandlers/ruby/connection.rb +93 -34
  110. data/server/executionhandlers/ruby/controller.rb +29 -19
  111. data/server/executionhandlers/ruby/desc.xml +107 -0
  112. data/server/executionhandlers/ruby/dsl_to_dslx.xsl +67 -24
  113. data/server/executionhandlers/ruby/execution.rb +1 -0
  114. data/server/resources/states.xml +3 -0
  115. data/server/resources/test.pdf +0 -0
  116. data/server/resources/topics.xml +4 -2
  117. data/server/routing/end.pid +1 -0
  118. data/server/routing/end.rb +3 -2
  119. data/server/routing/forward-events-00.pid +1 -0
  120. data/server/routing/forward-events.rb +26 -13
  121. data/server/routing/forward-votes.pid +1 -0
  122. data/server/routing/forward-votes.rb +4 -4
  123. data/server/routing/persist.pid +1 -0
  124. data/server/routing/persist.rb +41 -31
  125. data/server/server.pid +1 -0
  126. data/tools/cpee +99 -24
  127. metadata +80 -32
  128. data/cockpit/templates/Coopis 2010.xml.active +0 -1
  129. data/cockpit/templates/Coopis 2010.xml.active-uuid +0 -1
  130. data/cockpit/templates/Subprocess.xml.active +0 -1
  131. data/cockpit/templates/Subprocess.xml.active-uuid +0 -1
  132. data/cockpit/templates/Track Test.xml.active +0 -1
  133. data/cockpit/templates/Track Test.xml.active-uuid +0 -1
  134. data/cockpit/templates/UR-VUE 2020 Solution Baseline.xml.active +0 -1
  135. data/cockpit/templates/UR-VUE 2020 Solution Baseline.xml.active-uuid +0 -1
  136. data/cockpit/templates/Wait.xml.active +0 -1
  137. data/cockpit/templates/Wait.xml.active-uuid +0 -1
  138. data/cockpit/templates/Wait.xml.attrs +0 -13
  139. 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 opts[:redis].sismember("instance:#{id}/callbacks",callback)
58
+ if CPEE::Persistence::is_member?(id,opts,'callbacks',callback)
58
59
  res = {}
59
- res[:uuid] = opts[:redis].get("instance:#{id}/callback/#{callback}/uuid")
60
- res[:type] = opts[:redis].get("instance:#{id}/callback/#{callback}/type")
61
- res[:position] = opts[:redis].get("instance:#{id}/callback/#{callback}/position")
62
- res[:label] = opts[:redis].get("instance:#{id}/callback/#{callback}/label")
63
- if sub = opts[:redis].get("instance:#{id}/callback/#{callback}/subscription")
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[:redis].get("instance:#{id}/callback/#{callback}/type") == 'callback'
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[:redis].get("instance:#{id}/callback/#{callback}/type") == 'vote'
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[:redis].get("instance:#{id}/callback/#{callback}/type") == 'callback'
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[:redis].get("instance:#{id}/callback/#{callback}/type") == 'vote'
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.to_i,key)
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').to_i)&.each do |key,sse|
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, :timestamp => Time.now.xmlschema(3))
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::send(type, event, cpee, instance, instance_uuid, instance_name, content={}, backend)
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
- backend.publish(type.to_s + ':' + event,
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
@@ -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("instance:#{id}/#{item}").map do |e|
41
- [e,opts[:redis].get("instance:#{id}/#{item}/#{e}")]
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("instance:#{id}/#{item}",0,-1).map do |e|
46
- [e,opts[:redis].get("instance:#{id}/#{item}/#{e}")]
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("instance:#{id}/#{item}")
68
+ opts[:redis].get(@@obj + ":#{id}/#{item}")
64
69
  end #}}}
65
70
 
66
71
  def self::exists?(id,opts) #{{{
67
- opts[:redis].exists?("instance:#{id}/state")
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("instance:#{id}/handlers/#{key}")
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("instance:#{id}/handlers/#{key}")
126
+ opts[:redis].smembers(@@obj + ":#{id}/handlers/#{key}")
105
127
  end #}}}
106
128
  def self::exists_handler?(id,opts,key) #{{{
107
- opts[:redis].exists?("instance:#{id}/handlers/#{key}")
129
+ opts[:redis].exists?(@@obj + ":#{id}/handlers/#{key}")
108
130
  end #}}}
109
131
  def self::extract_handlers(id,opts) #{{{
110
- opts[:redis].smembers("instance:#{id}/handlers").map do |e|
111
- [e, opts[:redis].get("instance:#{id}/handlers/#{e}/url")]
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. See the GNU General Public License for more details.
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.exists? global_controller
9
+ if File.exist? global_controller
10
10
  require global_controller
11
- elsif File.exists? controller
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.exists? global_connectionhandler
17
+ if File.exist? global_connectionhandler
18
18
  require global_connectionhandler
19
- elsif File.exists? connectionhandler
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
- controller.notify("description/error", :message => err.message)
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
- if replay && @controller.attributes[:replayer]
63
- @handler_endpoint = @controller.attributes[:replayer]
64
- else
65
- @handler_endpoint = endpoints.is_a?(Array) ? endpoints.map{ |ep| readonly.endpoints[ep] }.compact : readonly.endpoints[endpoints]
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
- { :attributes => @controller.attributes }
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
- tendpoint = @handler_endpoint.sub(/^http(s)?-(get|put|post|delete):/,'http\\1:')
118
- type = $2 || parameters[:method] || 'post'
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
- client = Riddl::Client.new(tendpoint)
139
+ client = Riddl::Client.new(tendpoint)
121
140
 
122
- @handler_passthrough = callback
123
- @controller.callback(self,callback,:'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position)
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 = JSON::parse(r.value.read) rescue nil
275
- if ttt.nil?
276
- ''
277
- else
278
- enc = detect_encoding(ttt)
279
- enc == 'OTHER' ? ttt : (ttt.encode('UTF-8',enc) rescue convert_to_base64(ttt))
280
- end
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
- @controller.notify("activity/receiving", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint, :received => structurize_result(result), :annotations => @anno)
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("condition/eval", :instance_uuid => @controller.uuid, :code => code, :condition => (res ? "true" : "false"))
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 simulate(type,nesting,tid,parent,parameters={}) #{{{
341
- pp "#{type} - #{nesting} - #{tid} - #{parent} - #{parameters.inspect}"
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,