cpee 2.1.10 → 2.1.14
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/css/ui.css +4 -5
- data/cockpit/js/instance.js +13 -10
- data/cockpit/js/modifiers.js +10 -8
- data/cockpit/templates/Worklist.xml +8 -8
- data/cpee.gemspec +2 -1
- data/lib/cpee/implementation.rb +2 -2
- data/lib/cpee/implementation_notifications.rb +1 -1
- data/lib/cpee/redis.rb +8 -7
- data/server/executionhandlers/ruby/connection.rb +11 -1
- data/server/executionhandlers/ruby/controller.rb +5 -5
- data/server/routing/end.rb +2 -2
- data/server/routing/forward-events.rb +2 -2
- data/server/routing/forward-votes.rb +5 -5
- data/server/routing/persist.rb +2 -2
- metadata +16 -7
- data/server/routing/end.pid +0 -1
- data/server/routing/forward-events.pid +0 -1
- data/server/routing/forward-votes.pid +0 -1
- data/server/routing/persist.pid +0 -1
- data/tools/cpee.sic +0 -306
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 41c8af6dfe0026a757a1cb1d3627415773aabf2e99712ac77207de2f518fbf0e
|
4
|
+
data.tar.gz: 8b02404db658a5e2a6219e5b3843cee54beed9df08356d615c504bd56851b61d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 04104b072172fa082b879e414f6ffec58d21fe99be5ec18a7fd3a070947139cf30d7f02e377b34bcd8e61cc9f5afef1570971224c4786e5338ab9c02c11cd50f
|
7
|
+
data.tar.gz: 3cb492d19adf14b727c6ce14cd4edd2dcca0da1819502b63b20a68a249ce78a5c803b19c18a23d9051f00734cbb161cd0e9eac2ecb9efec2ce3d667cfa663440
|
data/cockpit/css/ui.css
CHANGED
@@ -135,7 +135,7 @@ ui-tabbed ui-tabbar ui-behind button {
|
|
135
135
|
#areainstance div.section { vertical-align: middle; height: 100%; }
|
136
136
|
#areainstance div.section:nth-child(1) { flex: 0 0 auto; padding: 0 0.5em 0 0; white-space: nowrap; }
|
137
137
|
#areainstance div.section:nth-child(2) { flex: 0 0 auto; border-left: 1px solid var(--x-ui-border-color); padding: 0 0.5em; white-space: nowrap; }
|
138
|
-
#areainstance div.section:nth-child(3) { flex: 1 1 auto; border-left: 1px solid var(--x-ui-border-color); padding: 0 0 0 0.5em;
|
138
|
+
#areainstance div.section:nth-child(3) { flex: 1 1 auto; border-left: 1px solid var(--x-ui-border-color); padding: 0 0 0 0.5em; }
|
139
139
|
|
140
140
|
#areainstance div.section:nth-child(1) > div:nth-child(2) { white-space: normal; text-align: right; }
|
141
141
|
|
@@ -148,10 +148,9 @@ ui-tabbed ui-tabbar ui-behind button {
|
|
148
148
|
|
149
149
|
#areainstance div.section:nth-child(2) button { white-space: normal; width: 6em; height: 5.7em; vertical-align: middle; margin: 0; padding: 0; }
|
150
150
|
|
151
|
-
#areainstance div.section:nth-child(3) { overflow-y: scroll; }
|
151
|
+
#areainstance div.section:nth-child(3) { overflow-y: scroll; overflow-x: hidden; display: flex; flex-direction: column; flex-wrap: wrap; justify-content: flex-start; align-content: flex-start; }
|
152
152
|
#areainstance div.section:nth-child(3) strong { margin:0; padding:0; white-space: normal; font-size: 0.7em; }
|
153
|
-
#areainstance div.section:nth-child(3) > div
|
154
|
-
#areainstance div.section:nth-child(3) > div { padding-bottom: 0em; }
|
153
|
+
#areainstance div.section:nth-child(3) > div { padding-bottom: 0.2em; flex: 0 0 auto; padding-right: 1em; }
|
155
154
|
#areainstance div.section:nth-child(3) select { margin-left: 1em; }
|
156
155
|
#areainstance div.section:nth-child(3) div.additional { margin: 0 1em; font-size: 0.9em; }
|
157
156
|
|
@@ -243,4 +242,4 @@ span.vote {
|
|
243
242
|
overflow: auto;
|
244
243
|
}
|
245
244
|
#disclaimer p { max-width: 80ex; text-align: justify; }
|
246
|
-
#disclaimer input { margin:0; padding:0; vertical-align:
|
245
|
+
#disclaimer input { margin:0; padding:0; vertical-align:bottom; margin-right: 0.5em; }
|
data/cockpit/js/instance.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
var es;
|
2
|
-
var
|
2
|
+
var suspended_redrawing = false;
|
3
3
|
var myid = ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16));
|
4
4
|
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
5
|
var loading = false;
|
@@ -13,7 +13,7 @@ var save = {};
|
|
13
13
|
var node_state = {};
|
14
14
|
|
15
15
|
function global_init() {
|
16
|
-
|
16
|
+
suspended_redrawing = false;
|
17
17
|
loading = false;
|
18
18
|
subscription = undefined;
|
19
19
|
subscription_state = 'less';
|
@@ -56,7 +56,7 @@ var sub_more = 'topic' + '=' + 'activity' + '&' +// {{{
|
|
56
56
|
'events' + '=' + 'instantiation' + '&' +
|
57
57
|
'topic' + '=' + 'transformation' + '&' +
|
58
58
|
'events' + '=' + 'change' + '&' +
|
59
|
-
'topic' + '=' + '
|
59
|
+
'topic' + '=' + 'executionhandler' + '&' +
|
60
60
|
'events' + '=' + 'error,change' + '&' +
|
61
61
|
'topic' + '=' + 'handlers' + '&' +
|
62
62
|
'events' + '=' + 'change';// }}}
|
@@ -78,7 +78,7 @@ var sub_less = 'topic' + '=' + 'activity' + '&' +// {{{
|
|
78
78
|
'events' + '=' + 'instantiation' + '&' +
|
79
79
|
'topic' + '=' + 'transformation' + '&' +
|
80
80
|
'events' + '=' + 'change' + '&' +
|
81
|
-
'topic' + '=' + '
|
81
|
+
'topic' + '=' + 'executionhandler' + '&' +
|
82
82
|
'events' + '=' + 'error,change' + '&' +
|
83
83
|
'topic' + '=' + 'handlers' + '&' +
|
84
84
|
'events' + '=' + 'change';// }}}
|
@@ -280,10 +280,8 @@ function sse() { //{{{
|
|
280
280
|
break;
|
281
281
|
case 'attributes':
|
282
282
|
monitor_instance_values("attributes");
|
283
|
-
if (
|
284
|
-
|
285
|
-
monitor_graph_change(true);
|
286
|
-
}
|
283
|
+
if (save['graph_theme'] != data.content.values.theme) {
|
284
|
+
monitor_graph_change(true);
|
287
285
|
}
|
288
286
|
break;
|
289
287
|
case 'task':
|
@@ -482,7 +480,11 @@ function adaptor_update() { //{{{
|
|
482
480
|
});
|
483
481
|
} //}}}
|
484
482
|
function adaptor_init(url,theme,dslx) { //{{{
|
483
|
+
// while inside and svgs are reloaded, do nothing here
|
484
|
+
if (suspended_redrawing) { return; }
|
485
485
|
if (save['graph_theme'] != theme) {
|
486
|
+
// while inside and svgs are reloaded, do nothing here
|
487
|
+
suspended_redrawing = true;
|
486
488
|
save['graph_theme'] = theme;
|
487
489
|
save['graph_adaptor'] = new WfAdaptor($('body').data('theme-base') + '/' + theme + '/theme.js',function(graphrealization){
|
488
490
|
manifestation.endpoints = save.endpoints_list;
|
@@ -570,6 +572,9 @@ function adaptor_init(url,theme,dslx) { //{{{
|
|
570
572
|
adaptor_update();
|
571
573
|
monitor_instance_pos();
|
572
574
|
$('#dat_details').empty();
|
575
|
+
|
576
|
+
// while inside and svgs are reloaded, do nothing here
|
577
|
+
suspended_redrawing = false;
|
573
578
|
});
|
574
579
|
} else {
|
575
580
|
save['graph_adaptor'].update(function(graphrealization){
|
@@ -580,7 +585,6 @@ function adaptor_init(url,theme,dslx) { //{{{
|
|
580
585
|
format_instance_pos();
|
581
586
|
});
|
582
587
|
}
|
583
|
-
suspended_monitoring = false;
|
584
588
|
} //}}}
|
585
589
|
|
586
590
|
function monitor_graph_change(force) { //{{{
|
@@ -921,7 +925,6 @@ function save_svgfile() {// {{{
|
|
921
925
|
}// }}}
|
922
926
|
async function set_testset(testset,exec) {// {{{
|
923
927
|
var url = $('body').attr('current-instance');
|
924
|
-
suspended_monitoring = true;
|
925
928
|
|
926
929
|
var promises = [];
|
927
930
|
|
data/cockpit/js/modifiers.js
CHANGED
@@ -42,7 +42,7 @@ function do_mod_save(target) {
|
|
42
42
|
let top = div.attr('data-resource');
|
43
43
|
let doc = save['modifiers_additional'][top].save();
|
44
44
|
let rep = $('body').attr('current-resources');
|
45
|
-
let now =
|
45
|
+
let now = $('div.select select',div).val();
|
46
46
|
|
47
47
|
var tset = $X('<testset xmlns="http://cpee.org/ns/properties/2.0"/>');
|
48
48
|
tset.append(doc.documentElement);
|
@@ -69,12 +69,13 @@ async function modifiers_display() {
|
|
69
69
|
let clone = document.importNode(document.querySelector('#modifiers template').content,true);
|
70
70
|
let t = $(r).text();
|
71
71
|
$('> div',clone).attr('data-resource',t);
|
72
|
-
$('div.title *',clone).text(decodeURIComponent(t));
|
72
|
+
$('div.title *',clone).text(decodeURIComponent(t).replace(/^\d*_?/,''));
|
73
73
|
|
74
74
|
let cpromises = [];
|
75
75
|
$('resource',ses).each(function(_,s) {
|
76
|
-
let opt = $('<option/>');
|
77
|
-
opt.text(decodeURIComponent($(s).text()));
|
76
|
+
let opt = $('<option value=""/>');
|
77
|
+
opt.text(decodeURIComponent($(s).text()).replace(/^\d*_?/,''));
|
78
|
+
opt.attr('value',$(s).text());
|
78
79
|
$('div.select select',clone).append(opt);
|
79
80
|
|
80
81
|
cpromises.push(
|
@@ -120,7 +121,8 @@ function modifiers_display_ui(url,top,it,notchanged) {
|
|
120
121
|
save['modifiers_additional'][top].content(attr);
|
121
122
|
}
|
122
123
|
});
|
123
|
-
}
|
124
|
+
},
|
125
|
+
error: function() {}
|
124
126
|
});
|
125
127
|
}
|
126
128
|
}
|
@@ -134,7 +136,7 @@ function modifiers_select() {
|
|
134
136
|
});
|
135
137
|
$('#modifiers div[data-resource]').each(function(_,r){
|
136
138
|
$('select option',r).each(function(_,s){
|
137
|
-
let where = $(r).attr('data-resource') + '/' +
|
139
|
+
let where = $(r).attr('data-resource') + '/' + $(s).attr('value');
|
138
140
|
let cond = save['modifiers'][where];
|
139
141
|
let success = true;
|
140
142
|
for (x in cond) {
|
@@ -142,8 +144,8 @@ function modifiers_select() {
|
|
142
144
|
}
|
143
145
|
if (success) {
|
144
146
|
let top = $(r).attr('data-resource');
|
145
|
-
let it =
|
146
|
-
$('select',r).val(
|
147
|
+
let it = $(s).attr('value');
|
148
|
+
$('select',r).val(it);
|
147
149
|
modifiers_display_ui(rep + 'modifiers/',top,it,save['modifiers_active'][top] == it);
|
148
150
|
save['modifiers_active'][top] = it;
|
149
151
|
}
|
@@ -12,15 +12,15 @@
|
|
12
12
|
<description xmlns="http://cpee.org/ns/description/1.0">
|
13
13
|
<call id="a1" endpoint="worklist">
|
14
14
|
<parameters>
|
15
|
-
<label>
|
15
|
+
<label>OK OR NOT OK</label>
|
16
16
|
<method>:post</method>
|
17
17
|
<arguments>
|
18
|
-
<orgmodel>
|
19
|
-
<domain>
|
20
|
-
<form>
|
21
|
-
<role>
|
22
|
-
<schaden>
|
23
|
-
<text>
|
18
|
+
<orgmodel>organisation1</orgmodel>
|
19
|
+
<domain>Virtual Business 1</domain>
|
20
|
+
<form>http://cpee.org/~demo/form/form-f.html</form>
|
21
|
+
<role>Regular</role>
|
22
|
+
<schaden>55546</schaden>
|
23
|
+
<text>fetzen hin</text>
|
24
24
|
</arguments>
|
25
25
|
</parameters>
|
26
26
|
<code>
|
@@ -44,4 +44,4 @@
|
|
44
44
|
<design_stage>development</design_stage>
|
45
45
|
<design_dir>Templates.dir</design_dir>
|
46
46
|
</attributes>
|
47
|
-
</testset>
|
47
|
+
</testset>
|
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.14"
|
4
4
|
s.platform = Gem::Platform::RUBY
|
5
5
|
s.license = "LGPL-3.0"
|
6
6
|
s.summary = "Preliminary release of cloud process execution engine (cpee.org). If you just need workflow execution, without a rest service exposing it, then use WEEL."
|
@@ -27,4 +27,5 @@ Gem::Specification.new do |s|
|
|
27
27
|
s.add_runtime_dependency 'json', '~>2.1'
|
28
28
|
s.add_runtime_dependency 'redis', '~> 4.1'
|
29
29
|
s.add_runtime_dependency 'rubyzip', '~>2'
|
30
|
+
s.add_runtime_dependency 'charlock_holmes', '~>0'
|
30
31
|
end
|
data/lib/cpee/implementation.rb
CHANGED
@@ -77,7 +77,7 @@ module CPEE
|
|
77
77
|
opts[:redis_pid] ||= 'redis.pid' # use e.g. /var/run/redis.pid if you do global. Look it up in your redis config
|
78
78
|
opts[:redis_db_name] ||= 'redis.rdb' # use e.g. /var/lib/redis.rdb for global stuff. Look it up in your redis config
|
79
79
|
|
80
|
-
CPEE::redis_connect opts
|
80
|
+
CPEE::redis_connect opts, 'Server Main'
|
81
81
|
|
82
82
|
opts[:sse_keepalive_frequency] ||= 10
|
83
83
|
opts[:sse_connections] = {}
|
@@ -252,7 +252,7 @@ module CPEE
|
|
252
252
|
end
|
253
253
|
|
254
254
|
@headers << Riddl::Header.new("CPEE-INSTANCE", id.to_s)
|
255
|
-
@headers << Riddl::Header.new("CPEE-INSTANCE-URL", File.join(opts[:url].to_s,id.to_s))
|
255
|
+
@headers << Riddl::Header.new("CPEE-INSTANCE-URL", File.join(opts[:url].to_s,id.to_s,'/'))
|
256
256
|
@headers << Riddl::Header.new("CPEE-INSTANCE-UUID", uuid)
|
257
257
|
|
258
258
|
Riddl::Parameter::Simple.new("id", id.to_s)
|
@@ -179,7 +179,7 @@ module CPEE
|
|
179
179
|
end #}}}
|
180
180
|
|
181
181
|
def self::sse_distributor(opts) #{{{
|
182
|
-
conn = opts[:redis_dyn].call
|
182
|
+
conn = opts[:redis_dyn].call "Server SSE"
|
183
183
|
conn.psubscribe('forward:*','event:state/change') do |on|
|
184
184
|
on.pmessage do |pat, what, message|
|
185
185
|
if pat == 'forward:*'
|
data/lib/cpee/redis.rb
CHANGED
@@ -15,29 +15,30 @@
|
|
15
15
|
require 'redis'
|
16
16
|
|
17
17
|
module CPEE
|
18
|
-
def self::redis_connect(opts)
|
18
|
+
def self::redis_connect(opts,name=nil)
|
19
19
|
if opts[:redis_cmd].nil?
|
20
20
|
begin
|
21
21
|
if opts[:redis_path]
|
22
|
-
opts[:redis_dyn] = Proc.new { Redis.new(path: opts[:redis_path], db: opts[:redis_db]) }
|
22
|
+
opts[:redis_dyn] = Proc.new { |name| Redis.new(path: opts[:redis_path], db: opts[:redis_db], id: name.gsub(/[^a-zA-Z0-9]/,'-') ) }
|
23
23
|
elsif opts[:redis_url]
|
24
|
-
opts[:redis_dyn] = Proc.new { Redis.new(url: opts[:redis_url], db: opts[:redis_db]) }
|
24
|
+
opts[:redis_dyn] = Proc.new { |name| Redis.new(url: opts[:redis_url], db: opts[:redis_db], id: name.gsub(/[^a-zA-Z0-9]/,'-') ) }
|
25
25
|
else
|
26
26
|
raise
|
27
27
|
end
|
28
|
-
opts[:redis] = opts[:redis_dyn].call
|
28
|
+
opts[:redis] = opts[:redis_dyn].call name.gsub(/[^a-zA-Z0-9]/,'-')
|
29
29
|
opts[:redis].dbsize
|
30
30
|
rescue
|
31
31
|
puts 'can not connect to redis. check if it is running and cpee is configured correctly ...'
|
32
32
|
exit
|
33
33
|
end
|
34
34
|
else # we always assume file socket if redis is startet locally
|
35
|
-
opts[:redis_dyn] = Proc.new { Redis.new(path: File.join(opts[:basepath],opts[:redis_path]), db: opts[:redis_db].to_i) }
|
35
|
+
opts[:redis_dyn] = Proc.new { |name| Redis.new(path: File.join(opts[:basepath],opts[:redis_path]), db: opts[:redis_db].to_i, id: name.gsub(/[^a-zA-Z0-9]/,'-') ) }
|
36
36
|
tried = false
|
37
37
|
begin
|
38
|
-
opts[:redis] = opts[:redis_dyn].call
|
38
|
+
opts[:redis] = opts[:redis_dyn].call name.gsub(/[^a-zA-Z0-9]/,'-')
|
39
39
|
opts[:redis].dbsize
|
40
|
-
rescue
|
40
|
+
rescue => e
|
41
|
+
puts e
|
41
42
|
res = unless tried
|
42
43
|
rcmd = opts[:redis_cmd]
|
43
44
|
rcmd.gsub! /#redis_path#/, File.join(opts[:basepath],opts[:redis_path])
|
@@ -12,6 +12,8 @@
|
|
12
12
|
# CPEE (file COPYING in the main directory). If not, see
|
13
13
|
# <http://www.gnu.org/licenses/>.
|
14
14
|
|
15
|
+
require 'charlock_holmes'
|
16
|
+
|
15
17
|
class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
16
18
|
def self::loop_guard(arguments,id,count) # {{{
|
17
19
|
controller = arguments[0]
|
@@ -101,7 +103,7 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
101
103
|
params << Riddl::Header.new("CPEE-INSTANCE",@controller.instance_id)
|
102
104
|
params << Riddl::Header.new("CPEE-INSTANCE-URL",@controller.instance_url)
|
103
105
|
params << Riddl::Header.new("CPEE-INSTANCE-UUID",@controller.uuid)
|
104
|
-
params << Riddl::Header.new("CPEE-CALLBACK"
|
106
|
+
params << Riddl::Header.new("CPEE-CALLBACK",File.join(@controller.instance_url,'callbacks',callback,'/'))
|
105
107
|
params << Riddl::Header.new("CPEE-CALLBACK-ID",callback)
|
106
108
|
params << Riddl::Header.new("CPEE-ACTIVITY",@handler_position)
|
107
109
|
params << Riddl::Header.new("CPEE-LABEL",@label||'')
|
@@ -239,6 +241,14 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
239
241
|
result
|
240
242
|
end
|
241
243
|
|
244
|
+
def detected_encoding(text)
|
245
|
+
CharlockHolmes::EncodingDetector.detect(text)[:encoding] || 'ISO-8859-1'
|
246
|
+
end
|
247
|
+
|
248
|
+
def convert_to_utf8(text)
|
249
|
+
CharlockHolmes::Converter.convert(text, detected_encoding(text), "UTF-8")
|
250
|
+
end
|
251
|
+
|
242
252
|
def structurize_result(result)
|
243
253
|
result.map do |r|
|
244
254
|
if r.is_a? Riddl::Parameter::Simple
|
@@ -33,7 +33,7 @@ def ⭐(a); ParaStruct.new(a); end
|
|
33
33
|
|
34
34
|
class Controller
|
35
35
|
def initialize(id,dir,opts)
|
36
|
-
CPEE::redis_connect(opts)
|
36
|
+
CPEE::redis_connect(opts,"Instance #{id}")
|
37
37
|
|
38
38
|
@redis = opts[:redis]
|
39
39
|
@votes = []
|
@@ -52,7 +52,7 @@ class Controller
|
|
52
52
|
@loop_guard = {}
|
53
53
|
|
54
54
|
@callback_keys = {}
|
55
|
-
@psredis = @opts[:redis_dyn].call
|
55
|
+
@psredis = @opts[:redis_dyn].call "Instance #{@id} Callback Response"
|
56
56
|
|
57
57
|
Thread.new do
|
58
58
|
@psredis.psubscribe('callback-response:*','callback-end:*') do |on|
|
@@ -96,10 +96,10 @@ class Controller
|
|
96
96
|
@opts[:host]
|
97
97
|
end
|
98
98
|
def base_url
|
99
|
-
@opts[:url]
|
99
|
+
File.join(@opts[:url],'/')
|
100
100
|
end
|
101
101
|
def instance_url
|
102
|
-
File.join(@opts[:url].to_s,@id.to_s)
|
102
|
+
File.join(@opts[:url].to_s,@id.to_s,'/')
|
103
103
|
end
|
104
104
|
def instance_id
|
105
105
|
@id
|
@@ -163,7 +163,7 @@ class Controller
|
|
163
163
|
|
164
164
|
if votes.length > 0
|
165
165
|
@votes += votes
|
166
|
-
psredis = @opts[:redis_dyn].call
|
166
|
+
psredis = @opts[:redis_dyn].call "Instance #{@id} Vote"
|
167
167
|
collect = []
|
168
168
|
psredis.subscribe(votes.map{|e| ['vote-response:' + e.to_s] }.flatten) do |on|
|
169
169
|
on.message do |what, message|
|
data/server/routing/end.rb
CHANGED
@@ -30,8 +30,8 @@ Daemonite.new do |opts|
|
|
30
30
|
opts[:redis_path] ||= '/tmp/redis.sock'
|
31
31
|
opts[:redis_db] ||= 1
|
32
32
|
|
33
|
-
CPEE::redis_connect opts
|
34
|
-
opts[:pubsubredis] = opts[:redis_dyn].call
|
33
|
+
CPEE::redis_connect opts, 'Server Routing End'
|
34
|
+
opts[:pubsubredis] = opts[:redis_dyn].call 'Server Routing End Sub'
|
35
35
|
end
|
36
36
|
|
37
37
|
run do
|
@@ -30,8 +30,8 @@ Daemonite.new do |opts|
|
|
30
30
|
opts[:redis_path] ||= '/tmp/redis.sock'
|
31
31
|
opts[:redis_db] ||= 1
|
32
32
|
|
33
|
-
CPEE::redis_connect opts
|
34
|
-
opts[:pubsubredis] = opts[:redis_dyn].call
|
33
|
+
CPEE::redis_connect opts, 'Server Routing Forward Events'
|
34
|
+
opts[:pubsubredis] = opts[:redis_dyn].call 'Server Routing Forward Events Sub'
|
35
35
|
end
|
36
36
|
|
37
37
|
run do
|
@@ -56,8 +56,8 @@ Daemonite.new do |opts|
|
|
56
56
|
opts[:redis_path] ||= '/tmp/redis.sock'
|
57
57
|
opts[:redis_db] ||= 1
|
58
58
|
|
59
|
-
CPEE::redis_connect opts
|
60
|
-
opts[:pubsubredis] = opts[:redis_dyn].call
|
59
|
+
CPEE::redis_connect opts, 'Server Routing Forward Votes'
|
60
|
+
opts[:pubsubredis] = opts[:redis_dyn].call 'Server Routing Forward Votes Sub'
|
61
61
|
end
|
62
62
|
|
63
63
|
run do
|
@@ -84,11 +84,11 @@ Daemonite.new do |opts|
|
|
84
84
|
opts[:redis].publish("forward:#{instance}/#{subscription_key}",mess)
|
85
85
|
else
|
86
86
|
client = Riddl::Client.new(url)
|
87
|
-
callback = m['instance-url']
|
87
|
+
callback = File.join(m['instance-url'],'/callbacks/',subscription_key,'/')
|
88
88
|
status, result, headers = (client.post [
|
89
|
-
Riddl::Header.new("CPEE-BASE",m['cpee']),
|
89
|
+
Riddl::Header.new("CPEE-BASE",File.join(m['cpee'],'/')),
|
90
90
|
Riddl::Header.new("CPEE-INSTANCE",m['instance']),
|
91
|
-
Riddl::Header.new("CPEE-INSTANCE-URL",m['instance-url']),
|
91
|
+
Riddl::Header.new("CPEE-INSTANCE-URL",File.join(m['instance-url'],'/')),
|
92
92
|
Riddl::Header.new("CPEE-INSTANCE-UUID",m['instance-uuid']),
|
93
93
|
Riddl::Header.new("CPEE-CALLBACK",callback),
|
94
94
|
Riddl::Header.new("CPEE-CALLBACK-ID",subscription_key),
|
data/server/routing/persist.rb
CHANGED
@@ -45,8 +45,8 @@ Daemonite.new do |opts|
|
|
45
45
|
opts[:redis_path] ||= '/tmp/redis.sock'
|
46
46
|
opts[:redis_db] ||= 1
|
47
47
|
|
48
|
-
CPEE::redis_connect opts
|
49
|
-
opts[:pubsubredis] = opts[:redis_dyn].call
|
48
|
+
CPEE::redis_connect opts, 'Server Routing Persist'
|
49
|
+
opts[:pubsubredis] = opts[:redis_dyn].call 'Server Routing Persist Sub'
|
50
50
|
end
|
51
51
|
|
52
52
|
run do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cpee
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Juergen eTM Mangler
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: tools
|
12
12
|
cert_chain: []
|
13
|
-
date: 2021-
|
13
|
+
date: 2021-08-02 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: riddl
|
@@ -102,6 +102,20 @@ dependencies:
|
|
102
102
|
- - "~>"
|
103
103
|
- !ruby/object:Gem::Version
|
104
104
|
version: '2'
|
105
|
+
- !ruby/object:Gem::Dependency
|
106
|
+
name: charlock_holmes
|
107
|
+
requirement: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - "~>"
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
type: :runtime
|
113
|
+
prerelease: false
|
114
|
+
version_requirements: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - "~>"
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
105
119
|
description: see http://cpee.org
|
106
120
|
email: juergen.mangler@gmail.com
|
107
121
|
executables:
|
@@ -632,18 +646,13 @@ files:
|
|
632
646
|
- server/resources/states.xml
|
633
647
|
- server/resources/topics.xml
|
634
648
|
- server/resources/transformation.xml
|
635
|
-
- server/routing/end.pid
|
636
649
|
- server/routing/end.rb
|
637
|
-
- server/routing/forward-events.pid
|
638
650
|
- server/routing/forward-events.rb
|
639
|
-
- server/routing/forward-votes.pid
|
640
651
|
- server/routing/forward-votes.rb
|
641
|
-
- server/routing/persist.pid
|
642
652
|
- server/routing/persist.rb
|
643
653
|
- server/server.conf
|
644
654
|
- server/server.rb
|
645
655
|
- tools/cpee
|
646
|
-
- tools/cpee.sic
|
647
656
|
- tools/server/cpee
|
648
657
|
- tools/server/resources/notifications/logging/subscription.xml
|
649
658
|
- tools/server/resources/properties.init
|
data/server/routing/end.pid
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
42643
|
@@ -1 +0,0 @@
|
|
1
|
-
42631
|
@@ -1 +0,0 @@
|
|
1
|
-
42635
|
data/server/routing/persist.pid
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
42639
|
data/tools/cpee.sic
DELETED
@@ -1,306 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
curpath = __dir__
|
3
|
-
require 'rubygems'
|
4
|
-
require 'optparse'
|
5
|
-
require 'fileutils'
|
6
|
-
require 'webrick'
|
7
|
-
require 'typhoeus'
|
8
|
-
require 'xml/smart'
|
9
|
-
require 'zip'
|
10
|
-
require 'pp'
|
11
|
-
|
12
|
-
def wrap(s, width=78, indent=18)
|
13
|
-
lines = []
|
14
|
-
line, s = s[0..indent-2], s[indent..-1]
|
15
|
-
s.split(/\n/).each do |ss|
|
16
|
-
ss.split(/[ \t]+/).each do |word|
|
17
|
-
if line.size + word.size >= width
|
18
|
-
lines << line
|
19
|
-
line = (" " * (indent)) + word
|
20
|
-
else
|
21
|
-
line << " " << word
|
22
|
-
end
|
23
|
-
end
|
24
|
-
lines << line if line
|
25
|
-
line = (" " * (indent-1))
|
26
|
-
end
|
27
|
-
return lines.join "\n"
|
28
|
-
end
|
29
|
-
|
30
|
-
ARGV.options { |opt|
|
31
|
-
opt.summary_indent = ' ' * 2
|
32
|
-
opt.summary_width = 15
|
33
|
-
opt.banner = "Usage:\n#{opt.summary_indent}#{File.basename($0)} [options] convert | ui | cpui DIR | new DIR | archive DIR URL | start URL | delete! URL | abandon URL\n"
|
34
|
-
opt.on("Options:")
|
35
|
-
opt.on("--help", "-h", "This text") { puts opt; exit }
|
36
|
-
opt.on("")
|
37
|
-
opt.on(wrap("[archive DIR URL] save properties from all finished instances listed at URL into DIR. Examples:\ncpee archive ./archive http://localhost:9298/1/\ncpee archive ./archive http://localhost:9298/1-200\ncpee archive ./archive http://localhost:9298/*"))
|
38
|
-
opt.on("")
|
39
|
-
opt.on(wrap("[abandon URL] running processes are stopped; ready or stopped processes are abandoned. Examples:\ncpee abandon http://localhost:9298/1/\ncpee abandon http://localhost:9298/1-200\ncpee abandon http://localhost:9298/*"))
|
40
|
-
opt.on("")
|
41
|
-
opt.on(wrap("[start URL] stopped processes are started; all others are not touched. Examples:\ncpee start http://localhost:9298/1\ncpee start http://localhost:9298/1-200\ncpee start http://localhost:9298/*"))
|
42
|
-
opt.on("")
|
43
|
-
opt.on(wrap("[delete! URL] DANGER ZONE. Vanishes forever. Not in archive. Examples:\ncpee delete! http://localhost:9298/1/"))
|
44
|
-
opt.on("")
|
45
|
-
opt.on(wrap("[new DIR] scaffolds a sample execution engine. Everything except instances can be removed for default behaviour."))
|
46
|
-
opt.on("")
|
47
|
-
opt.on(wrap("[cpui DIR] scaffolds a sample html client. New versions might require manual merging if you changed something."))
|
48
|
-
opt.on("")
|
49
|
-
opt.on(wrap("[ui] starts a simple static web server with the ui on http://localhost:8080. Use [cpui DIR] if you want stuff in apache or nginx."))
|
50
|
-
opt.on("")
|
51
|
-
opt.on(wrap("[convert] converts all testsets in the current directory to cpee2"))
|
52
|
-
opt.parse!
|
53
|
-
}
|
54
|
-
if (ARGV.length == 0) ||
|
55
|
-
(ARGV.length == 1 && !(%w(ui convert).include?(ARGV[0]))) ||
|
56
|
-
(ARGV.length == 2 && !(%w(abandon start delete! cpui new).include?(ARGV[0]))) ||
|
57
|
-
(ARGV.length == 3 && ARGV[0] != 'archive') ||
|
58
|
-
(ARGV.length > 3)
|
59
|
-
puts ARGV.options
|
60
|
-
exit
|
61
|
-
end
|
62
|
-
command = ARGV[0]
|
63
|
-
p1 = ARGV[1]
|
64
|
-
p2 = ARGV[2]
|
65
|
-
cockpit = "#{curpath}/../cockpit/"
|
66
|
-
|
67
|
-
def js_libs(cockpit)
|
68
|
-
res = Typhoeus.get('https://cpee.org/js_libs/js_libs.zip')
|
69
|
-
if res.success?
|
70
|
-
File.write(File.join(cockpit,'js_libs.zip'),res.response_body)
|
71
|
-
Zip::File.open(File.join(cockpit,'js_libs.zip')) do |zip_file|
|
72
|
-
zip_file.each do |entry|
|
73
|
-
case entry.ftype
|
74
|
-
when :directory
|
75
|
-
Dir.mkdir(File.join(cockpit,entry.name)) rescue nil
|
76
|
-
when :file
|
77
|
-
File.write(File.join(cockpit,entry.name),entry.get_input_stream.read)
|
78
|
-
when :symlink
|
79
|
-
FileUtils.ln_s(File.join('.',entry.get_input_stream.read),File.join(cockpit,entry.name), force: true)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
true
|
84
|
-
else
|
85
|
-
puts 'Internet access required to download javascript libs from "http://cpee.org/js_libs/js_libs.zip".'
|
86
|
-
false
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
if command == 'ui'
|
91
|
-
if js_libs(cockpit)
|
92
|
-
s = WEBrick::HTTPServer.new(:Port => 8080, :DocumentRoot => cockpit)
|
93
|
-
trap("INT"){ s.shutdown }
|
94
|
-
s.start
|
95
|
-
end
|
96
|
-
elsif command == 'cpui'
|
97
|
-
if !File.exists?(p1)
|
98
|
-
FileUtils.cp_r(cockpit,p1)
|
99
|
-
else
|
100
|
-
FileUtils.cp_r(Dir.glob(File.join(cockpit,'*')),p1,remove_destination: true)
|
101
|
-
puts "Directory already exists, updating ..."
|
102
|
-
end
|
103
|
-
js_libs(p1)
|
104
|
-
elsif command == 'convert'
|
105
|
-
Dir['*.xml'].each do |f|
|
106
|
-
XML::Smart.modify(f) do |doc|
|
107
|
-
doc.register_namespace 'd', 'http://cpee.org/ns/description/1.0'
|
108
|
-
doc.register_namespace 'p', 'http://riddl.org/ns/common-patterns/properties/1.0'
|
109
|
-
doc.register_namespace 'x', 'http://cpee.org/ns/properties/2.0'
|
110
|
-
if doc.root.qname.name == 'testset'
|
111
|
-
doc.root.namespaces[nil] = 'http://cpee.org/ns/properties/2.0'
|
112
|
-
doc.root.namespace = nil
|
113
|
-
|
114
|
-
doc.find('//x:handlerwrapper').each do |e|
|
115
|
-
if e.text == 'DefaultHandlerWrapper'
|
116
|
-
doc.root.prepend('x:executionhandler','ruby')
|
117
|
-
end
|
118
|
-
end rescue nil
|
119
|
-
doc.find('//x:handlerwrapper').delete_all!
|
120
|
-
doc.find('//x:start_url').each do |e|
|
121
|
-
e.text = 'https://cpee.org/flow/start/url/'
|
122
|
-
end rescue nil
|
123
|
-
doc.find('//x:start_git').each do |e|
|
124
|
-
e.text = 'https://cpee.org/flow/start/git/'
|
125
|
-
end rescue nil
|
126
|
-
doc.find('//d:finalize | //d:update | //d:prepare | //d:rescue').each do |e|
|
127
|
-
if e.parent.qname.name != 'code'
|
128
|
-
n = e.parent
|
129
|
-
if (x = n.find('d:code')).any?
|
130
|
-
x.first.add(e)
|
131
|
-
else
|
132
|
-
n.add('d:code').add(e)
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end rescue nil
|
136
|
-
|
137
|
-
doc.find('//p:*').each do |e|
|
138
|
-
e.namespaces.delete_all!
|
139
|
-
end rescue nil
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
elsif command == 'archive'
|
144
|
-
p2 = File.join(p2,'*') if p2 =~ /([a-zA-Z]|\/)$/
|
145
|
-
base = File.dirname(p2)
|
146
|
-
names = []
|
147
|
-
if File.basename(p2) =~ /(\d+)-(\d+)/
|
148
|
-
names = ($1.to_i..$2.to_i).to_a
|
149
|
-
elsif File.basename(p2) == '*'
|
150
|
-
res = Typhoeus.get(File.join(base,'/'))
|
151
|
-
if res.success?
|
152
|
-
XML::Smart.string(res.response_body) do |doc|
|
153
|
-
doc.find('//instance/@id').each do |ele|
|
154
|
-
names << ele.value
|
155
|
-
end
|
156
|
-
end
|
157
|
-
names.reverse!
|
158
|
-
else
|
159
|
-
exit
|
160
|
-
end
|
161
|
-
else
|
162
|
-
names << File.basename(p2)
|
163
|
-
end
|
164
|
-
names.each do |name|
|
165
|
-
print "Working on: " + name.to_s + "\r"
|
166
|
-
res = Typhoeus.get(File.join(base,name.to_s,'/'))
|
167
|
-
if res.success?
|
168
|
-
if res.headers['Content-Type'] =~ /^(text|application)\/xml/
|
169
|
-
XML::Smart.string(res.response_body) do |doc|
|
170
|
-
if doc.root.qname.to_s == "instances"
|
171
|
-
doc.root.children.each do |i|
|
172
|
-
if ["finished","abandoned"].include?(i.attributes['state']) || (["ready"].include?(i.attributes['state']) && Time.parse(i.attributes['changed']).to_i < Time.now-(60*60*24))
|
173
|
-
prop = Typhoeus.get(File.join(base,name.to_s,i.attributes['id'],'properties','/'))
|
174
|
-
if prop.success?
|
175
|
-
File.write(File.join(p1,i.attributes['uuid'] + '.xml'),prop.response_body) if prop.headers['Content-Type'] =~ /^(text|application)\/xml/
|
176
|
-
Typhoeus.delete(File.join(base,name.to_s,i.attributes['id'],'/'))
|
177
|
-
end
|
178
|
-
end
|
179
|
-
end
|
180
|
-
elsif doc.root.qname.to_s == "info"
|
181
|
-
prop = Typhoeus.get(File.join(base,name.to_s,'properties','/'))
|
182
|
-
if prop.success?
|
183
|
-
xprop = XML::Smart::string(prop.response_body)
|
184
|
-
xprop.register_namespace 'p', 'http://cpee.org/ns/properties/2.0'
|
185
|
-
if ["finished","abandoned"].include?(xprop.find("string(/p:properties/p:state)")) || (["ready"].include?(xprop.find("string(/p:properties/p:state)")) && Time.parse(xprop.find("string(/p:properties/p:state/@changed)")) < Time.now-(60*60*12))
|
186
|
-
uuid = xprop.find("string(/p:properties/p:attributes/p:uuid)")
|
187
|
-
id = name.to_s
|
188
|
-
File.write(File.join(p1,uuid + '.xml'),prop.response_body) if prop.headers['Content-Type'] =~ /^(text|application)\/xml/
|
189
|
-
Typhoeus.delete(File.join(base,name.to_s,'/'))
|
190
|
-
end
|
191
|
-
end
|
192
|
-
end
|
193
|
-
end
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
197
|
-
puts
|
198
|
-
elsif command == 'abandon'
|
199
|
-
p1 = File.join(p1,'*') if p1 =~ /([a-zA-Z]|\/)$/
|
200
|
-
base = File.dirname(p1)
|
201
|
-
names = []
|
202
|
-
if File.basename(p1) =~ /(\d+)-(\d+)/
|
203
|
-
names = ($1.to_i..$2.to_i).to_a
|
204
|
-
elsif File.basename(p1) == '*'
|
205
|
-
res = Typhoeus.get(File.join(base,'/'))
|
206
|
-
if res.success?
|
207
|
-
XML::Smart.string(res.response_body) do |doc|
|
208
|
-
doc.find('//instance/@id').each do |ele|
|
209
|
-
names << ele.value
|
210
|
-
end
|
211
|
-
end
|
212
|
-
names.reverse!
|
213
|
-
else
|
214
|
-
exit
|
215
|
-
end
|
216
|
-
else
|
217
|
-
names << File.basename(p1)
|
218
|
-
end
|
219
|
-
names.each do |name|
|
220
|
-
print "Working on: " + name.to_s + "\r"
|
221
|
-
res1 = Typhoeus.get(File.join(base,name.to_s,'properties','state','/'))
|
222
|
-
if res1.success?
|
223
|
-
if res1.response_body == 'ready' || res1.response_body == 'stopped'
|
224
|
-
Typhoeus.put(File.join(base,name.to_s,'properties','state','/'), headers: {'Content-Type' => 'application/x-www-form-urlencoded'}, body: "value=abandoned")
|
225
|
-
end
|
226
|
-
end
|
227
|
-
end
|
228
|
-
puts
|
229
|
-
elsif command == 'start'
|
230
|
-
p1 = File.join(p1,'*') if p1 =~ /([a-zA-Z]|\/)$/
|
231
|
-
base = File.dirname(p1)
|
232
|
-
names = []
|
233
|
-
if File.basename(p1) =~ /(\d+)-(\d+)/
|
234
|
-
names = ($1.to_i..$2.to_i).to_a
|
235
|
-
elsif File.basename(p1) == '*'
|
236
|
-
res = Typhoeus.get(File.join(base,'/'))
|
237
|
-
if res.success?
|
238
|
-
XML::Smart.string(res.response_body) do |doc|
|
239
|
-
doc.find('//instance/@id').each do |ele|
|
240
|
-
names << ele.value
|
241
|
-
end
|
242
|
-
end
|
243
|
-
names.reverse!
|
244
|
-
else
|
245
|
-
exit
|
246
|
-
end
|
247
|
-
else
|
248
|
-
names << File.basename(p1)
|
249
|
-
end
|
250
|
-
names.each do |name|
|
251
|
-
res = Typhoeus.get(File.join(base,name.to_s,'properties','state','/'))
|
252
|
-
if res.success?
|
253
|
-
case res.response_body
|
254
|
-
when "stopped" then
|
255
|
-
keep_alive = Typhoeus.get(File.join(base,name.to_s,'properties','attributes','keep_alive','/'))
|
256
|
-
if keep_alive.success?
|
257
|
-
Typhoeus.put(File.join(base,name.to_s,'properties','state','/'), headers: {'Content-Type' => 'application/x-www-form-urlencoded'}, body: "value=running")
|
258
|
-
end
|
259
|
-
end
|
260
|
-
end
|
261
|
-
end
|
262
|
-
elsif command == 'delete!'
|
263
|
-
p1 = File.join(p1,'*') if p1 =~ /([a-zA-Z]|\/)$/
|
264
|
-
base = File.dirname(p1)
|
265
|
-
names = []
|
266
|
-
if File.basename(p1) =~ /(\d+)-(\d+)/
|
267
|
-
names = ($1.to_i..$2.to_i).to_a
|
268
|
-
elsif File.basename(p1) == '*'
|
269
|
-
res = Typhoeus.get(File.join(base,'/'))
|
270
|
-
if res.success?
|
271
|
-
XML::Smart.string(res.response_body) do |doc|
|
272
|
-
doc.find('//instance/@id').each do |ele|
|
273
|
-
names << ele.value
|
274
|
-
end
|
275
|
-
end
|
276
|
-
names.reverse!
|
277
|
-
else
|
278
|
-
exit
|
279
|
-
end
|
280
|
-
else
|
281
|
-
names << File.basename(p1)
|
282
|
-
end
|
283
|
-
names.each do |name|
|
284
|
-
print "Working on: " + name.to_s + "\r"
|
285
|
-
Typhoeus.delete(File.join(base,name.to_s,'/'))
|
286
|
-
end
|
287
|
-
puts
|
288
|
-
elsif command == 'new'
|
289
|
-
if !File.exists?(p1)
|
290
|
-
FileUtils.cp_r("#{curpath}/server/",p1)
|
291
|
-
FileUtils.mkdir("#{p1}/archive") rescue nil
|
292
|
-
FileUtils.mkdir("#{p1}/instances") rescue nil
|
293
|
-
FileUtils.mkdir("#{p1}/resources") rescue nil
|
294
|
-
FileUtils.mkdir("#{p1}/executionhandler") rescue nil
|
295
|
-
Dir["#{curpath}/../systemd/*.service"].each do |f|
|
296
|
-
nam = File.basename f
|
297
|
-
cont = File.read(f)
|
298
|
-
cont.gsub!(/{CPEEUSER}/,`whoami`.strip)
|
299
|
-
cont.gsub!(/{CPEEWORKINGDIR}/,"#{File.realpath(p1)}")
|
300
|
-
cont.gsub!(/{CPEESERVER}/,"#{File.realpath(p1)}/server")
|
301
|
-
File.write("#{p1}/#{nam}",cont)
|
302
|
-
end
|
303
|
-
else
|
304
|
-
puts 'Directory already exists.'
|
305
|
-
end
|
306
|
-
end
|