erp_integration 0.54.0 → 0.55.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/README.md +41 -0
- data/lib/erp_integration/configuration.rb +12 -0
- data/lib/erp_integration/fulfil/client.rb +7 -1
- data/lib/erp_integration/middleware/logger.rb +2 -0
- data/lib/erp_integration/rate_limiter.rb +66 -0
- data/lib/erp_integration/version.rb +1 -1
- data/lib/erp_integration.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 865d21dfcb8c0caaed6bb6e76151e019424294a04c5a553c68459cbda871278b
|
4
|
+
data.tar.gz: 5da7b05a69bc74a8dcfa508ebe2b7b544e5902b26398b6da552fd139f20170f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea5e4f2a3f0e8bec393964d050ef9db305d1b7859032989d6899750306eba46efba5627e741fc469b95c215a23a42e6f6fcdee7f418f1ddf3da2f276cb201629
|
7
|
+
data.tar.gz: 71db26f1be6f150c53f34591d7ca46f7f89805fb65b5f44258c6dac86067bb8752feae8a08c11bf5cc4f6c096e7b3749b511583d1e3cf536921463e0d829e385
|
data/README.md
CHANGED
@@ -61,6 +61,47 @@ ErpIntegration::SalesOrder.api_keys_pool = '<your-api-key>'
|
|
61
61
|
ErpIntegration::SalesOrder.api_keys_pool = ['<your-api-key1>', '<your-api-key2>']
|
62
62
|
```
|
63
63
|
|
64
|
+
### Rate limiting
|
65
|
+
|
66
|
+
To manage the number of requests made to avoid rate limiting by the API provider, you can configure rate limiters in the ERP Integration gem. Each rate limiter should implement the `api_key_fragment` and `within_limit` methods.
|
67
|
+
|
68
|
+
### Setting Up Rate Limiters
|
69
|
+
You can configure multiple rate limiters to be used for HTTP operations on the client.
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
# config/initializers/erp_integration.rb
|
73
|
+
ErpIntegration.configure do |config|
|
74
|
+
config.rate_limiters = [
|
75
|
+
MyRateLimiter.new(api_key_fragment: 'key1'),
|
76
|
+
MyRateLimiter.new(api_key_fragment: 'key2')
|
77
|
+
]
|
78
|
+
end
|
79
|
+
```
|
80
|
+
|
81
|
+
Each rate limiter must implement the following methods:
|
82
|
+
- `api_key_fragment`: This method should return a string that is used to identify the rate limiter by the API key.
|
83
|
+
- `within_limit`: This method should `yield` to the block if the rate limit is not exceeded.
|
84
|
+
|
85
|
+
### Example Rate Limiter
|
86
|
+
Here is an example implementation of a rate limiter:
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
class MyRateLimiter
|
90
|
+
def initialize(api_key_fragment:)
|
91
|
+
@api_key_fragment = api_key_fragment
|
92
|
+
end
|
93
|
+
|
94
|
+
def api_key_fragment
|
95
|
+
@api_key_fragment
|
96
|
+
end
|
97
|
+
|
98
|
+
def within_limit
|
99
|
+
# Implement your rate limiting logic here
|
100
|
+
yield
|
101
|
+
end
|
102
|
+
end
|
103
|
+
```
|
104
|
+
|
64
105
|
### Supported Query Methods
|
65
106
|
|
66
107
|
After configuring the gem, one can easily query all the available ERP resources from the connected third-parties. In all cases, the API will return a collection of resources.
|
@@ -299,6 +299,18 @@ module ErpIntegration
|
|
299
299
|
def product_option_adapter
|
300
300
|
@product_option_adapter || :fulfil
|
301
301
|
end
|
302
|
+
|
303
|
+
# Rate limiters that will be used for HTTP operations on Client
|
304
|
+
# to manage the number of requests made to avoid rate limiting by the API provider.
|
305
|
+
def rate_limiters
|
306
|
+
@rate_limiters ||= []
|
307
|
+
end
|
308
|
+
|
309
|
+
# Sets the rate limiters that will be used
|
310
|
+
# @raise [MissingMethodError] if the rate limiter object doesn't respond to the required methods.
|
311
|
+
def rate_limiters=(rate_limiters)
|
312
|
+
@rate_limiters = rate_limiters.each { |limiter| RateLimiter.validate!(limiter) }
|
313
|
+
end
|
302
314
|
end
|
303
315
|
|
304
316
|
# Returns ERP Integration's configuration.
|
@@ -48,7 +48,9 @@ module ErpIntegration
|
|
48
48
|
raise ErpIntegration::Error, 'The Fulfil API key and/or base URL are missing.'
|
49
49
|
end
|
50
50
|
|
51
|
-
|
51
|
+
rate_limiter.within_limit do
|
52
|
+
connection.public_send(action_name, "api/#{version}/#{path}", options).body
|
53
|
+
end
|
52
54
|
end
|
53
55
|
end
|
54
56
|
|
@@ -64,6 +66,10 @@ module ErpIntegration
|
|
64
66
|
api_keys_pool.current_key
|
65
67
|
end
|
66
68
|
|
69
|
+
def rate_limiter
|
70
|
+
RateLimiter.find_by_api_key(api_key)
|
71
|
+
end
|
72
|
+
|
67
73
|
def default_headers
|
68
74
|
{
|
69
75
|
'Accept': 'application/json',
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ErpIntegration
|
4
|
+
class RateLimiter
|
5
|
+
class MissingMethodError < StandardError; end
|
6
|
+
# The `api_key_fragment` method should return a string that is used to identify
|
7
|
+
# the rate limiter by the API key.
|
8
|
+
#
|
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
|
11
|
+
|
12
|
+
class << self
|
13
|
+
# Validates that the rate limiter object responds to the required methods.
|
14
|
+
# It requires the `api_key_fragment` and `within_limit` methods to be present.
|
15
|
+
#
|
16
|
+
# @raise [MissingMethodError]
|
17
|
+
# @param rate_limiter [Object]
|
18
|
+
def validate!(rate_limiter)
|
19
|
+
REQUIRED_METHODS.each do |method|
|
20
|
+
next if rate_limiter.respond_to?(method)
|
21
|
+
|
22
|
+
raise MissingMethodError, "'#{rate_limiter.class}##{method}' method is required."
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Finds the rate limiter by the API key.
|
27
|
+
# If the API key is not found, it returns an unlimited rate limiter.
|
28
|
+
#
|
29
|
+
# @param api_key [String]
|
30
|
+
# @return [Object] The rate limiter object.
|
31
|
+
def find_by_api_key(api_key)
|
32
|
+
rate_limiters[api_key] || unlimited
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns an unlimited rate limiter.
|
36
|
+
#
|
37
|
+
# @return [RateLimiter::Unlimited] The unlimited rate limiter object.
|
38
|
+
def unlimited
|
39
|
+
@unlimited ||= Unlimited.new
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
# The `rate_limiters` hash stores the rate limiter objects found by the API key.
|
45
|
+
#
|
46
|
+
# @return [Hash] The rate limiters hash.
|
47
|
+
def rate_limiters
|
48
|
+
@rate_limiters ||= Hash.new do |h, api_key|
|
49
|
+
h[api_key] = ErpIntegration.config.rate_limiters.find do |rate_limiter|
|
50
|
+
api_key.end_with?(rate_limiter.api_key_fragment)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# {Unlimited} is a rate limiter that allows all requests.
|
57
|
+
# When the rate limiter wasn't found by the API key, it defaults to this class.
|
58
|
+
# Or if the `rate_limiters` option is not set in the configuration.
|
59
|
+
class Unlimited
|
60
|
+
# Executes the block without any restrictions.
|
61
|
+
def within_limit
|
62
|
+
yield
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/erp_integration.rb
CHANGED
@@ -11,6 +11,7 @@ require 'json'
|
|
11
11
|
require_relative 'erp_integration/version'
|
12
12
|
require_relative 'erp_integration/errors'
|
13
13
|
require_relative 'erp_integration/api_keys_pool'
|
14
|
+
require_relative 'erp_integration/rate_limiter'
|
14
15
|
require_relative 'erp_integration/configuration'
|
15
16
|
|
16
17
|
# Middleware
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: erp_integration
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.55.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stefan Vermaas
|
@@ -329,6 +329,7 @@ files:
|
|
329
329
|
- lib/erp_integration/purchase_order.rb
|
330
330
|
- lib/erp_integration/purchase_order_line.rb
|
331
331
|
- lib/erp_integration/purchase_request.rb
|
332
|
+
- lib/erp_integration/rate_limiter.rb
|
332
333
|
- lib/erp_integration/resource.rb
|
333
334
|
- lib/erp_integration/resources/errors.rb
|
334
335
|
- lib/erp_integration/resources/persistence.rb
|
@@ -368,7 +369,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
368
369
|
- !ruby/object:Gem::Version
|
369
370
|
version: '0'
|
370
371
|
requirements: []
|
371
|
-
rubygems_version: 3.
|
372
|
+
rubygems_version: 3.2.22
|
372
373
|
signing_key:
|
373
374
|
specification_version: 4
|
374
375
|
summary: Connects Mejuri with third-party ERP vendors
|