erp_integration 0.56.0 → 0.58.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/lib/erp_integration/configuration.rb +8 -4
- data/lib/erp_integration/errors.rb +1 -1
- data/lib/erp_integration/fulfil/client.rb +3 -1
- data/lib/erp_integration/logger.rb +29 -0
- data/lib/erp_integration/middleware/formatter.rb +38 -0
- data/lib/erp_integration/middleware/logger.rb +6 -8
- data/lib/erp_integration/rate_limiter.rb +21 -2
- data/lib/erp_integration/version.rb +1 -1
- data/lib/erp_integration.rb +2 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0414ab9ad823ea6eb9770829c73ec69f09776fc9cd9983ebd09cbd1efba44320
|
4
|
+
data.tar.gz: 8943d4e6c2868dd5d158e9a48af258b2cb8193f38715153aea55bca6d7cdeb74
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: feefbf3f9aa3900e9f4b6e2c2662199e1850211880ab50c2157312b562e5af4152e4545f61712d70ccdefb47f3b48c617663d6b2977a5bd613efa6f20842868c
|
7
|
+
data.tar.gz: c901363ad8f2cbf5e014a4e3fb1236b71e9c1d24762c710f90e3d2c4802bfaeb3f8144b7f22e17ca44e6d0bb9aaed0b0ce77082d30843d74f16bd4f2372c0c0c
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.0.2
|
@@ -168,10 +168,6 @@ module ErpIntegration
|
|
168
168
|
# @return [Symbol] The configured adapter for the tracking number.
|
169
169
|
attr_writer :product_option_adapter
|
170
170
|
|
171
|
-
# Logger that will be used for HTTP operations on Client
|
172
|
-
# @return [Logger] The configured logger
|
173
|
-
attr_accessor :logger
|
174
|
-
|
175
171
|
def initialize(**options)
|
176
172
|
options.each_pair do |key, value|
|
177
173
|
public_send("#{key}=", value) if respond_to?("#{key}=")
|
@@ -321,6 +317,14 @@ module ErpIntegration
|
|
321
317
|
def rate_limiters=(rate_limiters)
|
322
318
|
@rate_limiters = (rate_limiters || []).each { |limiter| RateLimiter.validate!(limiter) }
|
323
319
|
end
|
320
|
+
|
321
|
+
def logger
|
322
|
+
@logger || Logger.new(nil)
|
323
|
+
end
|
324
|
+
|
325
|
+
def logger=(logger)
|
326
|
+
@logger = Logger.new(logger)
|
327
|
+
end
|
324
328
|
end
|
325
329
|
|
326
330
|
# Returns ERP Integration's configuration.
|
@@ -32,7 +32,7 @@ module ErpIntegration
|
|
32
32
|
class MethodNotAllowed < HttpError; end
|
33
33
|
class NotAccepted < HttpError; end
|
34
34
|
class UnprocessableEntity < HttpError; end
|
35
|
-
class TooManyRequests <
|
35
|
+
class TooManyRequests < Faraday::Error; end
|
36
36
|
class InternalServerError < HttpError; end
|
37
37
|
end
|
38
38
|
end
|
@@ -3,6 +3,8 @@
|
|
3
3
|
module ErpIntegration
|
4
4
|
module Fulfil
|
5
5
|
class Client
|
6
|
+
FORMATTER = ErpIntegration::Middleware::Formatter
|
7
|
+
|
6
8
|
attr_reader :api_keys_pool, :base_url
|
7
9
|
attr_writer :connection, :faraday_adapter, :rotate_statuses
|
8
10
|
|
@@ -35,7 +37,7 @@ module ErpIntegration
|
|
35
37
|
# Custom middleware for rotating API keys
|
36
38
|
faraday.use ErpIntegration::Middleware::ApiKeysRotation, rotation_options
|
37
39
|
# Custom middleware for logging requests and responses
|
38
|
-
faraday.use ErpIntegration::Middleware::Logger, @logger if @logger
|
40
|
+
faraday.use ErpIntegration::Middleware::Logger, @logger, formatter: FORMATTER if @logger
|
39
41
|
|
40
42
|
# Adapter definition should be last in order to make the json parsers be loaded correctly
|
41
43
|
faraday.adapter faraday_adapter
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ErpIntegration
|
4
|
+
# The Logger class is a simple wrapper around the logger object.
|
5
|
+
class Logger
|
6
|
+
delegate :debug, :info, :warn, :error, :fatal, to: :logger, allow_nil: true
|
7
|
+
|
8
|
+
def initialize(logger = nil)
|
9
|
+
@logger = logger
|
10
|
+
end
|
11
|
+
|
12
|
+
# Logs the given tags if the logger is present.
|
13
|
+
# If the logger does not respond to `tagged`, it logs the tags as an info message.
|
14
|
+
def with_tags(*tags)
|
15
|
+
return yield unless logger
|
16
|
+
|
17
|
+
if logger.respond_to?(:tagged)
|
18
|
+
logger.tagged(*tags) { yield }
|
19
|
+
else
|
20
|
+
logger.info("Requested ERP with #{tags.join(', ')}")
|
21
|
+
yield
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
attr_reader :logger
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ErpIntegration
|
4
|
+
module Middleware
|
5
|
+
# The {Formatter} class is a custom formatter for the Faraday logger.
|
6
|
+
# It logs the rate limiter headers in the response.
|
7
|
+
class Formatter < Faraday::Logging::Formatter
|
8
|
+
def response(env)
|
9
|
+
super
|
10
|
+
public_send(log_level, 'response', &rate_limiter_headers(env.response_headers))
|
11
|
+
end
|
12
|
+
|
13
|
+
# Formats the rate limiter headers.
|
14
|
+
# @param headers [Hash]
|
15
|
+
def rate_limiter_headers(headers)
|
16
|
+
proc do
|
17
|
+
[
|
18
|
+
limit(headers),
|
19
|
+
remaining(headers),
|
20
|
+
reset_at(headers)
|
21
|
+
].join(', ')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def limit(headers)
|
26
|
+
"Rate Limit #{headers['x-ratelimit-limit']}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def remaining(headers)
|
30
|
+
"Remaining Limit #{headers['x-ratelimit-remaining']}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def reset_at(headers)
|
34
|
+
"Rate Limit Reset at #{Time.at(headers['x-ratelimit-reset'].to_i).utc}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -20,15 +20,9 @@ module ErpIntegration
|
|
20
20
|
|
21
21
|
def call(env)
|
22
22
|
api_key_fragment = sanitize_api_key(env.request_headers['X-API-KEY']) || 'none'
|
23
|
+
request_uuid = SecureRandom.uuid
|
23
24
|
|
24
|
-
|
25
|
-
@logger.tagged("API key *#{api_key_fragment}") do
|
26
|
-
@formatter.request(env)
|
27
|
-
|
28
|
-
@app.call(env).on_complete { |response| on_complete(response) }
|
29
|
-
end
|
30
|
-
else
|
31
|
-
@logger.info("Requested ERP with API key *#{api_key_fragment}")
|
25
|
+
@logger.with_tags(api_key_tag(api_key_fragment), request_uuid) do
|
32
26
|
@formatter.request(env)
|
33
27
|
|
34
28
|
@app.call(env).on_complete { |response| on_complete(response) }
|
@@ -48,6 +42,10 @@ module ErpIntegration
|
|
48
42
|
def sanitize_api_key(api_key)
|
49
43
|
api_key[-4..-1] if api_key
|
50
44
|
end
|
45
|
+
|
46
|
+
def api_key_tag(api_key_fragment)
|
47
|
+
"API key *#{api_key_fragment}"
|
48
|
+
end
|
51
49
|
end
|
52
50
|
end
|
53
51
|
end
|
@@ -7,7 +7,7 @@ module ErpIntegration
|
|
7
7
|
# the rate limiter by the API key.
|
8
8
|
#
|
9
9
|
# The `within_limit` method should yield to the block if the rate limit is not exceeded.
|
10
|
-
REQUIRED_METHODS = %i[api_key_fragment within_limit].freeze
|
10
|
+
REQUIRED_METHODS = %i[api_key_fragment name within_limit].freeze
|
11
11
|
|
12
12
|
class << self
|
13
13
|
# Validates that the rate limiter object responds to the required methods.
|
@@ -29,7 +29,7 @@ module ErpIntegration
|
|
29
29
|
# @param api_key [String]
|
30
30
|
# @return [Object] The rate limiter object.
|
31
31
|
def find_by_api_key(api_key)
|
32
|
-
rate_limiters[api_key] || unlimited
|
32
|
+
new(rate_limiters[api_key] || unlimited)
|
33
33
|
end
|
34
34
|
|
35
35
|
# Returns an unlimited rate limiter.
|
@@ -53,11 +53,30 @@ module ErpIntegration
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
+
delegate :name, to: :@rate_limiter
|
57
|
+
|
58
|
+
def initialize(rate_limiter)
|
59
|
+
@rate_limiter = rate_limiter
|
60
|
+
end
|
61
|
+
|
62
|
+
def within_limit(&block)
|
63
|
+
ErpIntegration.config.logger.with_tags(@rate_limiter.name) do
|
64
|
+
@rate_limiter.within_limit(&block)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
56
68
|
# {Unlimited} is a rate limiter that allows all requests.
|
57
69
|
# When the rate limiter wasn't found by the API key, it defaults to this class.
|
58
70
|
# Or if the `rate_limiters` option is not set in the configuration.
|
59
71
|
class Unlimited
|
60
72
|
# Executes the block without any restrictions.
|
73
|
+
|
74
|
+
attr_reader :name
|
75
|
+
|
76
|
+
def initialize
|
77
|
+
@name = 'unlimited'
|
78
|
+
end
|
79
|
+
|
61
80
|
def within_limit
|
62
81
|
yield
|
63
82
|
end
|
data/lib/erp_integration.rb
CHANGED
@@ -12,12 +12,14 @@ require_relative 'erp_integration/version'
|
|
12
12
|
require_relative 'erp_integration/errors'
|
13
13
|
require_relative 'erp_integration/api_keys_pool'
|
14
14
|
require_relative 'erp_integration/rate_limiter'
|
15
|
+
require_relative 'erp_integration/logger'
|
15
16
|
require_relative 'erp_integration/configuration'
|
16
17
|
|
17
18
|
# Middleware
|
18
19
|
require_relative 'erp_integration/middleware/api_keys_rotation'
|
19
20
|
require_relative 'erp_integration/middleware/error_handling'
|
20
21
|
require_relative 'erp_integration/middleware/logger'
|
22
|
+
require_relative 'erp_integration/middleware/formatter'
|
21
23
|
|
22
24
|
# HTTP clients
|
23
25
|
require_relative 'erp_integration/fulfil/client'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: erp_integration
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.58.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stefan Vermaas
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-12-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -317,8 +317,10 @@ files:
|
|
317
317
|
- lib/erp_integration/gift_card.rb
|
318
318
|
- lib/erp_integration/internal_shipment.rb
|
319
319
|
- lib/erp_integration/location.rb
|
320
|
+
- lib/erp_integration/logger.rb
|
320
321
|
- lib/erp_integration/middleware/api_keys_rotation.rb
|
321
322
|
- lib/erp_integration/middleware/error_handling.rb
|
323
|
+
- lib/erp_integration/middleware/formatter.rb
|
322
324
|
- lib/erp_integration/middleware/logger.rb
|
323
325
|
- lib/erp_integration/party_address.rb
|
324
326
|
- lib/erp_integration/product.rb
|
@@ -369,7 +371,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
369
371
|
- !ruby/object:Gem::Version
|
370
372
|
version: '0'
|
371
373
|
requirements: []
|
372
|
-
rubygems_version: 3.
|
374
|
+
rubygems_version: 3.2.22
|
373
375
|
signing_key:
|
374
376
|
specification_version: 4
|
375
377
|
summary: Connects Mejuri with third-party ERP vendors
|