cpee 2.1.61 → 2.1.62
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/cockpit/js/edit.js +2 -0
- data/cockpit/js/instance.js +5 -1
- data/cpee.gemspec +4 -2
- data/lib/cpee/implementation_properties.rb +1 -0
- data/server/executionhandlers/ruby/connection.rb +22 -102
- data/server/executionhandlers/ruby/controller.rb +0 -1
- data/server/executionhandlers/ruby/dsl_to_dslx.xsl +5 -3
- data/server/executionhandlers/rubyext/backend/README.md +17 -0
- data/server/executionhandlers/rubyext/backend/instance.template +18 -0
- data/server/executionhandlers/rubyext/backend/opts.yaml +8 -0
- data/server/executionhandlers/rubyext/backend/run +38 -0
- data/server/executionhandlers/rubyext/connection.rb +431 -0
- data/server/executionhandlers/rubyext/controller.rb +210 -0
- data/server/executionhandlers/rubyext/dsl_to_dslx.xsl +914 -0
- data/server/executionhandlers/rubyext/execution.rb +84 -0
- data/server/routing/end.pid +1 -1
- data/server/routing/forward-events-00.pid +1 -1
- data/server/routing/forward-votes.pid +1 -1
- data/server/routing/persist.pid +1 -1
- metadata +41 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: de80687b26430a0d4051fded9d255695cbe12bd5d3f5595bbaf370076d0bc7ef
|
4
|
+
data.tar.gz: a97d8605202a279b884a7872f7045270b0600ca7ebd889aadd598222f4671992
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9f8223d762b0396e5bfe72bb5f3aa649ddcac18d9d69e3d4e009272f7acaef9119c5de0489110c795f46b3b9fa3e482b6754615da2c067ba8f981a00ebee3a03
|
7
|
+
data.tar.gz: 731c82b38a6a493535becdf2389c57d0471e182442d86d7b198d79aa8b7470af8ffd0a4042847257eb9fbbee707adb2e88cb946b5f181e116ffe00c57bf547ea
|
data/cockpit/js/edit.js
CHANGED
data/cockpit/js/instance.js
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
var es;
|
2
2
|
var suspended_redrawing = false;
|
3
|
+
var skip_location = false;
|
3
4
|
var myid = ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16));
|
4
5
|
var paths = '#dat_details input, #dat_details textarea, #dat_details select, #dat_details button, #dat_details [contenteditable], #dat_dataelements input, #dat_dataelements textarea, #dat_dataelements select, #dat_dataelements button, #dat_dataelements [contenteditable], #dat_endpoints input, #dat_endpoints textarea, #dat_endpoints select, #dat_endpoints button, #dat_endpoints [contenteditable], #dat_attributes input, #dat_attributes textarea, #dat_attributes select, #dat_attributes button, #dat_attributes [contenteditable]';
|
5
6
|
var loading = false;
|
@@ -1175,7 +1176,10 @@ async function set_testset(testset,exec) {// {{{
|
|
1175
1176
|
tset.append($("testset > attributes",testset));
|
1176
1177
|
tset.append($("testset > description",testset));
|
1177
1178
|
tset.append($("testset > transformation",testset));
|
1178
|
-
|
1179
|
+
if (skip_location) {
|
1180
|
+
$('properties > attributes > info',tset).remove();
|
1181
|
+
$('properties > attributes > design_dir',tset).remove();
|
1182
|
+
}
|
1179
1183
|
|
1180
1184
|
promises.push(
|
1181
1185
|
$.ajax({
|
data/cpee.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "cpee"
|
3
|
-
s.version = "2.1.
|
3
|
+
s.version = "2.1.62"
|
4
4
|
s.platform = Gem::Platform::RUBY
|
5
5
|
s.license = "LGPL-3.0-or-later"
|
6
6
|
s.summary = "The cloud process execution engine (cpee.org). If you just need workflow execution, without a rest service exposing it, then use WEEL."
|
@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.homepage = 'http://cpee.org/'
|
23
23
|
|
24
24
|
s.add_runtime_dependency 'riddl', '~> 1.0'
|
25
|
-
s.add_runtime_dependency 'weel', '~> 1.99', '>= 1.99.
|
25
|
+
s.add_runtime_dependency 'weel', '~> 1.99', '>= 1.99.121'
|
26
26
|
s.add_runtime_dependency 'highline', '~> 2.0'
|
27
27
|
s.add_runtime_dependency 'redis', '~> 5.0'
|
28
28
|
s.add_runtime_dependency 'rubyzip', '~>2'
|
@@ -30,4 +30,6 @@ Gem::Specification.new do |s|
|
|
30
30
|
s.add_runtime_dependency 'mimemagic', '~>0'
|
31
31
|
s.add_runtime_dependency 'get_process_mem', '~>0.2'
|
32
32
|
s.add_runtime_dependency 'webrick', '~>1.7'
|
33
|
+
s.add_runtime_dependency 'rbtrace', '~>0.4'
|
34
|
+
s.add_runtime_dependency 'cpee-eval-ruby', '~> 1.0'
|
33
35
|
end
|
@@ -109,6 +109,7 @@ module CPEE
|
|
109
109
|
doc.find('/p:properties/p:state/@changed').first.value = CPEE::Persistence::extract_item(id,opts,'state/@changed')
|
110
110
|
doc.find('/p:properties/p:status/p:id').first.text = CPEE::Persistence::extract_item(id,opts,'status/id')
|
111
111
|
doc.find('/p:properties/p:status/p:message').first.text = CPEE::Persistence::extract_item(id,opts,'status/message')
|
112
|
+
doc.find('/p:properties/p:executionhandler').first.text = CPEE::Persistence::extract_item(id,opts,'executionhandler')
|
112
113
|
%w{dataelements endpoints attributes}.each do |item|
|
113
114
|
des = doc.find("/p:properties/p:#{item}").first
|
114
115
|
CPEE::Persistence::extract_list(id,opts,item).each{ |de| des.add(*de) }
|
@@ -16,6 +16,7 @@ require 'charlock_holmes'
|
|
16
16
|
require 'mimemagic'
|
17
17
|
require 'base64'
|
18
18
|
require 'get_process_mem'
|
19
|
+
require 'cpee-eval-ruby/translation'
|
19
20
|
|
20
21
|
class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
21
22
|
def self::loop_guard(arguments,id,count) # {{{
|
@@ -35,6 +36,9 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
35
36
|
def self::inform_syntax_error(arguments,err,code)# {{{
|
36
37
|
# TODO extract spot (code) where error happened for better error handling (ruby 3.1 only)
|
37
38
|
# https://github.com/rails/rails/pull/45818/commits/3beb2aff3be712e44c34a588fbf35b79c0246ca5
|
39
|
+
puts err.message
|
40
|
+
puts err.backtrace
|
41
|
+
|
38
42
|
controller = arguments[0]
|
39
43
|
mess = err.backtrace ? err.backtrace[0].gsub(/([\w -_]+):(\d+):in.*/,'\\1, Line \2: ') : ''
|
40
44
|
mess += err.message
|
@@ -273,7 +277,7 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
273
277
|
@controller.notify("status/change", :'activity-uuid' => @handler_activity_uuid, :endpoint => @handler_endpoint, :label => @label, :activity => @handler_position, :id => status.id, :message => status.message)
|
274
278
|
end
|
275
279
|
unless changed_dataelements.nil? || changed_dataelements.empty?
|
276
|
-
de = dataelements.slice(*changed_dataelements).transform_values { |v| enc = detect_encoding(v); (enc == 'OTHER' ? v : (v.encode('UTF-8',enc) rescue convert_to_base64(v))) }
|
280
|
+
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))) }
|
277
281
|
@controller.notify("dataelements/change", :'activity-uuid' => @handler_activity_uuid, :endpoint => @handler_endpoint, :label => @label, :activity => @handler_position, :changed => changed_dataelements, :values => de)
|
278
282
|
end
|
279
283
|
unless changed_endpoints.nil? || changed_endpoints.empty?
|
@@ -288,105 +292,8 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
288
292
|
@controller.vote("activity/syncing_before", :'activity-uuid' => @handler_activity_uuid, :endpoint => @handler_endpoint, :activity => @handler_position, :label => @label, :parameters => parameters)
|
289
293
|
end # }}}
|
290
294
|
|
291
|
-
def simplify_result(result)
|
292
|
-
if result.length == 1
|
293
|
-
if result[0].is_a? Riddl::Parameter::Simple
|
294
|
-
result = result[0].value
|
295
|
-
elsif result[0].is_a? Riddl::Parameter::Complex
|
296
|
-
if result[0].mimetype == 'application/json'
|
297
|
-
result = JSON::parse(result[0].value.read) rescue nil
|
298
|
-
elsif result[0].mimetype == 'text/csv'
|
299
|
-
result = result[0].value.read
|
300
|
-
elsif result[0].mimetype == 'text/yaml'
|
301
|
-
result = YAML::load(result[0].value.read) rescue nil
|
302
|
-
elsif result[0].mimetype == 'application/xml' || result[0].mimetype == 'text/xml'
|
303
|
-
result = XML::Smart::string(result[0].value.read) rescue nil
|
304
|
-
elsif result[0].mimetype == 'text/plain'
|
305
|
-
result = result[0].value.read
|
306
|
-
if result.start_with?("<?xml version=")
|
307
|
-
result = XML::Smart::string(result)
|
308
|
-
else
|
309
|
-
result = result.to_f if result == result.to_f.to_s
|
310
|
-
result = result.to_i if result == result.to_i.to_s
|
311
|
-
end
|
312
|
-
elsif result[0].mimetype == 'text/html'
|
313
|
-
result = result[0].value.read
|
314
|
-
result = result.to_f if result == result.to_f.to_s
|
315
|
-
result = result.to_i if result == result.to_i.to_s
|
316
|
-
else
|
317
|
-
result = result[0]
|
318
|
-
end
|
319
|
-
end
|
320
|
-
else
|
321
|
-
result = Riddl::Parameter::Array[*result]
|
322
|
-
end
|
323
|
-
if result.is_a? String
|
324
|
-
enc = detect_encoding(result)
|
325
|
-
enc == 'OTHER' ? result : (result.encode('UTF-8',enc) rescue convert_to_base64(result))
|
326
|
-
else
|
327
|
-
result
|
328
|
-
end
|
329
|
-
end
|
330
|
-
|
331
|
-
def detect_encoding(text)
|
332
|
-
if text.is_a? String
|
333
|
-
if text.valid_encoding? && text.encoding.name == 'UTF-8'
|
334
|
-
'UTF-8'
|
335
|
-
else
|
336
|
-
res = CharlockHolmes::EncodingDetector.detect(text)
|
337
|
-
if res.is_a?(Hash) && res[:type] == :text && res[:ruby_encoding] != "binary"
|
338
|
-
res[:encoding]
|
339
|
-
elsif res.is_a?(Hash) && res[:type] == :binary
|
340
|
-
'BINARY'
|
341
|
-
else
|
342
|
-
'ISO-8859-1'
|
343
|
-
end
|
344
|
-
end
|
345
|
-
else
|
346
|
-
'OTHER'
|
347
|
-
end
|
348
|
-
end
|
349
|
-
|
350
|
-
def convert_to_base64(text)
|
351
|
-
('data:' + MimeMagic.by_magic(text).type + ';base64,' + Base64::encode64(text)) rescue ('data:application/octet-stream;base64,' + Base64::encode64(text))
|
352
|
-
end
|
353
|
-
|
354
|
-
def structurize_result(result)
|
355
|
-
result.map do |r|
|
356
|
-
if r.is_a? Riddl::Parameter::Simple
|
357
|
-
{ 'name' => r.name, 'data' => r.value }
|
358
|
-
elsif r.is_a? Riddl::Parameter::Complex
|
359
|
-
res = if r.mimetype == 'application/json'
|
360
|
-
ttt = r.value.read
|
361
|
-
enc = detect_encoding(ttt)
|
362
|
-
enc == 'OTHER' ? ttt.inspect : (ttt.encode('UTF-8',enc) rescue convert_to_base64(ttt))
|
363
|
-
elsif r.mimetype == 'text/csv'
|
364
|
-
ttt = r.value.read
|
365
|
-
enc = detect_encoding(ttt)
|
366
|
-
enc == 'OTHER' ? ttt.inspect : (ttt.encode('UTF-8',enc) rescue convert_to_base64(ttt))
|
367
|
-
elsif r.mimetype == 'text/plain' || r.mimetype == 'text/html'
|
368
|
-
ttt = r.value.read
|
369
|
-
ttt = ttt.to_f if ttt == ttt.to_f.to_s
|
370
|
-
ttt = ttt.to_i if ttt == ttt.to_i.to_s
|
371
|
-
enc = detect_encoding(ttt)
|
372
|
-
enc == 'OTHER' ? ttt.inspect : (ttt.encode('UTF-8',enc) rescue convert_to_base64(ttt))
|
373
|
-
else
|
374
|
-
convert_to_base64(r.value.read)
|
375
|
-
end
|
376
|
-
|
377
|
-
tmp = {
|
378
|
-
'name' => r.name == '' ? 'result' : r.name,
|
379
|
-
'mimetype' => r.mimetype,
|
380
|
-
'data' => res.to_s
|
381
|
-
}
|
382
|
-
r.value.rewind
|
383
|
-
tmp
|
384
|
-
end
|
385
|
-
end
|
386
|
-
end
|
387
|
-
|
388
295
|
def callback(result=nil,options={})
|
389
|
-
recv = structurize_result(result)
|
296
|
+
recv = CPEE::EvalRuby::Translation::structurize_result(result)
|
390
297
|
@controller.notify("activity/receiving", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint, :received => recv, :annotations => @anno)
|
391
298
|
|
392
299
|
@guard_files += result
|
@@ -397,7 +304,7 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
397
304
|
if options['CPEE_EVENT']
|
398
305
|
@controller.notify("task/#{options['CPEE_EVENT'].gsub(/[^\w_-]/,'')}", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint, :received => recv)
|
399
306
|
else
|
400
|
-
@handler_returnValue =
|
307
|
+
@handler_returnValue = recv
|
401
308
|
@handler_returnOptions = options
|
402
309
|
end
|
403
310
|
if options['CPEE_STATUS']
|
@@ -430,11 +337,24 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
430
337
|
GC.start
|
431
338
|
end #}}}
|
432
339
|
|
433
|
-
def test_condition(
|
434
|
-
res =
|
340
|
+
def test_condition(dataelements,endpoints,local,additional,code,args={})
|
341
|
+
res = WEEL::ReadStructure.new(dataelements,endpoints,local,additional).instance_eval(code,'Condition',1)
|
435
342
|
@controller.notify("gateway/decide", :instance_uuid => @controller.uuid, :code => code, :condition => (res ? "true" : "false"))
|
436
343
|
res
|
437
344
|
end
|
345
|
+
def eval_expression(dataelements,endpoints,local,additional,code)
|
346
|
+
WEEL::ReadStructure.new(dataelements,endpoints,local,additional).instance_eval(code)
|
347
|
+
end
|
348
|
+
def manipulate(readonly,lock,dataelements,endpoints,status,local,additional,code,where,result=nil,options=nil)
|
349
|
+
result = CPEE::EvalRuby::Translation::simplify_structurized_result(result)
|
350
|
+
struct = if readonly
|
351
|
+
WEEL::ReadStructure.new(dataelements,endpoints,local,additional)
|
352
|
+
else
|
353
|
+
WEEL::ManipulateStructure.new(dataelements,endpoints,status,local,additional)
|
354
|
+
end
|
355
|
+
struct.instance_eval(code,where,1)
|
356
|
+
struct
|
357
|
+
end
|
438
358
|
|
439
359
|
def join_branches(branches) # factual, so for inclusive or [[a],[b],[c,d,e]]
|
440
360
|
@controller.notify("gateway/join", :instance_uuid => @controller.uuid, :branches => branches)
|
@@ -622,7 +622,7 @@
|
|
622
622
|
</xsl:call-template>
|
623
623
|
</xsl:otherwise>
|
624
624
|
</xsl:choose>
|
625
|
-
<xsl:text>, :value =>
|
625
|
+
<xsl:text>, :value => </xsl:text>
|
626
626
|
<xsl:choose>
|
627
627
|
<xsl:when test="not(node())">
|
628
628
|
<xsl:text>nil</xsl:text>
|
@@ -645,7 +645,9 @@
|
|
645
645
|
<xsl:otherwise>
|
646
646
|
<xsl:choose>
|
647
647
|
<xsl:when test="substring(text(),1,1) = '!'">
|
648
|
-
<xsl:
|
648
|
+
<xsl:text>🠊("</xsl:text>
|
649
|
+
<xsl:value-of select="str:replace(str:replace(substring(text(),2),'\','\\'),'"','\"')"/>
|
650
|
+
<xsl:text>")</xsl:text>
|
649
651
|
</xsl:when>
|
650
652
|
<xsl:otherwise>
|
651
653
|
<xsl:text>"</xsl:text>
|
@@ -655,7 +657,7 @@
|
|
655
657
|
</xsl:choose>
|
656
658
|
</xsl:otherwise>
|
657
659
|
</xsl:choose>
|
658
|
-
<xsl:text>
|
660
|
+
<xsl:text> </xsl:text>
|
659
661
|
<xsl:for-each select="@*">
|
660
662
|
<xsl:text>, :</xsl:text>
|
661
663
|
<xsl:value-of select="name()"/>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
* run is copied into every instance.
|
2
|
+
* opts.yaml is written on each start.
|
3
|
+
* instance.rb is written on each start.
|
4
|
+
|
5
|
+
## What can you do to make it more robust?
|
6
|
+
|
7
|
+
Replace run with a program that actually compiles and runs instance.rb. Of
|
8
|
+
courses the transformation_* xslts would have to be adapted to create suitable
|
9
|
+
code. The compiled executable would just need to behave the same as the instance.rb,
|
10
|
+
dispersing all the same events through redis.
|
11
|
+
|
12
|
+
More suitable languages would be crystal and javascript, c++. Less suitable,
|
13
|
+
but doable, would be python, C. I.e., all languages that do not support multi-line
|
14
|
+
lambdas would produce much less readable code, thus the "Description" tab in
|
15
|
+
the cockpit would be garbage.
|
16
|
+
|
17
|
+
Definitely do tell me if you are interessted in doing something like this ;-)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<%# coding: UTF-8 %>
|
2
|
+
class Instance < WEEL
|
3
|
+
connectionwrapper ConnectionWrapper
|
4
|
+
|
5
|
+
<% for key, value in endpoints -%>
|
6
|
+
endpoint :<%= key %> => <%= CPEE::ValueHelper::parse(value).inspect %>
|
7
|
+
<% end -%>
|
8
|
+
|
9
|
+
<% for key, value in dataelements -%>
|
10
|
+
data :<%= key %> => <%= CPEE::ValueHelper::parse(value).inspect %>
|
11
|
+
<% end -%>
|
12
|
+
|
13
|
+
<% unless positions.nil? || positions.empty? -%>
|
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
|
+
<% end -%>
|
16
|
+
|
17
|
+
<%= dsl.strip.gsub(/\n/,"\n ") %>
|
18
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
:host: localhost
|
2
|
+
:url: http://localhost:8298/
|
3
|
+
:redis_path: /tmp/redis.sock
|
4
|
+
:redis_db: 3
|
5
|
+
:executionhandlers: ../../executionhandlers/
|
6
|
+
:executionhandler: rubyext
|
7
|
+
:url_result_transformation: http://localhost:9302/structurize
|
8
|
+
:url_code: http://localhost:9302/exec
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
require 'rbtrace'
|
3
|
+
require 'yaml'
|
4
|
+
opts = YAML::load_file(File.join(__dir__,'opts.yaml'))
|
5
|
+
opts[:pidf] = __FILE__ + '.pid'
|
6
|
+
opts[:pid] = Process.pid
|
7
|
+
|
8
|
+
global_controller = File.join(opts[:global_executionhandlers],opts[:executionhandler],'controller.rb')
|
9
|
+
controller = File.join(opts[:executionhandlers], opts[:executionhandler],'controller.rb')
|
10
|
+
if File.exist? global_controller
|
11
|
+
require global_controller
|
12
|
+
elsif File.exist? controller
|
13
|
+
require controller
|
14
|
+
end
|
15
|
+
|
16
|
+
global_connectionhandler = File.join(opts[:global_executionhandlers],opts[:executionhandler],'connection.rb')
|
17
|
+
connectionhandler = File.join(opts[:executionhandlers], opts[:executionhandler],'connection.rb')
|
18
|
+
if File.exist? global_connectionhandler
|
19
|
+
require global_connectionhandler
|
20
|
+
elsif File.exist? connectionhandler
|
21
|
+
require connectionhandler
|
22
|
+
end
|
23
|
+
|
24
|
+
require_relative 'instance'
|
25
|
+
controller = Controller.new(File.basename(__dir__).to_i, __dir__, opts)
|
26
|
+
controller.instance = Instance.new controller
|
27
|
+
|
28
|
+
File.write(opts[:pidf],opts[:pid])
|
29
|
+
|
30
|
+
%w{TERM HUP INT}.each do |sig|
|
31
|
+
Signal.trap(sig) do
|
32
|
+
puts "Caught #{sig}!"
|
33
|
+
controller.stop
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
controller.start
|
38
|
+
File.unlink(opts[:pidf])
|