cpee 2.1.61 → 2.1.62
Sign up to get free protection for your applications and to get access to all the features.
- 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])
|