cloudmunda 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/Gemfile +1 -2
- data/Gemfile.lock +153 -1
- data/README.md +10 -1
- data/exe/cloudmunda +14 -0
- data/lib/cloudmunda/api/access_token.rb +19 -0
- data/lib/cloudmunda/api/client.rb +29 -0
- data/lib/cloudmunda/api/o_auth_resource.rb +19 -0
- data/lib/cloudmunda/api.rb +4 -0
- data/lib/cloudmunda/cli/launcher.rb +35 -0
- data/lib/cloudmunda/cli/processor.rb +109 -0
- data/lib/cloudmunda/cli/supervisor.rb +37 -0
- data/lib/cloudmunda/cli/worker.rb +163 -0
- data/lib/cloudmunda/cli.rb +169 -0
- data/lib/cloudmunda/configuration.rb +35 -0
- data/lib/cloudmunda/graphql/client.rb +29 -0
- data/lib/cloudmunda/graphql/user_tasks.rb +35 -0
- data/lib/cloudmunda/graphql.rb +2 -0
- data/lib/cloudmunda/loggable.rb +15 -0
- data/lib/cloudmunda/version.rb +1 -1
- data/lib/cloudmunda/zeebe/client.rb +107 -0
- data/lib/cloudmunda/zeebe.rb +1 -0
- data/lib/cloudmunda.rb +22 -2
- metadata +63 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0882dcb50d23ad283984404e67f589a28d39a08c19ec44b9c2ca00659386962e'
|
4
|
+
data.tar.gz: 7d03f8ddd3c6cc8ba8a464e64e84a14234a791540f947a25cb94dd36fd5bc8c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1aa60b038071944496032564eb73a21c3344211ab4339cc77d9d74de6ecaf7814e31eb69fafada0cd6f25432f9e4a85f2cf9003edf209735605986f9c5c26f9b
|
7
|
+
data.tar.gz: 5e5d47130dc95f8d98a12facaf4dc8830cded1f3420e3b96df838d5730c01339dd0187177d9f5d92c6c1ac175b67d647530dc497383686eda2d46a16cba57355
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,19 +1,151 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
cloudmunda (0.1.
|
4
|
+
cloudmunda (0.1.1)
|
5
|
+
concurrent-ruby (~> 1.0)
|
6
|
+
rest-client (~> 2.0)
|
7
|
+
zeebe-client (~> 0.16)
|
5
8
|
|
6
9
|
GEM
|
7
10
|
remote: https://rubygems.org/
|
8
11
|
specs:
|
12
|
+
actioncable (6.1.4.1)
|
13
|
+
actionpack (= 6.1.4.1)
|
14
|
+
activesupport (= 6.1.4.1)
|
15
|
+
nio4r (~> 2.0)
|
16
|
+
websocket-driver (>= 0.6.1)
|
17
|
+
actionmailbox (6.1.4.1)
|
18
|
+
actionpack (= 6.1.4.1)
|
19
|
+
activejob (= 6.1.4.1)
|
20
|
+
activerecord (= 6.1.4.1)
|
21
|
+
activestorage (= 6.1.4.1)
|
22
|
+
activesupport (= 6.1.4.1)
|
23
|
+
mail (>= 2.7.1)
|
24
|
+
actionmailer (6.1.4.1)
|
25
|
+
actionpack (= 6.1.4.1)
|
26
|
+
actionview (= 6.1.4.1)
|
27
|
+
activejob (= 6.1.4.1)
|
28
|
+
activesupport (= 6.1.4.1)
|
29
|
+
mail (~> 2.5, >= 2.5.4)
|
30
|
+
rails-dom-testing (~> 2.0)
|
31
|
+
actionpack (6.1.4.1)
|
32
|
+
actionview (= 6.1.4.1)
|
33
|
+
activesupport (= 6.1.4.1)
|
34
|
+
rack (~> 2.0, >= 2.0.9)
|
35
|
+
rack-test (>= 0.6.3)
|
36
|
+
rails-dom-testing (~> 2.0)
|
37
|
+
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
38
|
+
actiontext (6.1.4.1)
|
39
|
+
actionpack (= 6.1.4.1)
|
40
|
+
activerecord (= 6.1.4.1)
|
41
|
+
activestorage (= 6.1.4.1)
|
42
|
+
activesupport (= 6.1.4.1)
|
43
|
+
nokogiri (>= 1.8.5)
|
44
|
+
actionview (6.1.4.1)
|
45
|
+
activesupport (= 6.1.4.1)
|
46
|
+
builder (~> 3.1)
|
47
|
+
erubi (~> 1.4)
|
48
|
+
rails-dom-testing (~> 2.0)
|
49
|
+
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
50
|
+
activejob (6.1.4.1)
|
51
|
+
activesupport (= 6.1.4.1)
|
52
|
+
globalid (>= 0.3.6)
|
53
|
+
activemodel (6.1.4.1)
|
54
|
+
activesupport (= 6.1.4.1)
|
55
|
+
activerecord (6.1.4.1)
|
56
|
+
activemodel (= 6.1.4.1)
|
57
|
+
activesupport (= 6.1.4.1)
|
58
|
+
activestorage (6.1.4.1)
|
59
|
+
actionpack (= 6.1.4.1)
|
60
|
+
activejob (= 6.1.4.1)
|
61
|
+
activerecord (= 6.1.4.1)
|
62
|
+
activesupport (= 6.1.4.1)
|
63
|
+
marcel (~> 1.0.0)
|
64
|
+
mini_mime (>= 1.1.0)
|
65
|
+
activesupport (6.1.4.1)
|
66
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
67
|
+
i18n (>= 1.6, < 2)
|
68
|
+
minitest (>= 5.1)
|
69
|
+
tzinfo (~> 2.0)
|
70
|
+
zeitwerk (~> 2.3)
|
9
71
|
ast (2.4.2)
|
72
|
+
builder (3.2.4)
|
73
|
+
concurrent-ruby (1.1.9)
|
74
|
+
crass (1.0.6)
|
10
75
|
diff-lcs (1.4.4)
|
76
|
+
domain_name (0.5.20190701)
|
77
|
+
unf (>= 0.0.5, < 1.0.0)
|
78
|
+
erubi (1.10.0)
|
79
|
+
globalid (1.0.0)
|
80
|
+
activesupport (>= 5.0)
|
81
|
+
google-protobuf (3.19.1-x86_64-darwin)
|
82
|
+
googleapis-common-protos-types (1.3.0)
|
83
|
+
google-protobuf (~> 3.14)
|
84
|
+
grpc (1.42.0-x86_64-darwin)
|
85
|
+
google-protobuf (~> 3.18)
|
86
|
+
googleapis-common-protos-types (~> 1.0)
|
87
|
+
http-accept (1.7.0)
|
88
|
+
http-cookie (1.0.4)
|
89
|
+
domain_name (~> 0.5)
|
90
|
+
i18n (1.8.11)
|
91
|
+
concurrent-ruby (~> 1.0)
|
92
|
+
loofah (2.13.0)
|
93
|
+
crass (~> 1.0.2)
|
94
|
+
nokogiri (>= 1.5.9)
|
95
|
+
mail (2.7.1)
|
96
|
+
mini_mime (>= 0.1.1)
|
97
|
+
marcel (1.0.2)
|
98
|
+
method_source (1.0.0)
|
99
|
+
mime-types (3.4.1)
|
100
|
+
mime-types-data (~> 3.2015)
|
101
|
+
mime-types-data (3.2021.1115)
|
102
|
+
mini_mime (1.1.2)
|
103
|
+
minitest (5.14.4)
|
104
|
+
netrc (0.11.0)
|
105
|
+
nio4r (2.5.8)
|
106
|
+
nokogiri (1.12.5-x86_64-darwin)
|
107
|
+
racc (~> 1.4)
|
11
108
|
parallel (1.21.0)
|
12
109
|
parser (3.0.3.2)
|
13
110
|
ast (~> 2.4.1)
|
111
|
+
racc (1.6.0)
|
112
|
+
rack (2.2.3)
|
113
|
+
rack-test (1.1.0)
|
114
|
+
rack (>= 1.0, < 3)
|
115
|
+
rails (6.1.4.1)
|
116
|
+
actioncable (= 6.1.4.1)
|
117
|
+
actionmailbox (= 6.1.4.1)
|
118
|
+
actionmailer (= 6.1.4.1)
|
119
|
+
actionpack (= 6.1.4.1)
|
120
|
+
actiontext (= 6.1.4.1)
|
121
|
+
actionview (= 6.1.4.1)
|
122
|
+
activejob (= 6.1.4.1)
|
123
|
+
activemodel (= 6.1.4.1)
|
124
|
+
activerecord (= 6.1.4.1)
|
125
|
+
activestorage (= 6.1.4.1)
|
126
|
+
activesupport (= 6.1.4.1)
|
127
|
+
bundler (>= 1.15.0)
|
128
|
+
railties (= 6.1.4.1)
|
129
|
+
sprockets-rails (>= 2.0.0)
|
130
|
+
rails-dom-testing (2.0.3)
|
131
|
+
activesupport (>= 4.2.0)
|
132
|
+
nokogiri (>= 1.6)
|
133
|
+
rails-html-sanitizer (1.4.2)
|
134
|
+
loofah (~> 2.3)
|
135
|
+
railties (6.1.4.1)
|
136
|
+
actionpack (= 6.1.4.1)
|
137
|
+
activesupport (= 6.1.4.1)
|
138
|
+
method_source
|
139
|
+
rake (>= 0.13)
|
140
|
+
thor (~> 1.0)
|
14
141
|
rainbow (3.0.0)
|
15
142
|
rake (13.0.6)
|
16
143
|
regexp_parser (2.2.0)
|
144
|
+
rest-client (2.1.0)
|
145
|
+
http-accept (>= 1.7.0, < 2.0)
|
146
|
+
http-cookie (>= 1.0.2, < 2.0)
|
147
|
+
mime-types (>= 1.16, < 4.0)
|
148
|
+
netrc (~> 0.8)
|
17
149
|
rexml (3.2.5)
|
18
150
|
rspec (3.10.0)
|
19
151
|
rspec-core (~> 3.10.0)
|
@@ -40,13 +172,33 @@ GEM
|
|
40
172
|
rubocop-ast (1.15.0)
|
41
173
|
parser (>= 3.0.1.1)
|
42
174
|
ruby-progressbar (1.11.0)
|
175
|
+
sprockets (4.0.2)
|
176
|
+
concurrent-ruby (~> 1.0)
|
177
|
+
rack (> 1, < 3)
|
178
|
+
sprockets-rails (3.4.1)
|
179
|
+
actionpack (>= 5.2)
|
180
|
+
activesupport (>= 5.2)
|
181
|
+
sprockets (>= 3.0.0)
|
182
|
+
thor (1.1.0)
|
183
|
+
tzinfo (2.0.4)
|
184
|
+
concurrent-ruby (~> 1.0)
|
185
|
+
unf (0.1.4)
|
186
|
+
unf_ext
|
187
|
+
unf_ext (0.0.8)
|
43
188
|
unicode-display_width (2.1.0)
|
189
|
+
websocket-driver (0.7.5)
|
190
|
+
websocket-extensions (>= 0.1.0)
|
191
|
+
websocket-extensions (0.1.5)
|
192
|
+
zeebe-client (0.16.0)
|
193
|
+
grpc (~> 1.32)
|
194
|
+
zeitwerk (2.5.1)
|
44
195
|
|
45
196
|
PLATFORMS
|
46
197
|
x86_64-darwin-20
|
47
198
|
|
48
199
|
DEPENDENCIES
|
49
200
|
cloudmunda!
|
201
|
+
rails (>= 6)
|
50
202
|
rake (~> 13.0)
|
51
203
|
rspec (~> 3.0)
|
52
204
|
rubocop (~> 1.21)
|
data/README.md
CHANGED
@@ -22,7 +22,16 @@ Or install it yourself as:
|
|
22
22
|
|
23
23
|
## Usage
|
24
24
|
|
25
|
-
|
25
|
+
```ruby
|
26
|
+
Cloudmunda.configure do |config|
|
27
|
+
config.env = ENV['APP_ENV'] || ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
|
28
|
+
config.require = '.'
|
29
|
+
config.timeout = 30
|
30
|
+
config.zeebe_url = ENV['ZEEBE_URL']
|
31
|
+
config.auth_url = ENV['ZEEBE_AUTHORIZATION_SERVER_URL']
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
26
35
|
|
27
36
|
## Development
|
28
37
|
|
data/exe/cloudmunda
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "bundler/setup"
|
3
|
+
require "cloudmunda/cli"
|
4
|
+
|
5
|
+
begin
|
6
|
+
cli = ::Cloudmunda::CLI.instance
|
7
|
+
cli.parse
|
8
|
+
cli.run
|
9
|
+
rescue => e
|
10
|
+
raise e if $DEBUG
|
11
|
+
STDERR.puts e.message
|
12
|
+
STDERR.puts e.backtrace.join("\n")
|
13
|
+
exit 1
|
14
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cloudmunda
|
4
|
+
module API
|
5
|
+
class AccessToken < Cloudmunda::API::OAuthResource
|
6
|
+
def self.create(audience_url: Cloudmunda.audience)
|
7
|
+
uri = Cloudmunda.auth_url
|
8
|
+
payload = {
|
9
|
+
"grant_type":"client_credentials",
|
10
|
+
"audience": audience_url,
|
11
|
+
"client_id": Cloudmunda.client_id,
|
12
|
+
"client_secret": Cloudmunda.client_secret
|
13
|
+
}
|
14
|
+
|
15
|
+
create_by_uri(uri: uri, payload: payload)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rest-client'
|
4
|
+
require 'json'
|
5
|
+
require 'uri'
|
6
|
+
require 'base64'
|
7
|
+
|
8
|
+
module Cloudmunda
|
9
|
+
module API
|
10
|
+
class Client
|
11
|
+
def self.post(url, params = {})
|
12
|
+
response = RestClient.post(url, params.to_json, headers.merge(content_headers))
|
13
|
+
JSON.parse(response.body)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.headers
|
17
|
+
{
|
18
|
+
authorization: "Basic " + Base64.strict_encode64("#{Cloudmunda.client_id}:#{Cloudmunda.client_secret}"),
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.content_headers
|
23
|
+
{
|
24
|
+
'Content-Type': 'application/json'
|
25
|
+
}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
module Cloudmunda
|
6
|
+
module API
|
7
|
+
class OAuthResource < OpenStruct
|
8
|
+
def self.create_by_uri(uri:, payload:)
|
9
|
+
raw_item = Cloudmunda::API::Client.post(uri, payload)
|
10
|
+
raw_item = {} if raw_item == ""
|
11
|
+
new(raw_item)
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(raw)
|
15
|
+
super(raw)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative 'supervisor'
|
2
|
+
|
3
|
+
module Cloudmunda
|
4
|
+
class Launcher
|
5
|
+
|
6
|
+
attr_reader :supervisor
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@supervisor = ::Cloudmunda::Supervisor.new
|
10
|
+
end
|
11
|
+
|
12
|
+
# Starts the supervisor and job processors.
|
13
|
+
def start
|
14
|
+
supervisor.start
|
15
|
+
end
|
16
|
+
|
17
|
+
# Tells the supervisor to stop processing any more jobs.
|
18
|
+
def quiet
|
19
|
+
supervisor.quiet
|
20
|
+
end
|
21
|
+
|
22
|
+
# Tells the supervisor to stop job processors. This method blocks until
|
23
|
+
# all processors are complete and stopped. It can take up to configurable
|
24
|
+
# timeout.
|
25
|
+
def stop
|
26
|
+
supervisor.stop
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def client
|
32
|
+
::Cloudmunda.client
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module Cloudmunda
|
2
|
+
class Processor
|
3
|
+
|
4
|
+
attr_reader :client, :worker_class, :busy_count, :timer
|
5
|
+
|
6
|
+
def initialize(client: ::Cloudmunda.client, worker_class:)
|
7
|
+
@client = client
|
8
|
+
@worker_class = worker_class
|
9
|
+
@busy_count = ::Concurrent::AtomicFixnum.new(0)
|
10
|
+
@timer = ::Concurrent::TimerTask.new(
|
11
|
+
run_now: true,
|
12
|
+
execution_interval: worker_poll_interval,
|
13
|
+
timeout_interval: worker_timeout
|
14
|
+
) { run }
|
15
|
+
end
|
16
|
+
|
17
|
+
def start
|
18
|
+
timer.execute
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def stop
|
23
|
+
timer.shutdown
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def should_activate_jobs?
|
28
|
+
busy_count.value <= worker_max_jobs_to_activate
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def run
|
34
|
+
fetch if should_activate_jobs?
|
35
|
+
end
|
36
|
+
|
37
|
+
def fetch
|
38
|
+
activate_jobs_request.each do |response|
|
39
|
+
busy_count.increment(response.jobs.count)
|
40
|
+
response.jobs.each do |job|
|
41
|
+
::Concurrent::Future.execute do
|
42
|
+
process(job)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def process(job)
|
49
|
+
worker = worker_class.new(client)
|
50
|
+
begin
|
51
|
+
logger.info "class=#{worker_class} jid=#{job.key} Start processing #{job.type}"
|
52
|
+
|
53
|
+
worker.process(job)
|
54
|
+
worker.complete_job(job)
|
55
|
+
|
56
|
+
logger.info "class=#{worker_class} jid=#{job.key} Done processing #{job.type}"
|
57
|
+
rescue => exception
|
58
|
+
logger.info "class=#{worker_class} jid=#{job.key} Failed processing #{job.type}: #{exception.message}"
|
59
|
+
|
60
|
+
worker.fail_job(job, reason: exception.message)
|
61
|
+
raise exception
|
62
|
+
ensure
|
63
|
+
busy_count.decrement
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def activate_jobs_request
|
68
|
+
client.activate_jobs(
|
69
|
+
type: worker_type,
|
70
|
+
worker: worker_name,
|
71
|
+
timeout: worker_timeout * 1000,
|
72
|
+
maxJobsToActivate: max_jobs_to_activate,
|
73
|
+
fetchVariable: worker_variables_to_fetch,
|
74
|
+
)
|
75
|
+
end
|
76
|
+
|
77
|
+
def worker_type
|
78
|
+
worker_class.get_type
|
79
|
+
end
|
80
|
+
|
81
|
+
def worker_name
|
82
|
+
worker_class.get_name
|
83
|
+
end
|
84
|
+
|
85
|
+
def worker_max_jobs_to_activate
|
86
|
+
worker_class.get_max_jobs_to_activate
|
87
|
+
end
|
88
|
+
|
89
|
+
def worker_timeout
|
90
|
+
worker_class.get_timeout
|
91
|
+
end
|
92
|
+
|
93
|
+
def worker_variables_to_fetch
|
94
|
+
worker_class.get_variables_to_fetch
|
95
|
+
end
|
96
|
+
|
97
|
+
def worker_poll_interval
|
98
|
+
worker_class.get_poll_interval
|
99
|
+
end
|
100
|
+
|
101
|
+
def max_jobs_to_activate
|
102
|
+
worker_max_jobs_to_activate - busy_count.value
|
103
|
+
end
|
104
|
+
|
105
|
+
def logger
|
106
|
+
::Cloudmunda.logger
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require_relative 'processor'
|
2
|
+
|
3
|
+
module Cloudmunda
|
4
|
+
class Supervisor
|
5
|
+
def initialize
|
6
|
+
@processors = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def start
|
10
|
+
@processors = workers.map do |worker_class|
|
11
|
+
processor = ::Cloudmunda::Processor.new(worker_class: worker_class)
|
12
|
+
processor.start
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def quiet
|
17
|
+
logger.info "Terminating workers"
|
18
|
+
@processors.each(&:stop)
|
19
|
+
end
|
20
|
+
|
21
|
+
def stop(timeout: ::Cloudmunda.timeout)
|
22
|
+
quiet
|
23
|
+
logger.info "Pausing #{timeout}s to allow workers to finish..."
|
24
|
+
sleep timeout
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def workers
|
30
|
+
::Cloudmunda.workers.to_a
|
31
|
+
end
|
32
|
+
|
33
|
+
def logger
|
34
|
+
::Cloudmunda.logger
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Cloudmunda
|
4
|
+
module Worker
|
5
|
+
attr_accessor :client, :type, :max_jobs_to_activate, :poll_interval, :timeout, :variables
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
base.extend(ClassMethods)
|
9
|
+
Cloudmunda.register_worker(base)
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(client)
|
13
|
+
@client = client
|
14
|
+
end
|
15
|
+
|
16
|
+
def complete_job(job, variables: {})
|
17
|
+
logger.info "Completed processing job #{job.type} #{job.key}"
|
18
|
+
client.complete_job(
|
19
|
+
jobKey: job.key,
|
20
|
+
variables: Hash(variables).to_json,
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def fail_job(job, reason: "")
|
25
|
+
logger.error "Failed processing job #{job.type} #{job.key}: #{reason}"
|
26
|
+
client.fail_job(
|
27
|
+
jobKey: job.key,
|
28
|
+
retries: job.retries - 1,
|
29
|
+
errorMessage: reason,
|
30
|
+
)
|
31
|
+
rescue => e
|
32
|
+
logger.error e.message
|
33
|
+
end
|
34
|
+
|
35
|
+
def logger
|
36
|
+
::Cloudmunda.logger
|
37
|
+
end
|
38
|
+
|
39
|
+
module ClassMethods
|
40
|
+
# Sets the type of service task the worker should subscribe to.
|
41
|
+
#
|
42
|
+
# @example
|
43
|
+
# class MyWorker
|
44
|
+
# include ::Cloudmunda::Worker
|
45
|
+
# type "some-service-task-type"
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# @param [String] type
|
49
|
+
# @return [String]
|
50
|
+
def type(type)
|
51
|
+
@type = type
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns the type of service task the worker should subscribe to.
|
55
|
+
#
|
56
|
+
# @return [String]
|
57
|
+
def get_type
|
58
|
+
@type
|
59
|
+
end
|
60
|
+
|
61
|
+
# Sets the maximum number of jobs to send to the worker for processing at once.
|
62
|
+
# As jobs get completed by the worker, more jobs will be sent to the worker
|
63
|
+
# but always within this limit.
|
64
|
+
#
|
65
|
+
# @example
|
66
|
+
# class MyWorker
|
67
|
+
# include ::Cloudmunda::Worker
|
68
|
+
# max_jobs_to_activate 5
|
69
|
+
# end
|
70
|
+
#
|
71
|
+
# @param [Integer] max_jobs_to_activate
|
72
|
+
# @return [Integer]
|
73
|
+
def max_jobs_to_activate(max_jobs_to_activate)
|
74
|
+
@max_jobs_to_activate = max_jobs_to_activate
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns the maximum number of jobs to send to the worker for processing at once.
|
78
|
+
# As jobs get completed by the worker, more jobs will be sent to the worker
|
79
|
+
# but always within this limit.
|
80
|
+
#
|
81
|
+
# @return [Integer]
|
82
|
+
def get_max_jobs_to_activate
|
83
|
+
@max_jobs_to_activate || 1
|
84
|
+
end
|
85
|
+
|
86
|
+
# Sets the interval duration in seconds between polls to the broker.
|
87
|
+
#
|
88
|
+
# @example
|
89
|
+
# class MyWorker
|
90
|
+
# include ::Cloudmunda::Worker
|
91
|
+
# poll_interval 5
|
92
|
+
# end
|
93
|
+
#
|
94
|
+
# @param [Integer] poll_interval
|
95
|
+
# @return [Integer]
|
96
|
+
def poll_interval(poll_interval)
|
97
|
+
@poll_interval = poll_interval
|
98
|
+
end
|
99
|
+
|
100
|
+
# Returns the interval duration in seconds between polls to the broker.
|
101
|
+
#
|
102
|
+
# @return [Integer]
|
103
|
+
def get_poll_interval
|
104
|
+
@poll_interval || 5
|
105
|
+
end
|
106
|
+
|
107
|
+
# Sets the time in seconds the worker has to process the job before
|
108
|
+
# the broker consider it as expired and can schedule it to another worker.
|
109
|
+
#
|
110
|
+
# @example
|
111
|
+
# class MyWorker
|
112
|
+
# include ::Cloudmunda::Worker
|
113
|
+
# timeout 30
|
114
|
+
# end
|
115
|
+
#
|
116
|
+
# @param [Integer] timeout
|
117
|
+
# @return [Integer]
|
118
|
+
def timeout(timeout)
|
119
|
+
@timeout = timeout
|
120
|
+
end
|
121
|
+
|
122
|
+
# Returns the time in seconds the worker has to process the job before
|
123
|
+
# the broker consider it as expired and can schedule it to another worker.
|
124
|
+
#
|
125
|
+
# @return [Integer]
|
126
|
+
def get_timeout
|
127
|
+
@timeout || 30
|
128
|
+
end
|
129
|
+
|
130
|
+
# Sets the worker's variables to fetch from the broker when polling for new
|
131
|
+
# jobs.
|
132
|
+
#
|
133
|
+
# @example
|
134
|
+
# class MyWorker
|
135
|
+
# include ::Cloudmunda::Worker
|
136
|
+
# variables [:foo, :bar]
|
137
|
+
# end
|
138
|
+
#
|
139
|
+
# @param [Array<String, Symbol>] variables
|
140
|
+
# @return [Array<String, Symbol>]
|
141
|
+
def variables(variables)
|
142
|
+
@variables = variables
|
143
|
+
end
|
144
|
+
|
145
|
+
# Returns the worker's variables to fetch from the broker when polling for new
|
146
|
+
# jobs.
|
147
|
+
#
|
148
|
+
# @return [Array<String, Symbol>]
|
149
|
+
def get_variables_to_fetch
|
150
|
+
@variables.to_a
|
151
|
+
end
|
152
|
+
|
153
|
+
# Returns the worker's name.
|
154
|
+
#
|
155
|
+
# @return [String]
|
156
|
+
def get_name
|
157
|
+
name = self.name.gsub(/::/, ':')
|
158
|
+
name.gsub!(/([^A-Z:])([A-Z])/) { "#{$1}_#{$2}" }
|
159
|
+
name.downcase
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'optparse'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'cloudmunda'
|
5
|
+
require 'cloudmunda/cli/launcher'
|
6
|
+
|
7
|
+
$stdout.sync = true
|
8
|
+
|
9
|
+
module Cloudmunda
|
10
|
+
class CLI
|
11
|
+
include Singleton
|
12
|
+
|
13
|
+
attr_accessor :launcher
|
14
|
+
|
15
|
+
def parse(argv = ARGV)
|
16
|
+
parse_options(argv)
|
17
|
+
end
|
18
|
+
|
19
|
+
def run
|
20
|
+
boot
|
21
|
+
|
22
|
+
self_read, self_write = IO.pipe
|
23
|
+
sigs = %w[INT TERM]
|
24
|
+
sigs.each do |sig|
|
25
|
+
trap sig do
|
26
|
+
self_write.write("#{sig}\n")
|
27
|
+
end
|
28
|
+
rescue ArgumentError
|
29
|
+
logger.warn "Signal #{sig} not supported"
|
30
|
+
end
|
31
|
+
|
32
|
+
launch(self_read)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def parse_options(argv)
|
38
|
+
option_parser.parse!(argv)
|
39
|
+
end
|
40
|
+
|
41
|
+
def option_parser
|
42
|
+
OptionParser.new.tap do |p|
|
43
|
+
p.on "-e", "--env ENV", "Application environment" do |arg|
|
44
|
+
config.env = arg
|
45
|
+
end
|
46
|
+
|
47
|
+
p.on "-i", "--client-id CLIENT_ID", "Client ID" do |arg|
|
48
|
+
config.client_id = arg
|
49
|
+
end
|
50
|
+
|
51
|
+
p.on "-r", "--require [PATH|DIR]", "Location of Rails application with workers or file to require" do |arg|
|
52
|
+
if !File.exist?(arg) ||
|
53
|
+
(File.directory?(arg) && !File.exist?("#{arg}/config/application.rb"))
|
54
|
+
raise ArgumentError, "#{arg} is not a ruby file nor a rails application"
|
55
|
+
else
|
56
|
+
config.require = arg
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
p.on "-s", "--client-secret CLIENT_SECRET", "Client Secret" do |arg|
|
61
|
+
config.client_secret = arg
|
62
|
+
end
|
63
|
+
|
64
|
+
p.on "-u", "--zeebe-url ZEEBE_URL", "Zeebe URL" do |arg|
|
65
|
+
config.zeebe_url = arg
|
66
|
+
end
|
67
|
+
|
68
|
+
p.on "-U", "--zeebe-auth-url ZEEBE_AUTH_URL", "Zeebe Authorization Server URL" do |arg|
|
69
|
+
config.auth_url = arg
|
70
|
+
end
|
71
|
+
|
72
|
+
p.on "-a", "--audience URL", "Zeebe Audience" do |arg|
|
73
|
+
config.audience = arg
|
74
|
+
end
|
75
|
+
|
76
|
+
p.on "-T", "--use-access-token STRING", "Zeebe Audience" do |arg|
|
77
|
+
config.use_access_token = arg.to_s.downcase == 'true'
|
78
|
+
end
|
79
|
+
|
80
|
+
p.on "-t", "--timeout NUM", "Shutdown timeout" do |arg|
|
81
|
+
timeout = Integer(arg)
|
82
|
+
raise ArgumentError, "timeout must be a positive integer" if timeout <= 0
|
83
|
+
config.timeout = timeout
|
84
|
+
end
|
85
|
+
|
86
|
+
# p.on "-v", "--verbose", "Print more verbose output" do |arg|
|
87
|
+
# ::Cloudmuna.logger.level = ::Logger::DEBUG
|
88
|
+
# end
|
89
|
+
|
90
|
+
p.on "-V", "--version", "Print version and exit" do |arg|
|
91
|
+
puts "Cloudmunda #{::Cloudmunda::VERSION}"
|
92
|
+
exit(0)
|
93
|
+
end
|
94
|
+
|
95
|
+
p.banner = "Usage: cloudmunda [options]"
|
96
|
+
p.on_tail "-h", "--help", "Show help" do
|
97
|
+
puts p
|
98
|
+
|
99
|
+
exit(1)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def boot
|
105
|
+
ENV["RACK_ENV"] = ENV["RAILS_ENV"] = config.env
|
106
|
+
|
107
|
+
if File.directory?(config.require)
|
108
|
+
require 'rails'
|
109
|
+
if ::Rails::VERSION::MAJOR < 6
|
110
|
+
raise "Cloudmunda does not supports this version of Rails"
|
111
|
+
else
|
112
|
+
require File.expand_path("#{config.require}/config/environment.rb")
|
113
|
+
Dir[Rails.root.join('app/jobs/**/*.rb')].each { |f| require f }
|
114
|
+
|
115
|
+
logger.info "Booted Rails #{::Rails.version} application in #{config.env} environment"
|
116
|
+
end
|
117
|
+
else
|
118
|
+
require config.require
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def launch(self_read)
|
123
|
+
@launcher = ::Cloudmunda::Launcher.new
|
124
|
+
|
125
|
+
if config.env == "development" && $stdout.tty?
|
126
|
+
logger.info "Starting processing, hit Ctrl-C to stop"
|
127
|
+
end
|
128
|
+
|
129
|
+
begin
|
130
|
+
launcher.start
|
131
|
+
|
132
|
+
while readable_io = IO.select([self_read])
|
133
|
+
signal = readable_io.first[0].gets.strip
|
134
|
+
handle_signal(signal)
|
135
|
+
end
|
136
|
+
rescue Interrupt
|
137
|
+
logger.info "Shutting down"
|
138
|
+
launcher.stop
|
139
|
+
logger.info "Bye!"
|
140
|
+
|
141
|
+
exit(0)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def handle_signal(signal)
|
146
|
+
handler = signal_handlers[signal]
|
147
|
+
if handler
|
148
|
+
handler.call(self)
|
149
|
+
else
|
150
|
+
logger.warn "No signal handler for #{signal}"
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def signal_handlers
|
155
|
+
{
|
156
|
+
"INT" => ->(cli) { raise Interrupt },
|
157
|
+
"TERM" => ->(cli) { raise Interrupt },
|
158
|
+
}
|
159
|
+
end
|
160
|
+
|
161
|
+
def config
|
162
|
+
::Cloudmunda
|
163
|
+
end
|
164
|
+
|
165
|
+
def logger
|
166
|
+
::Cloudmunda.logger
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Cloudmunda
|
2
|
+
module Configuration
|
3
|
+
VALID_OPTIONS_KEYS = %i[env require logger timeout zeebe_url auth_url client_id client_secret audience graphql_url].freeze
|
4
|
+
attr_accessor(*VALID_OPTIONS_KEYS)
|
5
|
+
|
6
|
+
# Sets all configuration options to their default values when this module is extended.
|
7
|
+
def self.extended(base)
|
8
|
+
base.reset
|
9
|
+
end
|
10
|
+
|
11
|
+
def configure
|
12
|
+
yield self
|
13
|
+
end
|
14
|
+
|
15
|
+
def config
|
16
|
+
VALID_OPTIONS_KEYS.inject({}) do |option, key|
|
17
|
+
option.merge!(key => send(key))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Resets all configuration options to the defaults.
|
22
|
+
def reset
|
23
|
+
@env = ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
|
24
|
+
@logger = Logger.new($stdout)
|
25
|
+
@require = "."
|
26
|
+
@timeout = 30
|
27
|
+
@zeebe_url = ENV['ZEEBE_URL']
|
28
|
+
@auth_url = ENV['ZEEBE_AUTHORIZATION_SERVER_URL']
|
29
|
+
@client_id = ENV['ZEEBE_CLIENT_ID']
|
30
|
+
@client_secret = ENV['ZEEBE_CLIENT_SECRET']
|
31
|
+
@audience = ENV['ZEEBE_AUDIENCE']
|
32
|
+
@graphql_url = ENV['GRAPHQL_URL']
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rest-client'
|
4
|
+
require 'json'
|
5
|
+
require 'uri'
|
6
|
+
require 'base64'
|
7
|
+
|
8
|
+
module Cloudmunda
|
9
|
+
module Graphql
|
10
|
+
class Client
|
11
|
+
def self.post(params = {})
|
12
|
+
response = RestClient.post(Cloudmunda.graphql_url, params.to_json, headers.merge(content_headers))
|
13
|
+
JSON.parse(response.body)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.headers
|
17
|
+
{
|
18
|
+
authorization: "Bearer " + Cloudmunda::API::AccessToken.create(audience_url: 'tasklist.camunda.io').access_token
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.content_headers
|
23
|
+
{
|
24
|
+
'Content-Type': 'application/json'
|
25
|
+
}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cloudmunda
|
4
|
+
module Graphql
|
5
|
+
class UserTasks
|
6
|
+
def self.all
|
7
|
+
query = "{
|
8
|
+
tasks(query: { state: CREATED })
|
9
|
+
{
|
10
|
+
id
|
11
|
+
taskDefinitionId
|
12
|
+
name
|
13
|
+
taskState
|
14
|
+
assignee
|
15
|
+
taskState
|
16
|
+
isFirst
|
17
|
+
formKey
|
18
|
+
processDefinitionId
|
19
|
+
completionTime
|
20
|
+
processName
|
21
|
+
variables {
|
22
|
+
name
|
23
|
+
value
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}"
|
27
|
+
Cloudmunda::Graphql::Client.post(query: query)['data']['tasks']
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.run_mutation(mutation)
|
31
|
+
Cloudmunda::Graphql::Client.post(query: mutation)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/cloudmunda/version.rb
CHANGED
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'zeebe/client'
|
2
|
+
|
3
|
+
module Cloudmunda
|
4
|
+
module Zeebe
|
5
|
+
class Client
|
6
|
+
|
7
|
+
attr_reader :client
|
8
|
+
|
9
|
+
def initialize(url: ::Cloudmunda.zeebe_url)
|
10
|
+
@client = ::Zeebe::Client::GatewayProtocol::Gateway::Stub.new(url, authentication_headers)
|
11
|
+
end
|
12
|
+
|
13
|
+
def activate_jobs(params = {})
|
14
|
+
run(:activate_jobs,
|
15
|
+
::Zeebe::Client::GatewayProtocol::ActivateJobsRequest.new(params)
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
def cancel_workflow_instance(params = {})
|
20
|
+
run(:cancel_workflow_instance,
|
21
|
+
::Zeebe::Client::GatewayProtocol::CancelWorkflowInstanceRequest.new(params)
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
def complete_job(params = {})
|
26
|
+
run(:complete_job,
|
27
|
+
::Zeebe::Client::GatewayProtocol::CompleteJobRequest.new(params)
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_process_instance(params = {})
|
32
|
+
run(:create_process_instance,
|
33
|
+
::Zeebe::Client::GatewayProtocol::CreateProcessInstanceRequest.new(params)
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
def deploy_process(params = {})
|
38
|
+
run(:deploy_process,
|
39
|
+
::Zeebe::Client::GatewayProtocol::DeployProcessRequest.new(params)
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def fail_job(params = {})
|
44
|
+
run(:fail_job,
|
45
|
+
::Zeebe::Client::GatewayProtocol::FailJobRequest.new(params)
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
def throw_error(params = {})
|
50
|
+
run(:throw_error,
|
51
|
+
::Zeebe::Client::GatewayProtocol::ThrowErrorRequest.new(params)
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
def publish_message(params = {})
|
56
|
+
run(:publish_message,
|
57
|
+
::Zeebe::Client::GatewayProtocol::PublishMessageRequest.new(params)
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
def resolve_incident(params = {})
|
62
|
+
run(:resolve_incident,
|
63
|
+
::Zeebe::Client::GatewayProtocol::ResolveIncidentRequest.new(params)
|
64
|
+
)
|
65
|
+
end
|
66
|
+
|
67
|
+
def set_variables(params = {})
|
68
|
+
run(:set_variables,
|
69
|
+
::Zeebe::Client::GatewayProtocol::SetVariablesRequest.new(params)
|
70
|
+
)
|
71
|
+
end
|
72
|
+
|
73
|
+
def topology(params = {})
|
74
|
+
run(:topology,
|
75
|
+
::Zeebe::Client::GatewayProtocol::TopologyRequest.new(params)
|
76
|
+
)
|
77
|
+
end
|
78
|
+
|
79
|
+
def update_job_retries(params = {})
|
80
|
+
run(:update_job_retries,
|
81
|
+
::Zeebe::Client::GatewayProtocol::UpdateJobRetriesRequest.new(params)
|
82
|
+
)
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def run(method, params = {})
|
88
|
+
client.public_send(method, params)
|
89
|
+
rescue ::GRPC::Unavailable => exception
|
90
|
+
logger.error exception.message
|
91
|
+
raise exception
|
92
|
+
end
|
93
|
+
|
94
|
+
def logger
|
95
|
+
# ::Cloudmunda.logger
|
96
|
+
end
|
97
|
+
|
98
|
+
def authentication_headers
|
99
|
+
token = Cloudmunda::API::AccessToken.create
|
100
|
+
channel_creds = GRPC::Core::ChannelCredentials.new()
|
101
|
+
auth_proc = proc { { 'authorization' => "Bearer #{token.access_token}" } }
|
102
|
+
call_creds = GRPC::Core::CallCredentials.new(auth_proc)
|
103
|
+
channel_creds.compose(call_creds)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'zeebe/client'
|
data/lib/cloudmunda.rb
CHANGED
@@ -1,8 +1,28 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'concurrent'
|
4
|
+
|
3
5
|
require_relative "cloudmunda/version"
|
6
|
+
require_relative 'cloudmunda/loggable'
|
7
|
+
require_relative 'cloudmunda/cli/worker'
|
8
|
+
require_relative 'cloudmunda/configuration'
|
9
|
+
require_relative 'cloudmunda/api'
|
10
|
+
require_relative 'cloudmunda/zeebe'
|
11
|
+
require_relative 'cloudmunda/graphql'
|
4
12
|
|
5
13
|
module Cloudmunda
|
6
|
-
|
7
|
-
|
14
|
+
extend Configuration
|
15
|
+
extend Loggable
|
16
|
+
|
17
|
+
def self.client
|
18
|
+
@client ||= ::Cloudmunda::Zeebe::Client.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.register_worker(worker)
|
22
|
+
self.workers << worker
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.workers
|
26
|
+
@workers ||= []
|
27
|
+
end
|
8
28
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudmunda
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lien Van Den Steen
|
@@ -9,11 +9,54 @@ autorequire:
|
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
11
|
date: 2021-12-16 00:00:00.000000000 Z
|
12
|
-
dependencies:
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rest-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: zeebe-client
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.16'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.16'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: concurrent-ruby
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.0'
|
13
55
|
description: Ruby wrapper for Camunda Cloud
|
14
56
|
email:
|
15
57
|
- lienvandensteen@gmail.com
|
16
|
-
executables:
|
58
|
+
executables:
|
59
|
+
- cloudmunda
|
17
60
|
extensions: []
|
18
61
|
extra_rdoc_files: []
|
19
62
|
files:
|
@@ -28,8 +71,25 @@ files:
|
|
28
71
|
- Rakefile
|
29
72
|
- bin/console
|
30
73
|
- bin/setup
|
74
|
+
- exe/cloudmunda
|
31
75
|
- lib/cloudmunda.rb
|
76
|
+
- lib/cloudmunda/api.rb
|
77
|
+
- lib/cloudmunda/api/access_token.rb
|
78
|
+
- lib/cloudmunda/api/client.rb
|
79
|
+
- lib/cloudmunda/api/o_auth_resource.rb
|
80
|
+
- lib/cloudmunda/cli.rb
|
81
|
+
- lib/cloudmunda/cli/launcher.rb
|
82
|
+
- lib/cloudmunda/cli/processor.rb
|
83
|
+
- lib/cloudmunda/cli/supervisor.rb
|
84
|
+
- lib/cloudmunda/cli/worker.rb
|
85
|
+
- lib/cloudmunda/configuration.rb
|
86
|
+
- lib/cloudmunda/graphql.rb
|
87
|
+
- lib/cloudmunda/graphql/client.rb
|
88
|
+
- lib/cloudmunda/graphql/user_tasks.rb
|
89
|
+
- lib/cloudmunda/loggable.rb
|
32
90
|
- lib/cloudmunda/version.rb
|
91
|
+
- lib/cloudmunda/zeebe.rb
|
92
|
+
- lib/cloudmunda/zeebe/client.rb
|
33
93
|
homepage: https://github.com/lienvdsteen/cloudmunda
|
34
94
|
licenses:
|
35
95
|
- MIT
|