operaton-bpm-client 0.1.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.
Files changed (92) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +134 -0
  3. data/lib/operaton/bpm/client/backoff/backoff_strategy.rb +20 -0
  4. data/lib/operaton/bpm/client/backoff/error_aware_backoff_strategy.rb +22 -0
  5. data/lib/operaton/bpm/client/backoff/exponential_backoff_strategy.rb +38 -0
  6. data/lib/operaton/bpm/client/backoff/exponential_error_backoff_strategy.rb +38 -0
  7. data/lib/operaton/bpm/client/exceptions.rb +74 -0
  8. data/lib/operaton/bpm/client/external_task_client.rb +20 -0
  9. data/lib/operaton/bpm/client/external_task_client_builder.rb +18 -0
  10. data/lib/operaton/bpm/client/impl/engine_client.rb +132 -0
  11. data/lib/operaton/bpm/client/impl/engine_client_exception.rb +25 -0
  12. data/lib/operaton/bpm/client/impl/engine_client_logger.rb +54 -0
  13. data/lib/operaton/bpm/client/impl/engine_rest_exception_dto.rb +28 -0
  14. data/lib/operaton/bpm/client/impl/external_task_client_builder_impl.rb +349 -0
  15. data/lib/operaton/bpm/client/impl/external_task_client_impl.rb +41 -0
  16. data/lib/operaton/bpm/client/impl/external_task_client_logger.rb +236 -0
  17. data/lib/operaton/bpm/client/impl/object_mapper.rb +44 -0
  18. data/lib/operaton/bpm/client/impl/permanent_url_resolver.rb +22 -0
  19. data/lib/operaton/bpm/client/impl/request_dto.rb +24 -0
  20. data/lib/operaton/bpm/client/impl/request_executor.rb +143 -0
  21. data/lib/operaton/bpm/client/interceptor/auth/basic_auth_provider.rb +42 -0
  22. data/lib/operaton/bpm/client/interceptor/client_request_context.rb +16 -0
  23. data/lib/operaton/bpm/client/interceptor/client_request_interceptor.rb +18 -0
  24. data/lib/operaton/bpm/client/interceptor/impl/client_request_context_impl.rb +28 -0
  25. data/lib/operaton/bpm/client/interceptor/impl/request_interceptor_handler.rb +43 -0
  26. data/lib/operaton/bpm/client/spi/data_format.rb +32 -0
  27. data/lib/operaton/bpm/client/spi/data_format_configurator.rb +31 -0
  28. data/lib/operaton/bpm/client/spi/data_format_provider.rb +31 -0
  29. data/lib/operaton/bpm/client/task/external_task.rb +22 -0
  30. data/lib/operaton/bpm/client/task/external_task_handler.rb +28 -0
  31. data/lib/operaton/bpm/client/task/external_task_service.rb +18 -0
  32. data/lib/operaton/bpm/client/task/impl/dto/bpmn_error_request_dto.rb +35 -0
  33. data/lib/operaton/bpm/client/task/impl/dto/complete_request_dto.rb +33 -0
  34. data/lib/operaton/bpm/client/task/impl/dto/extend_lock_request_dto.rb +29 -0
  35. data/lib/operaton/bpm/client/task/impl/dto/failure_request_dto.rb +43 -0
  36. data/lib/operaton/bpm/client/task/impl/dto/lock_request_dto.rb +29 -0
  37. data/lib/operaton/bpm/client/task/impl/dto/set_variables_request_dto.rb +29 -0
  38. data/lib/operaton/bpm/client/task/impl/external_task_impl.rb +128 -0
  39. data/lib/operaton/bpm/client/task/impl/external_task_service_impl.rb +90 -0
  40. data/lib/operaton/bpm/client/task/ordering_config.rb +78 -0
  41. data/lib/operaton/bpm/client/task/sorting_dto.rb +29 -0
  42. data/lib/operaton/bpm/client/topic/impl/dto/fetch_and_lock_request_dto.rb +47 -0
  43. data/lib/operaton/bpm/client/topic/impl/dto/fetch_and_lock_response_dto.rb +32 -0
  44. data/lib/operaton/bpm/client/topic/impl/dto/topic_request_dto.rb +70 -0
  45. data/lib/operaton/bpm/client/topic/impl/topic_subscription_builder_impl.rb +164 -0
  46. data/lib/operaton/bpm/client/topic/impl/topic_subscription_impl.rb +76 -0
  47. data/lib/operaton/bpm/client/topic/impl/topic_subscription_manager.rb +222 -0
  48. data/lib/operaton/bpm/client/topic/impl/topic_subscription_manager_logger.rb +52 -0
  49. data/lib/operaton/bpm/client/topic/topic_subscription.rb +20 -0
  50. data/lib/operaton/bpm/client/topic/topic_subscription_builder.rb +22 -0
  51. data/lib/operaton/bpm/client/url_resolver.rb +15 -0
  52. data/lib/operaton/bpm/client/variable/client_values.rb +33 -0
  53. data/lib/operaton/bpm/client/variable/impl/abstract_typed_value_mapper.rb +59 -0
  54. data/lib/operaton/bpm/client/variable/impl/default_value_mappers.rb +71 -0
  55. data/lib/operaton/bpm/client/variable/impl/format/json/json_data_format.rb +82 -0
  56. data/lib/operaton/bpm/client/variable/impl/format/json/json_data_format_provider.rb +34 -0
  57. data/lib/operaton/bpm/client/variable/impl/mapper/boolean_value_mapper.rb +35 -0
  58. data/lib/operaton/bpm/client/variable/impl/mapper/byte_array_value_mapper.rb +53 -0
  59. data/lib/operaton/bpm/client/variable/impl/mapper/date_value_mapper.rb +61 -0
  60. data/lib/operaton/bpm/client/variable/impl/mapper/double_value_mapper.rb +36 -0
  61. data/lib/operaton/bpm/client/variable/impl/mapper/file_value_mapper.rb +73 -0
  62. data/lib/operaton/bpm/client/variable/impl/mapper/integer_value_mapper.rb +36 -0
  63. data/lib/operaton/bpm/client/variable/impl/mapper/json_value_mapper.rb +35 -0
  64. data/lib/operaton/bpm/client/variable/impl/mapper/long_value_mapper.rb +36 -0
  65. data/lib/operaton/bpm/client/variable/impl/mapper/null_value_mapper.rb +45 -0
  66. data/lib/operaton/bpm/client/variable/impl/mapper/number_value_mapper.rb +25 -0
  67. data/lib/operaton/bpm/client/variable/impl/mapper/object_value_mapper.rb +151 -0
  68. data/lib/operaton/bpm/client/variable/impl/mapper/primitive_value_mapper.rb +44 -0
  69. data/lib/operaton/bpm/client/variable/impl/mapper/short_value_mapper.rb +36 -0
  70. data/lib/operaton/bpm/client/variable/impl/mapper/string_value_mapper.rb +35 -0
  71. data/lib/operaton/bpm/client/variable/impl/mapper/xml_value_mapper.rb +35 -0
  72. data/lib/operaton/bpm/client/variable/impl/type/json_type_impl.rb +24 -0
  73. data/lib/operaton/bpm/client/variable/impl/type/xml_type_impl.rb +24 -0
  74. data/lib/operaton/bpm/client/variable/impl/typed_value_field.rb +36 -0
  75. data/lib/operaton/bpm/client/variable/impl/typed_values.rb +100 -0
  76. data/lib/operaton/bpm/client/variable/impl/value/deferred_file_value_impl.rb +57 -0
  77. data/lib/operaton/bpm/client/variable/impl/value/json_value_impl.rb +26 -0
  78. data/lib/operaton/bpm/client/variable/impl/value/xml_value_impl.rb +26 -0
  79. data/lib/operaton/bpm/client/variable/impl/value_mapper.rb +42 -0
  80. data/lib/operaton/bpm/client/variable/impl/value_mappers.rb +26 -0
  81. data/lib/operaton/bpm/client/variable/impl/variable_value.rb +55 -0
  82. data/lib/operaton/bpm/client/variable/value/deferred_file_value.rb +19 -0
  83. data/lib/operaton/bpm/client/variable/value/json_value.rb +16 -0
  84. data/lib/operaton/bpm/client/variable/value/xml_value.rb +16 -0
  85. data/lib/operaton/bpm/client/version.rb +9 -0
  86. data/lib/operaton/bpm/client.rb +121 -0
  87. data/lib/operaton/bpm/engine/variable/typed_value.rb +153 -0
  88. data/lib/operaton/bpm/engine/variable/value_type.rb +126 -0
  89. data/lib/operaton/bpm/engine/variable/variable_map.rb +72 -0
  90. data/lib/operaton/bpm/engine/variable/variables.rb +197 -0
  91. data/lib/operaton-bpm-client.rb +3 -0
  92. metadata +188 -0
@@ -0,0 +1,349 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "socket"
4
+ require "securerandom"
5
+
6
+ require_relative "../external_task_client_builder"
7
+ require_relative "external_task_client_logger"
8
+ require_relative "external_task_client_impl"
9
+ require_relative "permanent_url_resolver"
10
+ require_relative "object_mapper"
11
+ require_relative "engine_client"
12
+ require_relative "request_executor"
13
+ require_relative "../backoff/exponential_backoff_strategy"
14
+ require_relative "../interceptor/impl/request_interceptor_handler"
15
+ require_relative "../task/ordering_config"
16
+ require_relative "../topic/impl/topic_subscription_manager"
17
+ require_relative "../spi/data_format_provider"
18
+ require_relative "../spi/data_format_configurator"
19
+ require_relative "../variable/client_values"
20
+ require_relative "../variable/impl/default_value_mappers"
21
+ require_relative "../variable/impl/typed_values"
22
+ require_relative "../variable/impl/mapper/boolean_value_mapper"
23
+ require_relative "../variable/impl/mapper/byte_array_value_mapper"
24
+ require_relative "../variable/impl/mapper/date_value_mapper"
25
+ require_relative "../variable/impl/mapper/double_value_mapper"
26
+ require_relative "../variable/impl/mapper/file_value_mapper"
27
+ require_relative "../variable/impl/mapper/integer_value_mapper"
28
+ require_relative "../variable/impl/mapper/json_value_mapper"
29
+ require_relative "../variable/impl/mapper/long_value_mapper"
30
+ require_relative "../variable/impl/mapper/null_value_mapper"
31
+ require_relative "../variable/impl/mapper/object_value_mapper"
32
+ require_relative "../variable/impl/mapper/short_value_mapper"
33
+ require_relative "../variable/impl/mapper/string_value_mapper"
34
+ require_relative "../variable/impl/mapper/xml_value_mapper"
35
+ require_relative "../variable/impl/format/json/json_data_format_provider"
36
+
37
+ module Operaton
38
+ module Bpm
39
+ module Client
40
+ module Impl
41
+ # Mirrors org.operaton.bpm.client.impl.ExternalTaskClientBuilderImpl
42
+ class ExternalTaskClientBuilderImpl
43
+ include ExternalTaskClientBuilder
44
+
45
+ attr_reader :object_mapper, :value_mappers, :typed_values, :engine_client
46
+
47
+ def initialize
48
+ # default values
49
+ @worker_id = nil
50
+ @max_tasks = 10
51
+ @use_priority = true
52
+ @ordering_config = Task::OrderingConfig.empty
53
+ @async_response_timeout = nil
54
+ @lock_duration = 20_000
55
+ @default_serialization_format = Engine::Variable::Variables::SerializationDataFormats::JSON
56
+ @date_format = ObjectMapper::DEFAULT_DATE_FORMAT
57
+ @interceptors = []
58
+ @is_auto_fetching_enabled = true
59
+ @backoff_strategy = Backoff::ExponentialBackoffStrategy.new
60
+ @is_backoff_strategy_disabled = false
61
+ @http_customizer = nil
62
+ @url_resolver = PermanentUrlResolver.new(nil)
63
+ @object_mapper = nil
64
+ @value_mappers = nil
65
+ @typed_values = nil
66
+ @engine_client = nil
67
+ @topic_subscription_manager = nil
68
+ end
69
+
70
+ def base_url(base_url)
71
+ @url_resolver = PermanentUrlResolver.new(base_url)
72
+ self
73
+ end
74
+
75
+ def url_resolver(url_resolver)
76
+ @url_resolver = url_resolver
77
+ self
78
+ end
79
+
80
+ def worker_id(worker_id)
81
+ @worker_id = worker_id
82
+ self
83
+ end
84
+
85
+ def add_interceptor(interceptor)
86
+ @interceptors << interceptor
87
+ self
88
+ end
89
+
90
+ def max_tasks(max_tasks)
91
+ @max_tasks = max_tasks
92
+ self
93
+ end
94
+
95
+ def use_priority(use_priority)
96
+ @use_priority = use_priority
97
+ self
98
+ end
99
+
100
+ def use_create_time(use_create_time)
101
+ if use_create_time
102
+ @ordering_config.configure_field(Task::OrderingConfig::SortingField::CREATE_TIME)
103
+ @ordering_config.configure_direction_on_last_field(Task::OrderingConfig::Direction::DESC)
104
+ end
105
+ self
106
+ end
107
+
108
+ def order_by_create_time
109
+ @ordering_config.configure_field(Task::OrderingConfig::SortingField::CREATE_TIME)
110
+ self
111
+ end
112
+
113
+ def asc
114
+ @ordering_config.configure_direction_on_last_field(Task::OrderingConfig::Direction::ASC)
115
+ self
116
+ end
117
+
118
+ def desc
119
+ @ordering_config.configure_direction_on_last_field(Task::OrderingConfig::Direction::DESC)
120
+ self
121
+ end
122
+
123
+ def async_response_timeout(async_response_timeout)
124
+ @async_response_timeout = async_response_timeout
125
+ self
126
+ end
127
+
128
+ def lock_duration(lock_duration)
129
+ @lock_duration = lock_duration
130
+ self
131
+ end
132
+
133
+ def disable_auto_fetching
134
+ @is_auto_fetching_enabled = false
135
+ self
136
+ end
137
+
138
+ def backoff_strategy(backoff_strategy)
139
+ @backoff_strategy = backoff_strategy
140
+ self
141
+ end
142
+
143
+ def disable_backoff_strategy
144
+ @is_backoff_strategy_disabled = true
145
+ self
146
+ end
147
+
148
+ def default_serialization_format(default_serialization_format)
149
+ @default_serialization_format = default_serialization_format
150
+ self
151
+ end
152
+
153
+ # A Ruby strftime pattern (default "%Y-%m-%dT%H:%M:%S.%L%z", the
154
+ # equivalent of the Java client's "yyyy-MM-dd'T'HH:mm:ss.SSSZ").
155
+ def date_format(date_format)
156
+ @date_format = date_format
157
+ self
158
+ end
159
+
160
+ # Accepts a block invoked with the Net::HTTP instance of every request.
161
+ def customize_http_client(customizer = nil, &block)
162
+ @http_customizer = customizer || block
163
+ self
164
+ end
165
+
166
+ def build
167
+ raise logger.max_tasks_not_greater_than_zero_exception(@max_tasks) if @max_tasks <= 0
168
+
169
+ if !@async_response_timeout.nil? && @async_response_timeout <= 0
170
+ raise logger.async_response_timeout_not_greater_than_zero_exception(@async_response_timeout)
171
+ end
172
+
173
+ raise logger.lock_duration_is_not_greater_than_zero_exception(@lock_duration) if @lock_duration <= 0
174
+
175
+ raise logger.base_url_null_exception if @url_resolver.nil? || get_base_url.nil? || get_base_url.empty?
176
+
177
+ check_interceptors
178
+ @ordering_config.validate_ordering_properties
179
+
180
+ init_base_url
181
+ init_worker_id
182
+ init_object_mapper
183
+ init_engine_client
184
+ init_variable_mappers
185
+ init_topic_subscription_manager
186
+
187
+ ExternalTaskClientImpl.new(@topic_subscription_manager)
188
+ end
189
+
190
+ def get_base_url # rubocop:disable Naming/AccessorMethodName
191
+ @url_resolver.base_url
192
+ end
193
+
194
+ def get_default_serialization_format # rubocop:disable Naming/AccessorMethodName
195
+ @default_serialization_format
196
+ end
197
+
198
+ def get_date_format # rubocop:disable Naming/AccessorMethodName
199
+ @date_format
200
+ end
201
+
202
+ protected
203
+
204
+ def init_base_url
205
+ @url_resolver.base_url = sanitize_url(@url_resolver.base_url) if @url_resolver.is_a?(PermanentUrlResolver)
206
+ end
207
+
208
+ def sanitize_url(url)
209
+ url.strip.sub(%r{/+\z}, "")
210
+ end
211
+
212
+ def init_worker_id
213
+ return unless @worker_id.nil?
214
+
215
+ hostname = check_hostname
216
+ @worker_id = "#{hostname}#{SecureRandom.uuid}"
217
+ end
218
+
219
+ def check_interceptors
220
+ @interceptors.each do |interceptor|
221
+ raise logger.interceptor_null_exception if interceptor.nil?
222
+ end
223
+ end
224
+
225
+ def init_object_mapper
226
+ @object_mapper = ObjectMapper.new(@date_format)
227
+ end
228
+
229
+ def init_engine_client
230
+ request_interceptor_handler = Interceptor::Impl::RequestInterceptorHandler.new(@interceptors)
231
+ request_executor = RequestExecutor.new(
232
+ @object_mapper,
233
+ interceptor_handler: request_interceptor_handler,
234
+ http_customizer: @http_customizer,
235
+ read_timeout: compute_read_timeout
236
+ )
237
+ @engine_client = EngineClient.new(@worker_id, @max_tasks, @async_response_timeout, @url_resolver,
238
+ request_executor, @use_priority, @ordering_config)
239
+ end
240
+
241
+ def init_variable_mappers
242
+ @value_mappers = Variable::Impl::DefaultValueMappers.new(@default_serialization_format)
243
+
244
+ @value_mappers.add_mapper(Variable::Impl::Mapper::NullValueMapper.new)
245
+ @value_mappers.add_mapper(Variable::Impl::Mapper::BooleanValueMapper.new)
246
+ @value_mappers.add_mapper(Variable::Impl::Mapper::StringValueMapper.new)
247
+ @value_mappers.add_mapper(Variable::Impl::Mapper::DateValueMapper.new(@date_format))
248
+ @value_mappers.add_mapper(Variable::Impl::Mapper::ByteArrayValueMapper.new)
249
+
250
+ # number mappers
251
+ @value_mappers.add_mapper(Variable::Impl::Mapper::IntegerValueMapper.new)
252
+ @value_mappers.add_mapper(Variable::Impl::Mapper::LongValueMapper.new)
253
+ @value_mappers.add_mapper(Variable::Impl::Mapper::ShortValueMapper.new)
254
+ @value_mappers.add_mapper(Variable::Impl::Mapper::DoubleValueMapper.new)
255
+
256
+ # object
257
+ lookup_data_formats.each do |key, format|
258
+ @value_mappers.add_mapper(Variable::Impl::Mapper::ObjectValueMapper.new(key, format))
259
+ end
260
+
261
+ # json/xml
262
+ @value_mappers.add_mapper(Variable::Impl::Mapper::JsonValueMapper.new)
263
+ @value_mappers.add_mapper(Variable::Impl::Mapper::XmlValueMapper.new)
264
+
265
+ # file
266
+ @value_mappers.add_mapper(Variable::Impl::Mapper::FileValueMapper.new(@engine_client))
267
+
268
+ @typed_values = Variable::Impl::TypedValues.new(@value_mappers)
269
+ @engine_client.typed_values = @typed_values
270
+ end
271
+
272
+ def init_topic_subscription_manager
273
+ @topic_subscription_manager = Topic::Impl::TopicSubscriptionManager.new(
274
+ @engine_client, @typed_values, @lock_duration
275
+ )
276
+ @topic_subscription_manager.backoff_strategy = @backoff_strategy
277
+ @topic_subscription_manager.disable_backoff_strategy if @is_backoff_strategy_disabled
278
+ @topic_subscription_manager.start if auto_fetching_enabled?
279
+ end
280
+
281
+ def lookup_data_formats
282
+ data_formats = {}
283
+ lookup_custom_data_formats(data_formats)
284
+ apply_configurators(data_formats)
285
+ data_formats
286
+ end
287
+
288
+ def lookup_custom_data_formats(data_formats)
289
+ Spi::DataFormatProvider.providers.each do |provider|
290
+ logger.log_data_format_provider(provider)
291
+ lookup_provider(data_formats, provider)
292
+ end
293
+ end
294
+
295
+ def lookup_provider(data_formats, provider)
296
+ data_format_name = provider.data_format_name
297
+ raise logger.multiple_providers_for_dataformat(data_format_name) if data_formats.key?(data_format_name)
298
+
299
+ data_format_instance = provider.create_instance
300
+ data_formats[data_format_name] = data_format_instance
301
+ logger.log_data_format(data_format_instance)
302
+ end
303
+
304
+ def apply_configurators(data_formats)
305
+ Spi::DataFormatConfigurator.configurators.each do |configurator|
306
+ logger.log_data_format_configurator(configurator)
307
+ apply_configurator(data_formats, configurator)
308
+ end
309
+ end
310
+
311
+ def apply_configurator(data_formats, configurator)
312
+ data_formats.each_value do |data_format|
313
+ configurator.configure(data_format) if data_format.is_a?(configurator.data_format_class)
314
+ end
315
+ end
316
+
317
+ def check_hostname
318
+ hostname = get_hostname
319
+ raise logger.cannot_get_hostname_exception(nil) if hostname.nil? || hostname.empty?
320
+
321
+ hostname
322
+ rescue StandardError => e
323
+ raise logger.cannot_get_hostname_exception(e)
324
+ end
325
+
326
+ def get_hostname # rubocop:disable Naming/AccessorMethodName
327
+ Socket.gethostname
328
+ end
329
+
330
+ def auto_fetching_enabled?
331
+ @is_auto_fetching_enabled
332
+ end
333
+
334
+ def compute_read_timeout
335
+ if @async_response_timeout
336
+ (@async_response_timeout / 1000.0) + 30
337
+ else
338
+ 60
339
+ end
340
+ end
341
+
342
+ def logger
343
+ ExternalTaskClientLogger.client_logger
344
+ end
345
+ end
346
+ end
347
+ end
348
+ end
349
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../topic/impl/topic_subscription_builder_impl"
4
+
5
+ module Operaton
6
+ module Bpm
7
+ module Client
8
+ module Impl
9
+ # Mirrors org.operaton.bpm.client.impl.ExternalTaskClientImpl
10
+ class ExternalTaskClientImpl
11
+ attr_reader :topic_subscription_manager
12
+
13
+ def initialize(topic_subscription_manager)
14
+ @topic_subscription_manager = topic_subscription_manager
15
+ end
16
+
17
+ # Creates a fluent builder to create and configure a topic subscription.
18
+ def subscribe(topic_name)
19
+ Topic::Impl::TopicSubscriptionBuilderImpl.new(topic_name, topic_subscription_manager)
20
+ end
21
+
22
+ # Stops continuous fetching and locking of tasks.
23
+ def stop
24
+ topic_subscription_manager.stop
25
+ end
26
+
27
+ # Starts continuous fetching and locking of tasks.
28
+ def start
29
+ topic_subscription_manager.start
30
+ end
31
+
32
+ # True while the client is actively fetching tasks.
33
+ def active?
34
+ topic_subscription_manager.running?
35
+ end
36
+ alias is_active? active?
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,236 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "logger"
4
+ require_relative "../exceptions"
5
+
6
+ module Operaton
7
+ module Bpm
8
+ module Client
9
+ class << self
10
+ # Library-wide logger, mirroring the "org.operaton.bpm.client" SLF4J logger.
11
+ attr_writer :logger
12
+
13
+ def logger
14
+ @logger ||= Logger.new($stderr, progname: "org.operaton.bpm.client")
15
+ end
16
+ end
17
+
18
+ module Impl
19
+ # Mirrors org.operaton.bpm.client.impl.ExternalTaskClientLogger
20
+ class ExternalTaskClientLogger
21
+ PROJECT_CODE = "TASK/CLIENT"
22
+
23
+ def self.client_logger
24
+ @client_logger ||= new("01")
25
+ end
26
+
27
+ def self.engine_client_logger
28
+ @engine_client_logger ||= EngineClientLogger.new("02")
29
+ end
30
+
31
+ def self.topic_subscription_manager_logger
32
+ @topic_subscription_manager_logger ||= Topic::Impl::TopicSubscriptionManagerLogger.new("03")
33
+ end
34
+
35
+ def initialize(component_id)
36
+ @component_id = component_id
37
+ end
38
+
39
+ def exception_message(id, message_template, *args)
40
+ "#{PROJECT_CODE}-#{@component_id}#{id} #{format_template(message_template, *args)}"
41
+ end
42
+
43
+ def format_template(template, *args)
44
+ args.reduce(template) { |msg, arg| msg.sub("{}", arg.to_s) }
45
+ end
46
+
47
+ def log_error(id, message_template, error = nil, *args)
48
+ msg = exception_message(id, message_template, *args)
49
+ msg += " : #{error.class}: #{error.message}" if error
50
+ Client.logger.error(msg)
51
+ end
52
+
53
+ def log_info(id, message_template, *args)
54
+ Client.logger.info(exception_message(id, message_template, *args))
55
+ end
56
+
57
+ def log_debug(id, message_template, *args)
58
+ Client.logger.debug(exception_message(id, message_template, *args))
59
+ end
60
+
61
+ def base_url_null_exception
62
+ ExternalTaskClientException.new(exception_message(
63
+ "001", "Base URL cannot be null or an empty string"))
64
+ end
65
+
66
+ def cannot_get_hostname_exception(cause)
67
+ ExternalTaskClientException.new(exception_message("002", "Cannot get hostname"), cause)
68
+ end
69
+
70
+ def double_direction_config_exception
71
+ ExternalTaskClientException.new(
72
+ "Invalid query: can specify only one direction desc() or asc() for an ordering constraint")
73
+ end
74
+
75
+ def unspecified_order_by_method_exception
76
+ ExternalTaskClientException.new(
77
+ "Invalid query: You should call any of the orderBy methods first before specifying a direction")
78
+ end
79
+
80
+ def missing_direction_exception
81
+ ExternalTaskClientException.new(
82
+ "Invalid query: call asc() or desc() after using orderByXX()")
83
+ end
84
+
85
+ def topic_name_null_exception
86
+ ExternalTaskClientException.new(exception_message(
87
+ "003", "Topic name cannot be null"))
88
+ end
89
+
90
+ def lock_duration_is_not_greater_than_zero_exception(lock_duration)
91
+ ExternalTaskClientException.new(exception_message(
92
+ "004", "Lock duration must be greater than 0, but was '{}'", lock_duration))
93
+ end
94
+
95
+ def external_task_handler_null_exception
96
+ ExternalTaskClientException.new(exception_message(
97
+ "005", "External task handler cannot be null"))
98
+ end
99
+
100
+ def topic_name_already_subscribed_exception(topic_name)
101
+ ExternalTaskClientException.new(exception_message(
102
+ "006", "Topic name '{}' has already been subscribed", topic_name))
103
+ end
104
+
105
+ # Mirrors handledEngineClientException: maps EngineClientException
106
+ # causes to the public exception hierarchy.
107
+ def handled_engine_client_exception(action_name, error)
108
+ caused = error.cause
109
+
110
+ if caused.is_a?(RestException)
111
+ message = caused.message
112
+ status = caused.http_status_code
113
+
114
+ return case status
115
+ when 400 then BadRequestException.new(create_message("007", action_name, message), caused)
116
+ when 404 then NotFoundException.new(create_message("008", action_name, message), caused)
117
+ when 500 then EngineException.new(create_message("009", action_name, message), caused)
118
+ else
119
+ UnknownHttpErrorException.new(exception_message(
120
+ "031", "Exception while {}: The request failed with status code {} and message: \"{}\"",
121
+ action_name, status, message), caused)
122
+ end
123
+ end
124
+
125
+ if io_error?(caused)
126
+ return ConnectionLostException.new(exception_message(
127
+ "010", "Exception while {}: Connection could not be established with message: \"{}\"",
128
+ action_name, caused.message), caused)
129
+ end
130
+
131
+ ExternalTaskClientException.new(exception_message(
132
+ "011", "Exception while {}: ", action_name), error)
133
+ end
134
+
135
+ def create_message(id, action_name, message)
136
+ exception_message(id, "Exception while {}: {}", action_name, message)
137
+ end
138
+
139
+ def basic_auth_credentials_null_exception
140
+ ExternalTaskClientException.new(exception_message(
141
+ "012", "Basic authentication credentials (username, password) cannot be null"))
142
+ end
143
+
144
+ def interceptor_null_exception
145
+ ExternalTaskClientException.new(exception_message(
146
+ "013", "Interceptor cannot be null"))
147
+ end
148
+
149
+ def max_tasks_not_greater_than_zero_exception(max_tasks)
150
+ ExternalTaskClientException.new(exception_message(
151
+ "014", "Maximum amount of fetched tasks must be greater than zero, but was '{}'", max_tasks))
152
+ end
153
+
154
+ def async_response_timeout_not_greater_than_zero_exception(async_response_timeout)
155
+ ExternalTaskClientException.new(exception_message(
156
+ "015", "Asynchronous response timeout must be greater than zero, but was '{}'", async_response_timeout))
157
+ end
158
+
159
+ def value_mapper_exception_while_parsing_date(date, error)
160
+ ValueMapperException.new(exception_message(
161
+ "018", "Exception while mapping value: Cannot parse date '{}'", date), error)
162
+ end
163
+
164
+ def value_mapper_exception_due_to_no_object_type_name
165
+ ValueMapperException.new(exception_message(
166
+ "019", "Exception while mapping value: " \
167
+ "Cannot write serialized value for variable: no 'objectTypeName' provided for non-null value."))
168
+ end
169
+
170
+ def value_mapper_exception_while_serializing_object(error)
171
+ ValueMapperException.new(exception_message(
172
+ "020", "Exception while mapping value: Cannot serialize object in variable."), error)
173
+ end
174
+
175
+ def value_mapper_exception_while_deserializing_object(error)
176
+ ValueMapperException.new(exception_message(
177
+ "021", "Exception while mapping value: Cannot deserialize object in variable."), error)
178
+ end
179
+
180
+ def value_mapper_exception_while_serializing_abstract_value(name)
181
+ ValueMapperException.new(exception_message(
182
+ "022", "Cannot serialize value of abstract type '{}'", name))
183
+ end
184
+
185
+ def value_mapper_exception_due_to_serializer_not_found_for_typed_value(typed_value)
186
+ ValueMapperException.new(exception_message(
187
+ "023", "Cannot find serializer for value '{}'", typed_value))
188
+ end
189
+
190
+ def value_mapper_exception_due_to_serializer_not_found_for_typed_value_field(value)
191
+ ValueMapperException.new(exception_message(
192
+ "024", "Cannot find serializer for value '{}'", value))
193
+ end
194
+
195
+ def cannot_serialize_variable(variable_name, error)
196
+ ValueMapperException.new(exception_message(
197
+ "025", "Cannot serialize variable '{}'", variable_name), error)
198
+ end
199
+
200
+ def log_data_format_provider(provider)
201
+ log_info("026", "Discovered data format provider: {}[name = {}]",
202
+ provider.class.name, provider.data_format_name)
203
+ end
204
+
205
+ def log_data_format(data_format)
206
+ log_info("025", "Discovered data format: {}[name = {}]", data_format.class.name, data_format.name)
207
+ end
208
+
209
+ def log_data_format_configurator(configurator)
210
+ log_info("027", "Discovered data format configurator: {}[dataformat = {}]",
211
+ configurator.class.name, configurator.data_format_class.name)
212
+ end
213
+
214
+ def multiple_providers_for_dataformat(data_format_name)
215
+ ExternalTaskClientException.new(exception_message(
216
+ "028", "Multiple providers found for dataformat '{}'", data_format_name))
217
+ end
218
+
219
+ def pass_null_value_parameter(parameter_name)
220
+ ExternalTaskClientException.new(exception_message(
221
+ "030", "Null value is not allowed as '{}'", parameter_name))
222
+ end
223
+
224
+ private
225
+
226
+ def io_error?(error)
227
+ error.is_a?(IOError) || error.is_a?(SystemCallError) || error.is_a?(SocketError) ||
228
+ error.is_a?(Timeout::Error) || error.is_a?(OpenSSL::SSL::SSLError)
229
+ rescue NameError
230
+ error.is_a?(IOError) || error.is_a?(SystemCallError)
231
+ end
232
+ end
233
+ end
234
+ end
235
+ end
236
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "time"
5
+
6
+ module Operaton
7
+ module Bpm
8
+ module Client
9
+ module Impl
10
+ # Stands in for the configured Jackson ObjectMapper: JSON encoding and
11
+ # decoding plus date handling with the client's configured date format.
12
+ #
13
+ # The date format is a Ruby strftime pattern. The default corresponds to
14
+ # the Java client's "yyyy-MM-dd'T'HH:mm:ss.SSSZ".
15
+ class ObjectMapper
16
+ DEFAULT_DATE_FORMAT = "%Y-%m-%dT%H:%M:%S.%L%z"
17
+
18
+ attr_reader :date_format
19
+
20
+ def initialize(date_format = DEFAULT_DATE_FORMAT)
21
+ @date_format = date_format
22
+ end
23
+
24
+ def write_value_as_string(value)
25
+ JSON.generate(value)
26
+ end
27
+
28
+ def read_value(json_string)
29
+ JSON.parse(json_string)
30
+ end
31
+
32
+ def format_date(time)
33
+ time = time.to_time if !time.is_a?(Time) && time.respond_to?(:to_time)
34
+ time.strftime(date_format)
35
+ end
36
+
37
+ def parse_date(string)
38
+ Time.strptime(string, date_format)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../url_resolver"
4
+
5
+ module Operaton
6
+ module Bpm
7
+ module Client
8
+ module Impl
9
+ # Mirrors org.operaton.bpm.client.impl.PermanentUrlResolver
10
+ class PermanentUrlResolver
11
+ include UrlResolver
12
+
13
+ attr_accessor :base_url
14
+
15
+ def initialize(base_url)
16
+ @base_url = base_url
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end