bas 1.8.1 → 1.9.1
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/CHANGELOG.md +6 -0
- data/lib/bas/utils/operaton/base_operaton_client.rb +81 -0
- data/lib/bas/utils/operaton/external_task_client.rb +25 -65
- data/lib/bas/utils/operaton/process_client.rb +76 -0
- data/lib/bas/version.rb +1 -1
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6301713e4aa3a33bd8b221ebc9ad27769f4fec96f51c281f707093a64405f639
|
4
|
+
data.tar.gz: a6c0caed10c86f2ee8d5ec2bd2d0ad87e3ea8be9b6c8a1f542a4965b174412bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 56f493893506461d836362936b30e511be6d6508aa9a2b992479c78359c71b026bfe6098e094c4d8e66239a2ac946c45dd577b05d49d574b2e42227c6e344ae9
|
7
|
+
data.tar.gz: 326a87c50f0ce824f7a046600a9cdad8f06e31514a4799ecde76d503a6190e0b73f6b2d035c6d6ee769693c84ee5a474dfb6e37f729a379ef9787b0f44fe871d
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
# 1.9.1 (15.07.2025)
|
4
|
+
- [refactor: Refactor client to meet the needs of the implementation to be performed](https://github.com/kommitters/bas/pull/149)
|
5
|
+
|
6
|
+
# 1.9.0 (15.07.2025)
|
7
|
+
- [feat: Implement client to perform process deployments and instance creation in Operaton via the REST API](https://github.com/kommitters/bas/pull/146)
|
8
|
+
|
3
9
|
# 1.8.1 (08.07.2025)
|
4
10
|
- [refactor: Refactor client for correct use of shared_storage](https://github.com/kommitters/bas/pull/144)
|
5
11
|
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "faraday"
|
4
|
+
require "json"
|
5
|
+
|
6
|
+
module Utils
|
7
|
+
module Operaton
|
8
|
+
##
|
9
|
+
# BaseClient provides common HTTP methods and variable formatting logic
|
10
|
+
# shared by all Operaton API clients.
|
11
|
+
#
|
12
|
+
class BaseClient
|
13
|
+
def initialize(base_url:)
|
14
|
+
raise ArgumentError, "base_url is required" if base_url.to_s.strip.empty?
|
15
|
+
|
16
|
+
@base_url = base_url.chomp("/")
|
17
|
+
@conn = build_conn
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def build_conn
|
23
|
+
# Override to add multipart support for file uploads and URL encoding for form data
|
24
|
+
Faraday.new(url: @base_url) do |f|
|
25
|
+
f.request :json
|
26
|
+
f.response :json, content_type: /\bjson$/
|
27
|
+
f.adapter Faraday.default_adapter
|
28
|
+
f.options.timeout = 30
|
29
|
+
f.options.open_timeout = 10
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def full_url(path)
|
34
|
+
"#{@base_url}#{path.start_with?("/") ? path : "/#{path}"}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def get(path, params = {})
|
38
|
+
response = @conn.get(full_url(path), params)
|
39
|
+
handle_response(response)
|
40
|
+
end
|
41
|
+
|
42
|
+
def post(path, body = {}, headers = {})
|
43
|
+
response = @conn.post(full_url(path)) do |req|
|
44
|
+
req.headers.update(headers) if headers.any?
|
45
|
+
req.body = body
|
46
|
+
end
|
47
|
+
handle_response(response)
|
48
|
+
end
|
49
|
+
|
50
|
+
def handle_response(response)
|
51
|
+
unless response.success?
|
52
|
+
error_body = response.body.is_a?(Hash) ? response.body : { message: response.body }
|
53
|
+
raise "Operaton API Error #{response.status}: #{error_body["message"] || error_body}"
|
54
|
+
end
|
55
|
+
|
56
|
+
response.body
|
57
|
+
end
|
58
|
+
|
59
|
+
def format_variables(vars)
|
60
|
+
vars.transform_values do |value|
|
61
|
+
{
|
62
|
+
value: value,
|
63
|
+
type: ruby_type_to_operaton_type(value)
|
64
|
+
}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def ruby_type_to_operaton_type(value)
|
69
|
+
case value
|
70
|
+
when nil then "Null"
|
71
|
+
when String then "String"
|
72
|
+
when Integer then "Integer"
|
73
|
+
when Float then "Double"
|
74
|
+
when TrueClass, FalseClass then "Boolean"
|
75
|
+
when Array, Hash then "Json"
|
76
|
+
else "Object"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -2,10 +2,12 @@
|
|
2
2
|
|
3
3
|
require "faraday"
|
4
4
|
require "json"
|
5
|
+
require_relative "base_operaton_client"
|
5
6
|
|
6
7
|
module Utils
|
7
8
|
module Operaton
|
8
|
-
|
9
|
+
##
|
10
|
+
# Client for interacting with Operaton's External Task API.
|
9
11
|
#
|
10
12
|
# This client provides methods to manage external task lifecycle including:
|
11
13
|
# - Fetching and locking tasks
|
@@ -14,42 +16,35 @@ module Utils
|
|
14
16
|
# - Reporting task failures
|
15
17
|
#
|
16
18
|
# @example
|
17
|
-
# client = Utils::Operaton::ExternalTaskClient.
|
18
|
-
# worker_id: "worker-123")
|
19
|
+
# client = Utils::Operaton::ExternalTaskClient.new(base_url: "https://api.operaton.com", worker_id: "worker-123")
|
19
20
|
# tasks = client.fetch_and_lock("my-topic")
|
20
|
-
|
21
|
-
|
22
|
-
new(params)
|
23
|
-
end
|
24
|
-
|
21
|
+
#
|
22
|
+
class ExternalTaskClient < BaseClient
|
25
23
|
def initialize(params)
|
26
|
-
validate_params!(params)
|
27
|
-
|
28
|
-
@base_url = params[:base_url]
|
29
24
|
@worker_id = params[:worker_id]
|
30
|
-
|
31
|
-
|
32
|
-
f.request :json
|
33
|
-
f.response :json, content_type: /\bjson$/
|
34
|
-
f.adapter Faraday.default_adapter
|
35
|
-
end
|
25
|
+
validate_params!(params)
|
26
|
+
super(base_url: params[:base_url])
|
36
27
|
end
|
37
28
|
|
38
29
|
def fetch_and_lock(topics_str, lock_duration: 10_000, max_tasks: 1, use_priority: true, variables: [])
|
39
30
|
post(
|
40
31
|
"/external-task/fetchAndLock",
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
32
|
+
{
|
33
|
+
workerId: @worker_id,
|
34
|
+
maxTasks: max_tasks,
|
35
|
+
usePriority: use_priority,
|
36
|
+
topics: build_topics_payload(topics_str, lock_duration, variables)
|
37
|
+
}
|
45
38
|
)
|
46
39
|
end
|
47
40
|
|
48
41
|
def complete(task_id, variables = {})
|
49
42
|
post(
|
50
43
|
"/external-task/#{task_id}/complete",
|
51
|
-
|
52
|
-
|
44
|
+
{
|
45
|
+
workerId: @worker_id,
|
46
|
+
variables: format_variables(variables)
|
47
|
+
}
|
53
48
|
)
|
54
49
|
end
|
55
50
|
|
@@ -64,11 +59,13 @@ module Utils
|
|
64
59
|
def report_failure(task_id, error_message:, error_details:, retries:, retry_timeout:)
|
65
60
|
post(
|
66
61
|
"/external-task/#{task_id}/failure",
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
62
|
+
{
|
63
|
+
workerId: @worker_id,
|
64
|
+
errorMessage: error_message,
|
65
|
+
errorDetails: error_details,
|
66
|
+
retries: retries,
|
67
|
+
retryTimeout: retry_timeout
|
68
|
+
}
|
72
69
|
)
|
73
70
|
end
|
74
71
|
|
@@ -89,43 +86,6 @@ module Utils
|
|
89
86
|
}
|
90
87
|
end
|
91
88
|
end
|
92
|
-
|
93
|
-
def full_url(path)
|
94
|
-
"#{@base_url}#{path}"
|
95
|
-
end
|
96
|
-
|
97
|
-
def post(path, body = {})
|
98
|
-
handle_response(@conn.post(full_url(path), body))
|
99
|
-
end
|
100
|
-
|
101
|
-
def get(path, params = {})
|
102
|
-
handle_response(@conn.get(full_url(path), params))
|
103
|
-
end
|
104
|
-
|
105
|
-
def handle_response(response)
|
106
|
-
raise "Operaton API Error #{response.status}: #{response.body}" unless response.success?
|
107
|
-
|
108
|
-
response.body
|
109
|
-
end
|
110
|
-
|
111
|
-
def format_variables(vars)
|
112
|
-
vars.transform_values do |value|
|
113
|
-
{
|
114
|
-
value: value,
|
115
|
-
type: ruby_type_to_operaton_type(value)
|
116
|
-
}
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
def ruby_type_to_operaton_type(value)
|
121
|
-
case value
|
122
|
-
when String then "String"
|
123
|
-
when Integer then "Integer"
|
124
|
-
when Float then "Double"
|
125
|
-
when TrueClass, FalseClass then "Boolean"
|
126
|
-
else "Object"
|
127
|
-
end
|
128
|
-
end
|
129
89
|
end
|
130
90
|
end
|
131
91
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "faraday"
|
4
|
+
require "json"
|
5
|
+
require "faraday/multipart"
|
6
|
+
require "logger"
|
7
|
+
require_relative "base_operaton_client"
|
8
|
+
|
9
|
+
module Utils
|
10
|
+
module Operaton
|
11
|
+
##
|
12
|
+
# Client for deploying BPMN processes and starting process instances in Operaton (Camunda 7 API compatible)
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# client = Utils::Operaton::ProcessClient.new(base_url: "https://api.operaton.com")
|
16
|
+
# tasks = client.deploy_process(file_path, deployment_name: deployment_name)
|
17
|
+
#
|
18
|
+
class ProcessClient < BaseClient
|
19
|
+
def initialize(base_url:)
|
20
|
+
@logger = defined?(Rails) ? Rails.logger : Logger.new($stdout)
|
21
|
+
super(base_url: base_url)
|
22
|
+
end
|
23
|
+
|
24
|
+
def deploy_process(file_path, deployment_name:)
|
25
|
+
raise "File not found: #{file_path}" unless File.exist?(file_path)
|
26
|
+
raise "File is not readable: #{file_path}" unless File.readable?(file_path)
|
27
|
+
|
28
|
+
@logger.info "📁 Attempting to read file: #{file_path}"
|
29
|
+
@logger.info "📦 Deployment name: #{deployment_name}"
|
30
|
+
|
31
|
+
payload = {
|
32
|
+
"deployment-name" => deployment_name,
|
33
|
+
"deploy-changed-only" => "true",
|
34
|
+
"data" => Faraday::Multipart::FilePart.new(file_path, "application/octet-stream", File.basename(file_path))
|
35
|
+
}
|
36
|
+
|
37
|
+
post("/deployment/create", payload)
|
38
|
+
end
|
39
|
+
|
40
|
+
def instance_with_business_key_exists?(process_key, business_key)
|
41
|
+
query_params = {
|
42
|
+
processDefinitionKey: process_key,
|
43
|
+
maxResults: 50,
|
44
|
+
active: true
|
45
|
+
}
|
46
|
+
|
47
|
+
response = get("/history/process-instance", query_params)
|
48
|
+
response.any? { |instance| instance["businessKey"] == business_key }
|
49
|
+
end
|
50
|
+
|
51
|
+
def start_process_instance_by_key(process_key, business_key:, variables: {})
|
52
|
+
json_payload = {
|
53
|
+
businessKey: business_key,
|
54
|
+
variables: format_variables(variables)
|
55
|
+
}
|
56
|
+
|
57
|
+
post(
|
58
|
+
"/process-definition/key/#{process_key}/start",
|
59
|
+
JSON.generate(json_payload),
|
60
|
+
{ "Content-Type" => "application/json" }
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def build_conn
|
67
|
+
Faraday.new(url: @base_url) do |f|
|
68
|
+
f.request :multipart
|
69
|
+
f.request :url_encoded
|
70
|
+
f.response :json, content_type: /\bjson$/
|
71
|
+
f.adapter Faraday.default_adapter
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/bas/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bas
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kommitters Open Source
|
@@ -23,6 +23,20 @@ dependencies:
|
|
23
23
|
- - "~>"
|
24
24
|
- !ruby/object:Gem::Version
|
25
25
|
version: '8.0'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: faraday-multipart
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
26
40
|
- !ruby/object:Gem::Dependency
|
27
41
|
name: httparty
|
28
42
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,7 +112,9 @@ files:
|
|
98
112
|
- lib/bas/utils/notion/update_db_page.rb
|
99
113
|
- lib/bas/utils/notion/update_db_state.rb
|
100
114
|
- lib/bas/utils/openai/run_assistant.rb
|
115
|
+
- lib/bas/utils/operaton/base_operaton_client.rb
|
101
116
|
- lib/bas/utils/operaton/external_task_client.rb
|
117
|
+
- lib/bas/utils/operaton/process_client.rb
|
102
118
|
- lib/bas/utils/postgres/request.rb
|
103
119
|
- lib/bas/version.rb
|
104
120
|
- renovate.json
|
@@ -123,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
139
|
- !ruby/object:Gem::Version
|
124
140
|
version: '0'
|
125
141
|
requirements: []
|
126
|
-
rubygems_version: 3.6.
|
142
|
+
rubygems_version: 3.6.9
|
127
143
|
specification_version: 4
|
128
144
|
summary: BAS - Business automation suite
|
129
145
|
test_files: []
|