cpee-worklist 1.0.0
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 +7 -0
- data/AUTHORS +3 -0
- data/LICENSE +165 -0
- data/README.md +21 -0
- data/Rakefile +21 -0
- data/cpee-worklist.gemspec +27 -0
- data/lib/cpee-worklist/activities.rb +36 -0
- data/lib/cpee-worklist/controller.rb +160 -0
- data/lib/cpee-worklist/implementation.rb +432 -0
- data/lib/cpee-worklist/implementation.xml +35 -0
- data/lib/cpee-worklist/organisation.rng +82 -0
- data/lib/cpee-worklist/routing/end.rb +59 -0
- data/lib/cpee-worklist/routing/forward-events.rb +78 -0
- data/lib/cpee-worklist/routing/forward-votes.rb +125 -0
- data/lib/cpee-worklist/routing/persist.rb +75 -0
- data/lib/cpee-worklist/topics.xml +32 -0
- data/lib/cpee-worklist/user.rb +61 -0
- data/lib/cpee-worklist/utils.rb +52 -0
- data/lib/cpee-worklist/wlengine.xml +176 -0
- data/server/worklist +37 -0
- data/server/worklist.conf +2 -0
- data/tools/cpee-worklist +49 -0
- metadata +135 -0
@@ -0,0 +1,78 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# This file is part of CPEE-WORKLIST
|
4
|
+
#
|
5
|
+
# CPEE-WORKLIST is free software: you can redistribute it and/or modify it
|
6
|
+
# under the terms of the GNU Lesser General Public License as published by the
|
7
|
+
# Free Software Foundation, either version 3 of the License, or (at your
|
8
|
+
# option) any later version.
|
9
|
+
#
|
10
|
+
# CPEE-WORKLIST is distributed in the hope that it will be useful, but WITHOUT
|
11
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
12
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
13
|
+
# details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Lesser General Public License
|
16
|
+
# along with CPEE-WORKLIST (file LICENSE in the main directory). If not, see
|
17
|
+
# <http://www.gnu.org/licenses/>.
|
18
|
+
|
19
|
+
require 'redis'
|
20
|
+
require 'daemonite'
|
21
|
+
require 'riddl/client'
|
22
|
+
require 'cpee/redis'
|
23
|
+
|
24
|
+
Daemonite.new do |opts|
|
25
|
+
opts[:runtime_opts] += [
|
26
|
+
["--url=URL", "-uURL", "Specify redis url", ->(p){ opts[:redis_url] = p }],
|
27
|
+
["--path=PATH", "-pPATH", "Specify redis path, e.g. /tmp/redis.sock", ->(p){ opts[:redis_path] = p }],
|
28
|
+
["--db=DB", "-dDB", "Specify redis db, e.g. 1", ->(p) { opts[:redis_db] = p.to_i }]
|
29
|
+
]
|
30
|
+
|
31
|
+
on startup do
|
32
|
+
opts[:redis_path] ||= '/tmp/redis.sock'
|
33
|
+
opts[:redis_db] ||= 1
|
34
|
+
|
35
|
+
CPEE::redis_connect opts, 'Server Routing Forward Events'
|
36
|
+
opts[:pubsubredis] = opts[:redis_dyn].call 'Server Routing Forward Events Sub'
|
37
|
+
end
|
38
|
+
|
39
|
+
run do
|
40
|
+
opts[:pubsubredis].psubscribe('event:*') do |on|
|
41
|
+
on.pmessage do |pat, what, message|
|
42
|
+
index = message.index(' ')
|
43
|
+
mess = message[index+1..-1]
|
44
|
+
instance = message[0...index]
|
45
|
+
type, worker, event = what.split(':',3)
|
46
|
+
topic = ::File::dirname(event)
|
47
|
+
name = ::File::basename(event)
|
48
|
+
long = File.join(topic,type,name)
|
49
|
+
opts[:redis].smembers("worklist:#{instance}/handlers").each do |key|
|
50
|
+
if opts[:redis].smembers("worklist:#{instance}/handlers/#{key}").include? long
|
51
|
+
url = opts[:redis].get("worklist:#{instance}/handlers/#{key}/url")
|
52
|
+
if url.nil? || url == ""
|
53
|
+
opts[:redis].publish("forward:#{instance}/#{key}",mess)
|
54
|
+
else
|
55
|
+
client = Riddl::Client.new(url)
|
56
|
+
client.post [
|
57
|
+
Riddl::Parameter::Simple::new('type',type),
|
58
|
+
Riddl::Parameter::Simple::new('topic',topic),
|
59
|
+
Riddl::Parameter::Simple::new('event',name),
|
60
|
+
Riddl::Parameter::Complex::new('notification','application/json',mess)
|
61
|
+
]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
unless opts[:redis].exists?("worklist:#{instance}/state")
|
66
|
+
empt = opts[:redis].keys("worklist:#{instance}/*").to_a
|
67
|
+
opts[:redis].multi do |multi|
|
68
|
+
multi.del empt
|
69
|
+
end
|
70
|
+
end
|
71
|
+
rescue => e
|
72
|
+
puts e.message
|
73
|
+
puts e.backtrace
|
74
|
+
p '-----------------'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end.go!
|
@@ -0,0 +1,125 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# This file is part of CPEE-WORKLIST
|
4
|
+
#
|
5
|
+
# CPEE-WORKLIST is free software: you can redistribute it and/or modify it
|
6
|
+
# under the terms of the GNU Lesser General Public License as published by the
|
7
|
+
# Free Software Foundation, either version 3 of the License, or (at your
|
8
|
+
# option) any later version.
|
9
|
+
#
|
10
|
+
# CPEE-WORKLIST is distributed in the hope that it will be useful, but WITHOUT
|
11
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
12
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
13
|
+
# details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Lesser General Public License
|
16
|
+
# along with CPEE-WORKLIST (file LICENSE in the main directory). If not, see
|
17
|
+
# <http://www.gnu.org/licenses/>.
|
18
|
+
|
19
|
+
require 'redis'
|
20
|
+
require 'daemonite'
|
21
|
+
require 'riddl/client'
|
22
|
+
require 'json'
|
23
|
+
require 'cpee/message'
|
24
|
+
require 'cpee/redis'
|
25
|
+
|
26
|
+
def persist_handler(instance,key,mess,redis) #{{{
|
27
|
+
redis.multi do |multi|
|
28
|
+
multi.sadd("worklist:#{instance}/callbacks",key)
|
29
|
+
multi.set("worklist:#{instance}/callback/#{key}/subscription",mess.dig('content','subscription'))
|
30
|
+
multi.set("worklist:#{instance}/callback/#{key}/uuid",mess.dig('content','activity-uuid'))
|
31
|
+
multi.set("worklist:#{instance}/callback/#{key}/label",mess.dig('content','label'))
|
32
|
+
multi.set("worklist:#{instance}/callback/#{key}/position",mess.dig('content','activity'))
|
33
|
+
multi.set("worklist:#{instance}/callback/#{key}/type",'vote')
|
34
|
+
end
|
35
|
+
end #}}}
|
36
|
+
|
37
|
+
def send_response(instance,key,url,value,redis) #{{{
|
38
|
+
CPEE::Message::send(
|
39
|
+
:'vote-response',
|
40
|
+
key,
|
41
|
+
url,
|
42
|
+
instance,
|
43
|
+
{},
|
44
|
+
{},
|
45
|
+
value,
|
46
|
+
redis
|
47
|
+
)
|
48
|
+
end #}}}
|
49
|
+
|
50
|
+
Daemonite.new do |opts|
|
51
|
+
opts[:runtime_opts] += [
|
52
|
+
["--url=URL", "-uURL", "Specify redis url", ->(p){ opts[:redis_url] = p }],
|
53
|
+
["--path=PATH", "-pPATH", "Specify redis path, e.g. /tmp/redis.sock", ->(p){ opts[:redis_path] = p }],
|
54
|
+
["--db=DB", "-dDB", "Specify redis db, e.g. 1", ->(p) { opts[:redis_db] = p.to_i }]
|
55
|
+
]
|
56
|
+
|
57
|
+
on startup do
|
58
|
+
opts[:redis_path] ||= '/tmp/redis.sock'
|
59
|
+
opts[:redis_db] ||= 1
|
60
|
+
|
61
|
+
CPEE::redis_connect opts, 'Server Routing Forward Votes'
|
62
|
+
opts[:pubsubredis] = opts[:redis_dyn].call 'Server Routing Forward Votes Sub'
|
63
|
+
end
|
64
|
+
|
65
|
+
run do
|
66
|
+
opts[:pubsubredis].psubscribe('vote:00:*') do |on|
|
67
|
+
on.pmessage do |pat, what, message|
|
68
|
+
index = message.index(' ')
|
69
|
+
mess = message[index+1..-1]
|
70
|
+
instance = message[0...index]
|
71
|
+
type, worker, event = what.split(':',3)
|
72
|
+
topic = ::File::dirname(event)
|
73
|
+
name = ::File::basename(event)
|
74
|
+
long = File.join(topic,type,name)
|
75
|
+
|
76
|
+
opts[:redis].smembers("worklist:#{instance}/handlers").each do |subscription_key|
|
77
|
+
if opts[:redis].smembers("worklist:#{instance}/handlers/#{subscription_key}").include? long
|
78
|
+
m = JSON.parse(mess)
|
79
|
+
callback_key = m.dig('content','key')
|
80
|
+
url = opts[:redis].get("worklist:#{instance}/handlers/#{subscription_key}/url")
|
81
|
+
|
82
|
+
if url.nil? || url == ""
|
83
|
+
persist_handler instance, callback_key, m, opts[:redis]
|
84
|
+
opts[:redis].publish("forward:#{instance}/#{subscription_key}",mess)
|
85
|
+
else
|
86
|
+
client = Riddl::Client.new(url)
|
87
|
+
callback = File.join(m['instance-url'],'/callbacks/',subscription_key,'/')
|
88
|
+
status, result, headers = (client.post [
|
89
|
+
Riddl::Header.new("CPEE-WL-BASE",File.join(m['cpee'],'/')),
|
90
|
+
Riddl::Header.new("CPEE-WL-DOMAIN",m['instance']),
|
91
|
+
Riddl::Header.new("CPEE-WL-DOMAIN-URL",File.join(m['instance-url'],'/')),
|
92
|
+
Riddl::Header.new("CPEE-WL-DOMAIN-UUID",m['instance-uuid']),
|
93
|
+
Riddl::Header.new("CPEE-WL-CALLBACK",callback),
|
94
|
+
Riddl::Header.new("CPEE-WL-CALLBACK-ID",subscription_key),
|
95
|
+
Riddl::Parameter::Simple::new('type',type),
|
96
|
+
Riddl::Parameter::Simple::new('topic',topic),
|
97
|
+
Riddl::Parameter::Simple::new('vote',name),
|
98
|
+
Riddl::Parameter::Simple::new('callback',callback),
|
99
|
+
Riddl::Parameter::Complex::new('notification','application/json',mess)
|
100
|
+
] rescue [ 0, [], []])
|
101
|
+
if status >= 200 && status < 300
|
102
|
+
val = if result[0].class == Riddl::Parameter::Simple
|
103
|
+
result[0].value
|
104
|
+
else
|
105
|
+
result[0].value.read
|
106
|
+
end
|
107
|
+
if (headers["CPEE_CALLBACK"] && headers["CPEE_CALLBACK"] == 'true') || val == 'callback'
|
108
|
+
persist_handler instance, callback_key, m, opts[:redis]
|
109
|
+
else # they may send true or false
|
110
|
+
send_response instance, callback_key, m['cpee'], val, opts[:redis]
|
111
|
+
end
|
112
|
+
else
|
113
|
+
send_response instance, callback_key, m['cpee'], true, opts[:redis]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
rescue => e
|
119
|
+
puts e.message
|
120
|
+
puts e.backtrace
|
121
|
+
p '-----------------'
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end.go!
|
@@ -0,0 +1,75 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# This file is part of CPEE-WORKLIST
|
4
|
+
#
|
5
|
+
# CPEE-WORKLIST is free software: you can redistribute it and/or modify it
|
6
|
+
# under the terms of the GNU Lesser General Public License as published by the
|
7
|
+
# Free Software Foundation, either version 3 of the License, or (at your
|
8
|
+
# option) any later version.
|
9
|
+
#
|
10
|
+
# CPEE-WORKLIST is distributed in the hope that it will be useful, but WITHOUT
|
11
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
12
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
13
|
+
# details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Lesser General Public License
|
16
|
+
# along with CPEE-WORKLIST (file LICENSE in the main directory). If not, see
|
17
|
+
# <http://www.gnu.org/licenses/>.
|
18
|
+
|
19
|
+
require 'json'
|
20
|
+
require 'redis'
|
21
|
+
require 'daemonite'
|
22
|
+
require 'cpee/value_helper'
|
23
|
+
require 'cpee/redis'
|
24
|
+
|
25
|
+
EVENTS = %w{
|
26
|
+
event:00:handler/change
|
27
|
+
}
|
28
|
+
|
29
|
+
Daemonite.new do |opts|
|
30
|
+
opts[:runtime_opts] += [
|
31
|
+
["--url=URL", "-uURL", "Specify redis url", ->(p){ opts[:redis_url] = p }],
|
32
|
+
["--path=PATH", "-pPATH", "Specify redis path, e.g. /tmp/redis.sock", ->(p){ opts[:redis_path] = p }],
|
33
|
+
["--db=DB", "-dDB", "Specify redis db, e.g. 1", ->(p) { opts[:redis_db] = p.to_i }]
|
34
|
+
]
|
35
|
+
|
36
|
+
on startup do
|
37
|
+
opts[:redis_path] ||= '/tmp/redis.sock'
|
38
|
+
opts[:redis_db] ||= 1
|
39
|
+
|
40
|
+
CPEE::redis_connect opts, 'Server Routing Persist'
|
41
|
+
opts[:pubsubredis] = opts[:redis_dyn].call 'Server Routing Persist Sub'
|
42
|
+
end
|
43
|
+
|
44
|
+
run do
|
45
|
+
opts[:pubsubredis].subscribe(EVENTS) do |on|
|
46
|
+
on.message do |what, message|
|
47
|
+
mess = JSON.parse(message[message.index(' ')+1..-1])
|
48
|
+
case what
|
49
|
+
when 'event:00:handler/change'
|
50
|
+
opts[:redis].multi do |multi|
|
51
|
+
mess.dig('content','changed').each do |c|
|
52
|
+
multi.sadd("worklist:worklist/handlers",mess.dig('content','key'))
|
53
|
+
multi.sadd("worklist:worklist/handlers/#{mess.dig('content','key')}",c)
|
54
|
+
multi.set("worklist:worklist/#handlers/#{mess.dig('content','key')}/url",mess.dig('content','url'))
|
55
|
+
multi.sadd("worklist:worklist/handlers/#{c}",mess.dig('content','key'))
|
56
|
+
end
|
57
|
+
mess.dig('content','deleted').to_a.each do |c|
|
58
|
+
multi.srem("worklist:worklist/handlers/#{mess.dig('content','key')}",c)
|
59
|
+
multi.srem("worklist:worklist/handlers/#{c}",mess.dig('content','key'))
|
60
|
+
end
|
61
|
+
end
|
62
|
+
if opts[:redis].scard("worklist:worklist/handlers/#{mess.dig('content','key')}") < 1
|
63
|
+
opts[:redis].multi do |multi|
|
64
|
+
multi.del("worklist:worklist/handlers/#{mess.dig('content','key')}/url")
|
65
|
+
multi.srem("worklist:worklist/handlers",mess.dig('content','key'))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
rescue => e
|
70
|
+
puts e.message
|
71
|
+
puts e.backtrace
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end.go!
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<!--
|
2
|
+
This file is part of CPEE-WORKLIST
|
3
|
+
|
4
|
+
CPEE-WORKLIST is free software: you can redistribute it and/or modify it
|
5
|
+
under the terms of the GNU Lesser General Public License as published by the
|
6
|
+
Free Software Foundation, either version 3 of the License, or (at your
|
7
|
+
option) any later version.
|
8
|
+
|
9
|
+
CPEE-WORKLIST is distributed in the hope that it will be useful, but WITHOUT
|
10
|
+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
11
|
+
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
12
|
+
details.
|
13
|
+
|
14
|
+
You should have received a copy of the GNU Lesser General Public License
|
15
|
+
along with CPEE-WORKLIST (file LICENSE in the main directory). If not, see
|
16
|
+
<http://www.gnu.org/licenses/>.
|
17
|
+
-->
|
18
|
+
|
19
|
+
<topics xmlns='http://riddl.org/ns/common-patterns/notifications-producer/2.0'>
|
20
|
+
<topic id='user'>
|
21
|
+
<event>status</event>
|
22
|
+
<event>take</event>
|
23
|
+
<event>giveback</event>
|
24
|
+
<event>finish</event>
|
25
|
+
</topic>
|
26
|
+
<topic id='task'>
|
27
|
+
<event>invalid</event>
|
28
|
+
<event>delete</event>
|
29
|
+
<event>add</event>
|
30
|
+
<vote>add</vote>
|
31
|
+
</topic>
|
32
|
+
</topics>
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# This file is part of CPEE-WORKLIST
|
2
|
+
#
|
3
|
+
# CPEE-WORKLIST is free software: you can redistribute it and/or modify it
|
4
|
+
# under the terms of the GNU Lesser General Public License as published by the
|
5
|
+
# Free Software Foundation, either version 3 of the License, or (at your
|
6
|
+
# option) any later version.
|
7
|
+
#
|
8
|
+
# CPEE-WORKLIST is distributed in the hope that it will be useful, but WITHOUT
|
9
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
10
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
11
|
+
# details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU Lesser General Public License
|
14
|
+
# along with CPEE-WORKLIST (file LICENSE in the main directory). If not, see
|
15
|
+
# <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
|
18
|
+
module CPEE
|
19
|
+
module Worklist
|
20
|
+
|
21
|
+
module User
|
22
|
+
def self::ok?(opts,task,user)
|
23
|
+
fname = File.join(opts[:top],'orgmodels',Riddl::Protocols::Utils::escape(task['orgmodel']))
|
24
|
+
orgmodel = XML::Smart.open_unprotected(fname)
|
25
|
+
orgmodel.register_namespace 'o', 'http://cpee.org/ns/organisation/1.0'
|
26
|
+
subjects = orgmodel.find('/o:organisation/o:subjects/o:subject')
|
27
|
+
unit = task['unit']
|
28
|
+
role = task['role']
|
29
|
+
if (unit=='*')
|
30
|
+
if (role=='*')
|
31
|
+
subjects.each{|s| return true if s.attributes['uid']==user}
|
32
|
+
else
|
33
|
+
orgmodel.find("/o:organisation/o:subjects/o:subject[o:relation/@role='#{role}']").each do |s|
|
34
|
+
return true if user==s.attributes['uid']
|
35
|
+
end
|
36
|
+
end
|
37
|
+
else
|
38
|
+
if (role=='*')
|
39
|
+
orgmodel.find("/o:organisation/o:subjects/o:subject[o:relation/@unit='#{unit}']").each do |s|
|
40
|
+
return true if user==s.attributes['uid']
|
41
|
+
end
|
42
|
+
else
|
43
|
+
orgmodel.find("/o:organisation/o:subjects/o:subject[o:relation/@unit='#{unit}' and o:relation/@role='#{role}']").each do |s|
|
44
|
+
return true if user==s.attributes['uid']
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
false
|
49
|
+
end
|
50
|
+
|
51
|
+
def self::info(opts,task,user)
|
52
|
+
fname = File.join(opts[:top],'orgmodels',Riddl::Protocols::Utils::escape(task['orgmodel']))
|
53
|
+
orgmodel = XML::Smart.open_unprotected(fname)
|
54
|
+
orgmodel.register_namespace 'o', 'http://cpee.org/ns/organisation/1.0'
|
55
|
+
user = orgmodel.find("/o:organisation/o:subjects/o:subject[@uid='#{user}']/o:relation")
|
56
|
+
{}.tap{ |t| user.map{|u| (t[u.attributes['unit']]||=[]) << u.attributes['role']}}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# This file is part of CPEE-WORKLIST
|
2
|
+
#
|
3
|
+
# CPEE-WORKLIST is free software: you can redistribute it and/or modify it
|
4
|
+
# under the terms of the GNU Lesser General Public License as published by the
|
5
|
+
# Free Software Foundation, either version 3 of the License, or (at your
|
6
|
+
# option) any later version.
|
7
|
+
#
|
8
|
+
# CPEE-WORKLIST is distributed in the hope that it will be useful, but WITHOUT
|
9
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
10
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
11
|
+
# details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU Lesser General Public License
|
14
|
+
# along with CPEE-WORKLIST (file LICENSE in the main directory). If not, see
|
15
|
+
# <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
module CPEE
|
18
|
+
module Worklist
|
19
|
+
|
20
|
+
def self::watch_services(watchdog_start_off,url,path,db)
|
21
|
+
return if watchdog_start_off
|
22
|
+
EM.defer do
|
23
|
+
Dir[File.join(__dir__,'routing','*.rb')].each do |s|
|
24
|
+
s = s.sub(/\.rb$/,'')
|
25
|
+
pid = (File.read(s + '.pid').to_i rescue nil)
|
26
|
+
cmd = if url.nil?
|
27
|
+
"-p \"#{path}\" -d #{db} restart"
|
28
|
+
else
|
29
|
+
"-u \"#{url}\" -d #{db} restart"
|
30
|
+
end
|
31
|
+
if (pid.nil? || !(Process.kill(0, pid) rescue false)) && !File.exist?(s + '.lock')
|
32
|
+
system "#{s}.rb " + cmd + " 1>/dev/null 2>&1"
|
33
|
+
puts "➡ Service #{File.basename(s)} (-v #{cmd}) started ..."
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def self::cleanup_services(watchdog_start_off)
|
40
|
+
return if watchdog_start_off
|
41
|
+
Dir[File.join(__dir__,'routing','*.rb')].each do |s|
|
42
|
+
s = s.sub(/\.rb$/,'')
|
43
|
+
pid = (File.read(s + '.pid').to_i rescue nil)
|
44
|
+
if !pid.nil? || (Process.kill(0, pid) rescue false)
|
45
|
+
system "#{s}.rb stop 1>/dev/null 2>&1"
|
46
|
+
puts "➡ Service #{File.basename(s,'.rb')} stopped ..."
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
<!--
|
2
|
+
This file is part of CPEE-WORKLIST
|
3
|
+
|
4
|
+
CPEE-WORKLIST is free software: you can redistribute it and/or modify it
|
5
|
+
under the terms of the GNU Lesser General Public License as published by the
|
6
|
+
Free Software Foundation, either version 3 of the License, or (at your
|
7
|
+
option) any later version.
|
8
|
+
|
9
|
+
CPEE-WORKLIST is distributed in the hope that it will be useful, but WITHOUT
|
10
|
+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
11
|
+
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
12
|
+
details.
|
13
|
+
|
14
|
+
You should have received a copy of the GNU Lesser General Public License
|
15
|
+
along with CPEE-WORKLIST (file LICENSE in the main directory). If not, see
|
16
|
+
<http://www.gnu.org/licenses/>.
|
17
|
+
-->
|
18
|
+
|
19
|
+
<description xmlns="http://riddl.org/ns/description/1.0" xmlns:ann="http://riddl.org/ns/annotation/1.0" xmlns:xi="http://www.w3.org/2001/XInclude" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
|
20
|
+
<message name="activityhappens"> <!--{{{-->
|
21
|
+
<parameter name="orgmodel" type="string"/>
|
22
|
+
<parameter name="form" type="string"/>
|
23
|
+
<choice>
|
24
|
+
<parameter name="unit" type="string"/>
|
25
|
+
<parameter name="role" type="string"/>
|
26
|
+
<group>
|
27
|
+
<parameter name="unit" type="string"/>
|
28
|
+
<parameter name="role" type="string"/>
|
29
|
+
</group>
|
30
|
+
</choice>
|
31
|
+
<optional>
|
32
|
+
<parameter name="priority" type="positiveInteger"/>
|
33
|
+
</optional>
|
34
|
+
<optional>
|
35
|
+
<parameter name="collect" type="nonNegativeInteger"/>
|
36
|
+
</optional>
|
37
|
+
<optional>
|
38
|
+
<parameter name="deadline" type="string"/>
|
39
|
+
</optional>
|
40
|
+
<parameter name="restrictions" type="string"/>
|
41
|
+
<parameter name="data" type="string"/>
|
42
|
+
</message> <!--}}}-->
|
43
|
+
|
44
|
+
<message name="uid">
|
45
|
+
<parameter name="userid" type="string"/>
|
46
|
+
</message>
|
47
|
+
<message name="status">
|
48
|
+
<parameter name="status" type="string"/>
|
49
|
+
</message>
|
50
|
+
<message name="take">
|
51
|
+
<parameter name="operation" fixed="take"/>
|
52
|
+
</message>
|
53
|
+
<message name="giveback">
|
54
|
+
<parameter name="operation" fixed="giveback"/>
|
55
|
+
</message>
|
56
|
+
|
57
|
+
<message name="tasks">
|
58
|
+
<parameter name="tasks" mimetype="text/xml" handler="http://riddl.org/ns/handlers/relaxng">
|
59
|
+
<element name="tasks" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" xmlns="http://relaxng.org/ns/structure/1.0">
|
60
|
+
<zeroOrMore>
|
61
|
+
<element name="task">
|
62
|
+
<attribute name="callback_id">
|
63
|
+
<data type="string"/>
|
64
|
+
</attribute>
|
65
|
+
<attribute name="cpee_callback">
|
66
|
+
<data type="string"/>
|
67
|
+
</attribute>
|
68
|
+
<attribute name="cpee_instance">
|
69
|
+
<data type="string"/>
|
70
|
+
</attribute>
|
71
|
+
<attribute name="cpee_base">
|
72
|
+
<data type="string"/>
|
73
|
+
</attribute>
|
74
|
+
<attribute name="instance_uuid">
|
75
|
+
<data type="string"/>
|
76
|
+
</attribute>
|
77
|
+
<attribute name="cpee_label">
|
78
|
+
<data type="string"/>
|
79
|
+
</attribute>
|
80
|
+
<attribute name="cpee_activity">
|
81
|
+
<data type="string"/>
|
82
|
+
</attribute>
|
83
|
+
<attribute name="orgmodel">
|
84
|
+
<data type="string"/>
|
85
|
+
</attribute>
|
86
|
+
<element name="label">
|
87
|
+
<data type="string"/>
|
88
|
+
</element>
|
89
|
+
<element name="role">
|
90
|
+
<data type="string"/>
|
91
|
+
</element>
|
92
|
+
<element name="unit">
|
93
|
+
<data type="string"/>
|
94
|
+
</element>
|
95
|
+
<oneOrMore>
|
96
|
+
<element name="user">
|
97
|
+
<attribute name="uid">
|
98
|
+
<data type="string"/>
|
99
|
+
</attribute>
|
100
|
+
<data type="string"/>
|
101
|
+
</element>
|
102
|
+
</oneOrMore>
|
103
|
+
</element>
|
104
|
+
</zeroOrMore>
|
105
|
+
</element>
|
106
|
+
</parameter>
|
107
|
+
</message>
|
108
|
+
<message name="xml">
|
109
|
+
<parameter name="return" mimetype="text/xml"/>
|
110
|
+
</message>
|
111
|
+
<message name="json">
|
112
|
+
<parameter name="data" mimetype="application/json"/>
|
113
|
+
</message>
|
114
|
+
<message name="callbacks">
|
115
|
+
<parameter name="info" mimetype="text/xml" handler="http://riddl.org/ns/handlers/relaxng">
|
116
|
+
<grammar xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
|
117
|
+
<start>
|
118
|
+
<element name="callbacks">
|
119
|
+
<attribute name="details">
|
120
|
+
<choice>
|
121
|
+
<value>debug</value>
|
122
|
+
<value>production</value>
|
123
|
+
</choice>
|
124
|
+
</attribute>
|
125
|
+
<zeroOrMore>
|
126
|
+
<ref name="callback"/>
|
127
|
+
</zeroOrMore>
|
128
|
+
</element>
|
129
|
+
</start>
|
130
|
+
|
131
|
+
<define name="callback">
|
132
|
+
<element name='callback'>
|
133
|
+
<attribute name='id'>
|
134
|
+
<data type="string"/>
|
135
|
+
</attribute>
|
136
|
+
<data type="string"/>
|
137
|
+
</element>
|
138
|
+
</define>
|
139
|
+
|
140
|
+
</grammar>
|
141
|
+
</parameter>
|
142
|
+
</message>
|
143
|
+
|
144
|
+
<resource>
|
145
|
+
<post in="activityhappens"/>
|
146
|
+
<get out="tasks"/>
|
147
|
+
<resource relative="orgmodels">
|
148
|
+
<get out="xml"/>
|
149
|
+
</resource>
|
150
|
+
<resource relative="tasks"> <!-- all tasks in domain -->
|
151
|
+
<resource> <!-- task -->
|
152
|
+
<delete/>
|
153
|
+
<put in="uid"/>
|
154
|
+
</resource>
|
155
|
+
</resource>
|
156
|
+
<resource relative="callbacks">
|
157
|
+
<get in="*" out="callbacks"/>
|
158
|
+
<resource>
|
159
|
+
<put in="*"/>
|
160
|
+
</resource>
|
161
|
+
</resource>
|
162
|
+
<resource> <!-- user -->
|
163
|
+
<put in="status"/>
|
164
|
+
<get out="status"/>
|
165
|
+
<resource relative="tasks">
|
166
|
+
<get out="xml"/>
|
167
|
+
<resource> <!-- task -->
|
168
|
+
<get out="json"/>
|
169
|
+
<put in="take"/>
|
170
|
+
<put in="giveback"/>
|
171
|
+
<delete/>
|
172
|
+
</resource>
|
173
|
+
</resource>
|
174
|
+
</resource>
|
175
|
+
</resource>
|
176
|
+
</description>
|
data/server/worklist
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# This file is part of CPEE-WORKLIST
|
4
|
+
#
|
5
|
+
# CPEE-WORKLIST is free software: you can redistribute it and/or modify it
|
6
|
+
# under the terms of the GNU Lesser General Public License as published by the
|
7
|
+
# Free Software Foundation, either version 3 of the License, or (at your
|
8
|
+
# option) any later version.
|
9
|
+
#
|
10
|
+
# CPEE-WORKLIST is distributed in the hope that it will be useful, but WITHOUT
|
11
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
12
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
13
|
+
# details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Lesser General Public License
|
16
|
+
# along with CPEE-WORKLIST (file LICENSE in the main directory). If not, see
|
17
|
+
# <http://www.gnu.org/licenses/>.
|
18
|
+
|
19
|
+
require 'rubygems'
|
20
|
+
if File.exist? File.join(__dir__,'../lib/cpee-worklist/implementation.rb')
|
21
|
+
require_relative '../lib/cpee-worklist/implementation'
|
22
|
+
else
|
23
|
+
require 'cpee-worklist/implementation'
|
24
|
+
end
|
25
|
+
|
26
|
+
options = {
|
27
|
+
:host => 'localhost',
|
28
|
+
:port => 9398,
|
29
|
+
:secure => false
|
30
|
+
}
|
31
|
+
|
32
|
+
Riddl::Server.new(CPEE::Worklist::SERVER, options) do |opts|
|
33
|
+
accessible_description true
|
34
|
+
cross_site_xhr true
|
35
|
+
|
36
|
+
use CPEE::Worklist::implementation(opts)
|
37
|
+
end.loop!
|