cpee 2.1.11 → 2.1.15
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/instance.js +2 -2
- 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 +18 -6
- 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: bdba71d5df8124590a3b932d83af91b87801663f3e21d8ebbafb9d4e2b339869
|
|
4
|
+
data.tar.gz: 73e7507c88a39096b2d418178a03150165a0966cd94ce4d452565a21c0e31683
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '093136bfeee58f4ba9152b15c5a83220aa219734160a50b60739f30337e08e2b99d2b503addcec8cd72c832bf67430b4e177110007f5693a593c8a513d620fec'
|
|
7
|
+
data.tar.gz: d50286266ac5d15a94f4c0f86cdd2d87b8730948e0f1a6bdfe0d0ca73af8104fdcf720620abf06b8819aaea005d6cf264954c0b063841f4dba22c29c977e2bd2
|
data/cockpit/js/instance.js
CHANGED
|
@@ -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';// }}}
|
|
@@ -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.15"
|
|
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,9 @@
|
|
|
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
|
+
require 'base64'
|
|
17
|
+
|
|
15
18
|
class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
16
19
|
def self::loop_guard(arguments,id,count) # {{{
|
|
17
20
|
controller = arguments[0]
|
|
@@ -101,7 +104,7 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
101
104
|
params << Riddl::Header.new("CPEE-INSTANCE",@controller.instance_id)
|
|
102
105
|
params << Riddl::Header.new("CPEE-INSTANCE-URL",@controller.instance_url)
|
|
103
106
|
params << Riddl::Header.new("CPEE-INSTANCE-UUID",@controller.uuid)
|
|
104
|
-
params << Riddl::Header.new("CPEE-CALLBACK"
|
|
107
|
+
params << Riddl::Header.new("CPEE-CALLBACK",File.join(@controller.instance_url,'callbacks',callback,'/'))
|
|
105
108
|
params << Riddl::Header.new("CPEE-CALLBACK-ID",callback)
|
|
106
109
|
params << Riddl::Header.new("CPEE-ACTIVITY",@handler_position)
|
|
107
110
|
params << Riddl::Header.new("CPEE-LABEL",@label||'')
|
|
@@ -195,11 +198,12 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
195
198
|
unless status.nil?
|
|
196
199
|
@controller.notify("status/change", :'activity-uuid' => @handler_activity_uuid, :endpoint => @handler_endpoint, :label => @label, :activity => @handler_position, :id => status.id, :message => status.message)
|
|
197
200
|
end
|
|
198
|
-
unless changed_dataelements.nil?
|
|
199
|
-
|
|
201
|
+
unless changed_dataelements.nil? || changed_dataelements.empty?
|
|
202
|
+
de = dataelements.slice(*changed_dataelements).transform_values { |v| detect_encoding(v) == 'UTF-8' ? v : convert_to_base64(v) }
|
|
203
|
+
@controller.notify("dataelements/change", :'activity-uuid' => @handler_activity_uuid, :endpoint => @handler_endpoint, :label => @label, :activity => @handler_position, :changed => changed_dataelements, :values => de)
|
|
200
204
|
end
|
|
201
|
-
unless changed_endpoints.nil?
|
|
202
|
-
@controller.notify("endpoints/change", :'activity-uuid' => @handler_activity_uuid, :endpoint => @handler_endpoint, :label => @label, :activity => @handler_position, :changed => changed_endpoints, :values => endpoints)
|
|
205
|
+
unless changed_endpoints.nil? || changed_endpoints.empty?
|
|
206
|
+
@controller.notify("endpoints/change", :'activity-uuid' => @handler_activity_uuid, :endpoint => @handler_endpoint, :label => @label, :activity => @handler_position, :changed => changed_endpoints, :values => endpoints.slice(*changed_endpoints))
|
|
203
207
|
end
|
|
204
208
|
end # }}}
|
|
205
209
|
|
|
@@ -239,6 +243,14 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
239
243
|
result
|
|
240
244
|
end
|
|
241
245
|
|
|
246
|
+
def detect_encoding(text)
|
|
247
|
+
CharlockHolmes::EncodingDetector.detect(text)[:encoding] || 'ISO-8859-1'
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def convert_to_base64(text)
|
|
251
|
+
'data:application/octet-stream;base64,' + Base64::urlsafe_encode64(text)
|
|
252
|
+
end
|
|
253
|
+
|
|
242
254
|
def structurize_result(result)
|
|
243
255
|
result.map do |r|
|
|
244
256
|
if r.is_a? Riddl::Parameter::Simple
|
|
@@ -257,7 +269,7 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
257
269
|
tmp = {
|
|
258
270
|
'name' => r.name == '' ? 'result' : r.name,
|
|
259
271
|
'mimetype' => r.mimetype,
|
|
260
|
-
'data' => res
|
|
272
|
+
'data' => (detect_encoding(res) == 'UTF-8' ? res : convert_to_base64(res))
|
|
261
273
|
}
|
|
262
274
|
r.value.rewind
|
|
263
275
|
tmp
|
|
@@ -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.15
|
|
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
|