cloudmunda 0.1.0 → 0.1.3
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/.rubocop.yml +5 -7
- data/.rubocop_todo.yml +39 -0
- data/CHANGELOG.md +13 -1
- data/Gemfile +5 -6
- data/Gemfile.lock +153 -1
- data/README.md +173 -4
- data/Rakefile +3 -3
- data/bin/console +3 -3
- data/diagrams/demo.bpmn +47 -0
- data/exe/cloudmunda +17 -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 +15 -0
- data/lib/cloudmunda/api.rb +5 -0
- data/lib/cloudmunda/cli/launcher.rb +36 -0
- data/lib/cloudmunda/cli/processor.rb +110 -0
- data/lib/cloudmunda/cli/supervisor.rb +45 -0
- data/lib/cloudmunda/cli/worker.rb +186 -0
- data/lib/cloudmunda/cli.rb +168 -0
- data/lib/cloudmunda/configuration.rb +38 -0
- data/lib/cloudmunda/graphql/client.rb +30 -0
- data/lib/cloudmunda/graphql/user_tasks.rb +35 -0
- data/lib/cloudmunda/graphql.rb +4 -0
- data/lib/cloudmunda/loggable.rb +17 -0
- data/lib/cloudmunda/version.rb +1 -1
- data/lib/cloudmunda/zeebe/client.rb +96 -0
- data/lib/cloudmunda/zeebe.rb +3 -0
- data/lib/cloudmunda.rb +23 -3
- metadata +67 -8
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'supervisor'
|
4
|
+
|
5
|
+
module Cloudmunda
|
6
|
+
class Launcher
|
7
|
+
attr_reader :supervisor
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@supervisor = ::Cloudmunda::Supervisor.new
|
11
|
+
end
|
12
|
+
|
13
|
+
# Starts the supervisor and job processors.
|
14
|
+
def start
|
15
|
+
supervisor.start
|
16
|
+
end
|
17
|
+
|
18
|
+
# Tells the supervisor to stop processing any more jobs.
|
19
|
+
def quiet
|
20
|
+
supervisor.quiet
|
21
|
+
end
|
22
|
+
|
23
|
+
# Tells the supervisor to stop job processors. This method blocks until
|
24
|
+
# all processors are complete and stopped. It can take up to configurable
|
25
|
+
# timeout.
|
26
|
+
def stop
|
27
|
+
supervisor.stop
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def client
|
33
|
+
::Cloudmunda.client
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cloudmunda
|
4
|
+
class Processor
|
5
|
+
attr_reader :client, :worker_class, :busy_count, :timer
|
6
|
+
|
7
|
+
def initialize(worker_class:, client: ::Cloudmunda.client)
|
8
|
+
@client = client
|
9
|
+
@worker_class = worker_class
|
10
|
+
@busy_count = ::Concurrent::AtomicFixnum.new(0)
|
11
|
+
@timer = ::Concurrent::TimerTask.new(
|
12
|
+
run_now: true,
|
13
|
+
execution_interval: worker_poll_interval,
|
14
|
+
timeout_interval: worker_timeout
|
15
|
+
) { run }
|
16
|
+
end
|
17
|
+
|
18
|
+
def start
|
19
|
+
timer.execute
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def stop
|
24
|
+
timer.shutdown
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def should_activate_jobs?
|
29
|
+
busy_count.value <= worker_max_jobs_to_activate
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def run
|
35
|
+
fetch if should_activate_jobs?
|
36
|
+
end
|
37
|
+
|
38
|
+
def fetch
|
39
|
+
activate_jobs_request.each do |response|
|
40
|
+
busy_count.increment(response.jobs.count)
|
41
|
+
response.jobs.each do |job|
|
42
|
+
::Concurrent::Future.execute do
|
43
|
+
process(job)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def process(job)
|
50
|
+
worker = worker_class.new(client)
|
51
|
+
begin
|
52
|
+
logger.info "class=#{worker_class} jid=#{job.key} Start processing #{job.type}"
|
53
|
+
|
54
|
+
worker.process(job)
|
55
|
+
worker.complete_job(job)
|
56
|
+
|
57
|
+
logger.info "class=#{worker_class} jid=#{job.key} Done processing #{job.type}"
|
58
|
+
rescue StandardError => e
|
59
|
+
logger.info "class=#{worker_class} jid=#{job.key} Failed processing #{job.type}: #{e.message}"
|
60
|
+
|
61
|
+
worker.fail_job(job, reason: e.message)
|
62
|
+
raise e
|
63
|
+
ensure
|
64
|
+
busy_count.decrement
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def activate_jobs_request
|
69
|
+
client.activate_jobs(
|
70
|
+
type: worker_type,
|
71
|
+
worker: worker_name,
|
72
|
+
timeout: worker_timeout * 1000,
|
73
|
+
maxJobsToActivate: max_jobs_to_activate,
|
74
|
+
fetchVariable: worker_variables_to_fetch
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
def worker_type
|
79
|
+
worker_class.get_type
|
80
|
+
end
|
81
|
+
|
82
|
+
def worker_name
|
83
|
+
worker_class.get_name
|
84
|
+
end
|
85
|
+
|
86
|
+
def worker_max_jobs_to_activate
|
87
|
+
worker_class.get_max_jobs_to_activate
|
88
|
+
end
|
89
|
+
|
90
|
+
def worker_timeout
|
91
|
+
worker_class.get_timeout
|
92
|
+
end
|
93
|
+
|
94
|
+
def worker_variables_to_fetch
|
95
|
+
worker_class.get_variables_to_fetch
|
96
|
+
end
|
97
|
+
|
98
|
+
def worker_poll_interval
|
99
|
+
worker_class.get_poll_interval
|
100
|
+
end
|
101
|
+
|
102
|
+
def max_jobs_to_activate
|
103
|
+
worker_max_jobs_to_activate - busy_count.value
|
104
|
+
end
|
105
|
+
|
106
|
+
def logger
|
107
|
+
::Cloudmunda.logger
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'processor'
|
4
|
+
|
5
|
+
module Cloudmunda
|
6
|
+
class Supervisor
|
7
|
+
def initialize
|
8
|
+
@processors = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def start
|
12
|
+
workers.each do |worker_class|
|
13
|
+
if ::Cloudmunda.env == 'development' && !worker_class.get_runs_in_development
|
14
|
+
logger.info "Not starting a processor for worker #{worker_class.get_type} as it doesn't run in development."
|
15
|
+
next
|
16
|
+
end
|
17
|
+
|
18
|
+
logger.info "Starting a processor for worker #{worker_class.get_type}"
|
19
|
+
processor = ::Cloudmunda::Processor.new(worker_class: worker_class)
|
20
|
+
@processors << processor.start
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def quiet
|
25
|
+
logger.info 'Terminating workers'
|
26
|
+
@processors.each(&:stop)
|
27
|
+
end
|
28
|
+
|
29
|
+
def stop(timeout: ::Cloudmunda.timeout)
|
30
|
+
quiet
|
31
|
+
logger.info "Pausing #{timeout}s to allow workers to finish..."
|
32
|
+
sleep timeout
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def workers
|
38
|
+
::Cloudmunda.workers.to_a
|
39
|
+
end
|
40
|
+
|
41
|
+
def logger
|
42
|
+
::Cloudmunda.logger
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,186 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Cloudmunda
|
6
|
+
module Worker
|
7
|
+
attr_accessor :client, :type, :max_jobs_to_activate, :poll_interval, :timeout, :variables, :runs_in_development
|
8
|
+
|
9
|
+
def self.included(base)
|
10
|
+
base.extend(ClassMethods)
|
11
|
+
Cloudmunda.register_worker(base)
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(client)
|
15
|
+
@client = client
|
16
|
+
end
|
17
|
+
|
18
|
+
def complete_job(job, variables: {})
|
19
|
+
logger.info "Completed processing job #{job.type} #{job.key}"
|
20
|
+
client.complete_job(
|
21
|
+
jobKey: job.key,
|
22
|
+
variables: Hash(variables).to_json
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
def fail_job(job, reason: '')
|
27
|
+
logger.error "Failed processing job #{job.type} #{job.key}: #{reason}"
|
28
|
+
client.fail_job(
|
29
|
+
jobKey: job.key,
|
30
|
+
retries: job.retries - 1,
|
31
|
+
errorMessage: reason
|
32
|
+
)
|
33
|
+
rescue StandardError => e
|
34
|
+
logger.error e.message
|
35
|
+
end
|
36
|
+
|
37
|
+
def logger
|
38
|
+
::Cloudmunda.logger
|
39
|
+
end
|
40
|
+
|
41
|
+
module ClassMethods
|
42
|
+
# Sets the type of service task the worker should subscribe to.
|
43
|
+
#
|
44
|
+
# @example
|
45
|
+
# class MyWorker
|
46
|
+
# include ::Cloudmunda::Worker
|
47
|
+
# type "some-service-task-type"
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# @param [String] type
|
51
|
+
# @return [String]
|
52
|
+
def type(type)
|
53
|
+
@type = type
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns the type of service task the worker should subscribe to.
|
57
|
+
#
|
58
|
+
# @return [String]
|
59
|
+
def get_type
|
60
|
+
@type
|
61
|
+
end
|
62
|
+
|
63
|
+
# Sets the maximum number of jobs to send to the worker for processing at once.
|
64
|
+
# As jobs get completed by the worker, more jobs will be sent to the worker
|
65
|
+
# but always within this limit.
|
66
|
+
#
|
67
|
+
# @example
|
68
|
+
# class MyWorker
|
69
|
+
# include ::Cloudmunda::Worker
|
70
|
+
# max_jobs_to_activate 5
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
# @param [Integer] max_jobs_to_activate
|
74
|
+
# @return [Integer]
|
75
|
+
def max_jobs_to_activate(max_jobs_to_activate)
|
76
|
+
@max_jobs_to_activate = max_jobs_to_activate
|
77
|
+
end
|
78
|
+
|
79
|
+
# Returns the maximum number of jobs to send to the worker for processing at once.
|
80
|
+
# As jobs get completed by the worker, more jobs will be sent to the worker
|
81
|
+
# but always within this limit.
|
82
|
+
#
|
83
|
+
# @return [Integer]
|
84
|
+
def get_max_jobs_to_activate
|
85
|
+
@max_jobs_to_activate || 1
|
86
|
+
end
|
87
|
+
|
88
|
+
# Sets the interval duration in seconds between polls to the broker.
|
89
|
+
#
|
90
|
+
# @example
|
91
|
+
# class MyWorker
|
92
|
+
# include ::Cloudmunda::Worker
|
93
|
+
# poll_interval 5
|
94
|
+
# end
|
95
|
+
#
|
96
|
+
# @param [Integer] poll_interval
|
97
|
+
# @return [Integer]
|
98
|
+
def poll_interval(poll_interval)
|
99
|
+
@poll_interval = poll_interval
|
100
|
+
end
|
101
|
+
|
102
|
+
# Returns the interval duration in seconds between polls to the broker.
|
103
|
+
#
|
104
|
+
# @return [Integer]
|
105
|
+
def get_poll_interval
|
106
|
+
@poll_interval || 5
|
107
|
+
end
|
108
|
+
|
109
|
+
# Sets the time in seconds the worker has to process the job before
|
110
|
+
# the broker consider it as expired and can schedule it to another worker.
|
111
|
+
#
|
112
|
+
# @example
|
113
|
+
# class MyWorker
|
114
|
+
# include ::Cloudmunda::Worker
|
115
|
+
# timeout 30
|
116
|
+
# end
|
117
|
+
#
|
118
|
+
# @param [Integer] timeout
|
119
|
+
# @return [Integer]
|
120
|
+
def timeout(timeout)
|
121
|
+
@timeout = timeout
|
122
|
+
end
|
123
|
+
|
124
|
+
# Returns the time in seconds the worker has to process the job before
|
125
|
+
# the broker consider it as expired and can schedule it to another worker.
|
126
|
+
#
|
127
|
+
# @return [Integer]
|
128
|
+
def get_timeout
|
129
|
+
@timeout || 30
|
130
|
+
end
|
131
|
+
|
132
|
+
# Sets the worker's variables to fetch from the broker when polling for new
|
133
|
+
# jobs.
|
134
|
+
#
|
135
|
+
# @example
|
136
|
+
# class MyWorker
|
137
|
+
# include ::Cloudmunda::Worker
|
138
|
+
# variables [:foo, :bar]
|
139
|
+
# end
|
140
|
+
#
|
141
|
+
# @param [Array<String, Symbol>] variables
|
142
|
+
# @return [Array<String, Symbol>]
|
143
|
+
def variables(variables)
|
144
|
+
@variables = variables
|
145
|
+
end
|
146
|
+
|
147
|
+
# Returns the worker's variables to fetch from the broker when polling for new
|
148
|
+
# jobs.
|
149
|
+
#
|
150
|
+
# @return [Array<String, Symbol>]
|
151
|
+
def get_variables_to_fetch
|
152
|
+
@variables.to_a
|
153
|
+
end
|
154
|
+
|
155
|
+
# Sets if this service task runs in development mode or not.
|
156
|
+
#
|
157
|
+
# @example
|
158
|
+
# class MyWorker
|
159
|
+
# include ::Cloudmunda::Worker
|
160
|
+
# runs_in_development true
|
161
|
+
# end
|
162
|
+
#
|
163
|
+
# @param [Boolean] runs_in_development
|
164
|
+
# @return [Boolean]
|
165
|
+
def runs_in_development(runs_in_development)
|
166
|
+
@runs_in_development = runs_in_development
|
167
|
+
end
|
168
|
+
|
169
|
+
# Returns if this service task should run in development mode.
|
170
|
+
#
|
171
|
+
# @return [Boolean]
|
172
|
+
def get_runs_in_development
|
173
|
+
@runs_in_development || false
|
174
|
+
end
|
175
|
+
|
176
|
+
# Returns the worker's name.
|
177
|
+
#
|
178
|
+
# @return [String]
|
179
|
+
def get_name
|
180
|
+
name = self.name.gsub(/::/, ':')
|
181
|
+
name.gsub!(/([^A-Z:])([A-Z])/) { "#{Regexp.last_match(1)}_#{Regexp.last_match(2)}" }
|
182
|
+
name.downcase
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'singleton'
|
4
|
+
require 'optparse'
|
5
|
+
require 'fileutils'
|
6
|
+
require 'cloudmunda'
|
7
|
+
require 'cloudmunda/cli/launcher'
|
8
|
+
|
9
|
+
$stdout.sync = true
|
10
|
+
|
11
|
+
module Cloudmunda
|
12
|
+
class CLI
|
13
|
+
include Singleton
|
14
|
+
|
15
|
+
attr_accessor :launcher
|
16
|
+
|
17
|
+
def parse(argv = ARGV)
|
18
|
+
parse_options(argv)
|
19
|
+
end
|
20
|
+
|
21
|
+
def run
|
22
|
+
boot
|
23
|
+
|
24
|
+
self_read, self_write = IO.pipe
|
25
|
+
sigs = %w[INT TERM]
|
26
|
+
sigs.each do |sig|
|
27
|
+
trap sig do
|
28
|
+
self_write.write("#{sig}\n")
|
29
|
+
end
|
30
|
+
rescue ArgumentError
|
31
|
+
logger.warn "Signal #{sig} not supported"
|
32
|
+
end
|
33
|
+
|
34
|
+
launch(self_read)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def parse_options(argv)
|
40
|
+
option_parser.parse!(argv)
|
41
|
+
end
|
42
|
+
|
43
|
+
def option_parser
|
44
|
+
OptionParser.new.tap do |p|
|
45
|
+
p.on '-e', '--env ENV', 'Application environment' do |arg|
|
46
|
+
config.env = arg
|
47
|
+
end
|
48
|
+
|
49
|
+
p.on '-i', '--client-id CLIENT_ID', 'Client ID' do |arg|
|
50
|
+
config.client_id = arg
|
51
|
+
end
|
52
|
+
|
53
|
+
p.on '-r', '--require [PATH|DIR]', 'Location of Rails application with workers or file to require' do |arg|
|
54
|
+
if !File.exist?(arg) ||
|
55
|
+
(File.directory?(arg) && !File.exist?("#{arg}/config/application.rb"))
|
56
|
+
raise ArgumentError, "#{arg} is not a ruby file nor a rails application"
|
57
|
+
else
|
58
|
+
config.require = arg
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
p.on '-s', '--client-secret CLIENT_SECRET', 'Client Secret' do |arg|
|
63
|
+
config.client_secret = arg
|
64
|
+
end
|
65
|
+
|
66
|
+
p.on '-u', '--zeebe-url ZEEBE_URL', 'Zeebe URL' do |arg|
|
67
|
+
config.zeebe_url = arg
|
68
|
+
end
|
69
|
+
|
70
|
+
p.on '-U', '--zeebe-auth-url ZEEBE_AUTH_URL', 'Zeebe Authorization Server URL' do |arg|
|
71
|
+
config.auth_url = arg
|
72
|
+
end
|
73
|
+
|
74
|
+
p.on '-a', '--audience URL', 'Zeebe Audience' do |arg|
|
75
|
+
config.audience = arg
|
76
|
+
end
|
77
|
+
|
78
|
+
p.on '-T', '--use-access-token STRING', 'Zeebe Audience' do |arg|
|
79
|
+
config.use_access_token = arg.to_s.downcase == 'true'
|
80
|
+
end
|
81
|
+
|
82
|
+
p.on '-t', '--timeout NUM', 'Shutdown timeout' do |arg|
|
83
|
+
timeout = Integer(arg)
|
84
|
+
raise ArgumentError, 'timeout must be a positive integer' if timeout <= 0
|
85
|
+
|
86
|
+
config.timeout = timeout
|
87
|
+
end
|
88
|
+
|
89
|
+
# p.on "-v", "--verbose", "Print more verbose output" do |arg|
|
90
|
+
# ::Cloudmuna.logger.level = ::Logger::DEBUG
|
91
|
+
# end
|
92
|
+
|
93
|
+
p.on '-V', '--version', 'Print version and exit' do |_arg|
|
94
|
+
puts "Cloudmunda #{::Cloudmunda::VERSION}"
|
95
|
+
exit(0)
|
96
|
+
end
|
97
|
+
|
98
|
+
p.banner = 'Usage: cloudmunda [options]'
|
99
|
+
p.on_tail '-h', '--help', 'Show help' do
|
100
|
+
puts p
|
101
|
+
|
102
|
+
exit(1)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def boot
|
108
|
+
ENV['RACK_ENV'] = ENV['RAILS_ENV'] = config.env
|
109
|
+
|
110
|
+
if File.directory?(config.require)
|
111
|
+
require 'rails'
|
112
|
+
raise 'Cloudmunda does not supports this version of Rails' if ::Rails::VERSION::MAJOR < 6
|
113
|
+
|
114
|
+
require File.expand_path("#{config.require}/config/environment.rb")
|
115
|
+
Dir[Rails.root.join('app/jobs/**/*.rb')].sort.each { |f| require f }
|
116
|
+
|
117
|
+
logger.info "Booted Rails #{::Rails.version} application in #{config.env} environment"
|
118
|
+
else
|
119
|
+
require config.require
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def launch(self_read)
|
124
|
+
@launcher = ::Cloudmunda::Launcher.new
|
125
|
+
|
126
|
+
logger.info 'Starting processing, hit Ctrl-C to stop' if config.env == 'development' && $stdout.tty?
|
127
|
+
|
128
|
+
begin
|
129
|
+
launcher.start
|
130
|
+
|
131
|
+
while (readable_io = IO.select([self_read]))
|
132
|
+
signal = readable_io.first[0].gets.strip
|
133
|
+
handle_signal(signal)
|
134
|
+
end
|
135
|
+
rescue Interrupt
|
136
|
+
logger.info 'Shutting down'
|
137
|
+
launcher.stop
|
138
|
+
logger.info 'Bye!'
|
139
|
+
|
140
|
+
exit(0)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def handle_signal(signal)
|
145
|
+
handler = signal_handlers[signal]
|
146
|
+
if handler
|
147
|
+
handler.call(self)
|
148
|
+
else
|
149
|
+
logger.warn "No signal handler for #{signal}"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def signal_handlers
|
154
|
+
{
|
155
|
+
'INT' => ->(_cli) { raise Interrupt },
|
156
|
+
'TERM' => ->(_cli) { raise Interrupt }
|
157
|
+
}
|
158
|
+
end
|
159
|
+
|
160
|
+
def config
|
161
|
+
::Cloudmunda
|
162
|
+
end
|
163
|
+
|
164
|
+
def logger
|
165
|
+
::Cloudmunda.logger
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cloudmunda
|
4
|
+
module Configuration
|
5
|
+
VALID_OPTIONS_KEYS = %i[env require logger timeout zeebe_url auth_url client_id client_secret audience
|
6
|
+
graphql_url].freeze
|
7
|
+
attr_accessor(*VALID_OPTIONS_KEYS)
|
8
|
+
|
9
|
+
# Sets all configuration options to their default values when this module is extended.
|
10
|
+
def self.extended(base)
|
11
|
+
base.reset
|
12
|
+
end
|
13
|
+
|
14
|
+
def configure
|
15
|
+
yield self
|
16
|
+
end
|
17
|
+
|
18
|
+
def config
|
19
|
+
VALID_OPTIONS_KEYS.inject({}) do |option, key|
|
20
|
+
option.merge!(key => send(key))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Resets all configuration options to the defaults.
|
25
|
+
def reset
|
26
|
+
@env = ENV['APP_ENV'] || ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
|
27
|
+
@logger = Logger.new($stdout)
|
28
|
+
@require = '.'
|
29
|
+
@timeout = @env == 'development' ? 5 : 30
|
30
|
+
@zeebe_url = ENV['ZEEBE_URL']
|
31
|
+
@auth_url = ENV['ZEEBE_AUTHORIZATION_SERVER_URL']
|
32
|
+
@client_id = ENV['ZEEBE_CLIENT_ID']
|
33
|
+
@client_secret = ENV['ZEEBE_CLIENT_SECRET']
|
34
|
+
@audience = ENV['ZEEBE_AUDIENCE']
|
35
|
+
@graphql_url = ENV['GRAPHQL_URL']
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,30 @@
|
|
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
|
+
access_token = Cloudmunda::API::AccessToken.create(audience_url: 'tasklist.camunda.io').access_token
|
18
|
+
{
|
19
|
+
authorization: "Bearer #{access_token}"
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.content_headers
|
24
|
+
{
|
25
|
+
'Content-Type': 'application/json'
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
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