apisonator 3.0.0 → 3.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 455379ea79ee4377baa1060f0213d37d08c66135c6a0be9233536de917968303
4
- data.tar.gz: d46f21858ba98539d51b0a32582e9b82c2ff6d08cbacb1b791d6cb9ea782024e
3
+ metadata.gz: 1f414f062cdabb59cdcc29b67a862a4400baa6e8d92ebeec909907ed881aa806
4
+ data.tar.gz: 2db24643307830c7cb2cef21da16a51aae8f9336b7bf35f90d4f22f82d15ff45
5
5
  SHA512:
6
- metadata.gz: 5df4b993ffd0dd16cc9d75b4dc88652cba83d0767c967d10777191010ea87a8db4cf0b824adc3879e47e4221ff5a48cfdfe54954b76b4fb4537b8a514fe91caf
7
- data.tar.gz: ee54b488232e0cf277d7bf052bbaab9edb96ba582b18859a7053a57a07ee50b9e932ed471e26a84cd60b9c7052c444b9595d07f98eb7d937eb83e4a5b28a1118
6
+ metadata.gz: 71ad48dc02408cab0de7f8264832489a08b935f55b47139a81ee7228cd71c783d8ebe81c7737c9b3035327535bd9b561784838486194e4b2ab808bb740fad753
7
+ data.tar.gz: 843744f70251b4d26365ab1fe2a4e7c73444b57629f3815c6043bbe467c70835050fdaabdd458e47323a11fb4294b01d1674dd5215f09b6647518adcfbf484da
@@ -2,6 +2,73 @@
2
2
 
3
3
  Notable changes to Apisonator will be tracked in this document.
4
4
 
5
+ ## 3.2.1 - 2021-01-22
6
+
7
+ ### Fixed
8
+
9
+ - Reports of 0 hits no longer generate unnecessary stats keys in Redis
10
+ ([#247](https://github.com/3scale/apisonator/pull/247)).
11
+
12
+ ## 3.2.0 - 2021-01-19
13
+
14
+ ### Added
15
+
16
+ - New endpoint in the internal API to get the provider key for a given (token,
17
+ service_id) pair ([#243](https://github.com/3scale/apisonator/pull/243)).
18
+
19
+ ### Changed
20
+
21
+ - The config file used when running in a Docker image now parses "1" and "true"
22
+ (case-insensitive) as true
23
+ ([#245](https://github.com/3scale/apisonator/pull/245)).
24
+
25
+ ### Fixed
26
+
27
+ - Fixed some metrics of the internal API that were not being counted
28
+ correctly([#244](https://github.com/3scale/apisonator/pull/244)).
29
+
30
+
31
+ ## 3.1.0 - 2020-10-14
32
+
33
+ ### Added
34
+
35
+ - Prometheus metrics for the internal API
36
+ ([#236](https://github.com/3scale/apisonator/pull/236)).
37
+ - Docs with a detailed explanation about how counter updates are performed
38
+ ([#239](https://github.com/3scale/apisonator/pull/239)).
39
+
40
+ ### Changed
41
+
42
+ - NotifyJobs are run only when the service ID is explicitly defined
43
+ ([#238](https://github.com/3scale/apisonator/pull/238)).
44
+
45
+ ### Fixed
46
+
47
+ - Fixed corner case that raised "TransactionTimestampNotWithinRange" in notify
48
+ jobs ([#235](https://github.com/3scale/apisonator/pull/235)).
49
+
50
+
51
+ ## 3.0.1.1 - 2020-07-28
52
+
53
+ ### Changed
54
+
55
+ - Updated json gem to v2.3.1
56
+ ([#232](https://github.com/3scale/apisonator/pull/232)).
57
+
58
+ ## 3.0.1 - 2020-07-14
59
+
60
+ ### Fixed
61
+
62
+ - The Prometheus counter of "5xx" errors has been fixed
63
+ ([#230](https://github.com/3scale/apisonator/pull/230)).
64
+
65
+ ### Changed
66
+
67
+ - Gem updates: rack to v2.1.4
68
+ ([#228](https://github.com/3scale/apisonator/pull/228)) and async-redis to
69
+ v0.5.0 ([#229](https://github.com/3scale/apisonator/pull/229)).
70
+
71
+
5
72
  ## 3.0.0 - 2020-06-19
6
73
 
7
74
  ### Removed
@@ -53,13 +53,13 @@ gem 'rake', '~> 13.0'
53
53
  gem 'builder', '= 3.2.3'
54
54
  # Use a patched resque to allow reusing their Airbrake Failure class
55
55
  gem 'resque', git: 'https://github.com/3scale/resque', branch: '3scale'
56
- gem 'rack', '~> 2.0.8'
56
+ gem 'rack', '~> 2.1.4'
57
57
  gem 'sinatra', '~> 2.0.3'
58
58
  gem 'sinatra-contrib', '~> 2.0.3'
59
59
  # Optional external error logging services
60
60
  gem 'bugsnag', '~> 6', require: nil
61
61
  gem 'yabeda-prometheus', '~> 0.5.0'
62
- gem 'async-redis', '~> 0.4.1'
62
+ gem 'async-redis', '~> 0.5'
63
63
  gem 'falcon', '~> 0.35'
64
64
 
65
65
  # Use a patched redis-rb that fixes an issue when trying to connect with
@@ -35,7 +35,7 @@ GIT
35
35
  PATH
36
36
  remote: .
37
37
  specs:
38
- apisonator (3.0.0)
38
+ apisonator (3.2.1)
39
39
 
40
40
  GEM
41
41
  remote: https://rubygems.org/
@@ -66,14 +66,15 @@ GEM
66
66
  async-http-cache (0.1.5)
67
67
  async-http
68
68
  protocol-http (~> 0.14)
69
- async-io (1.27.5)
69
+ async-io (1.27.7)
70
70
  async (~> 1.14)
71
71
  async-pool (0.2.0)
72
72
  async (~> 1.8)
73
- async-redis (0.4.1)
73
+ async-redis (0.5.0)
74
74
  async (~> 1.8)
75
75
  async-io (~> 1.10)
76
- protocol-redis (~> 0.2.0)
76
+ async-pool (~> 0.2)
77
+ protocol-redis (~> 0.5.0)
77
78
  async-rspec (1.13.0)
78
79
  rspec (~> 3.0)
79
80
  rspec-files (~> 1.0)
@@ -118,7 +119,7 @@ GEM
118
119
  i18n (1.8.2)
119
120
  concurrent-ruby (~> 1.0)
120
121
  jmespath (1.3.1)
121
- json (2.1.0)
122
+ json (2.3.1)
122
123
  license_finder (5.9.2)
123
124
  bundler
124
125
  rubyzip
@@ -161,7 +162,7 @@ GEM
161
162
  protocol-http2 (0.11.6)
162
163
  protocol-hpack (~> 1.4)
163
164
  protocol-http (~> 0.15)
164
- protocol-redis (0.2.0)
165
+ protocol-redis (0.5.0)
165
166
  pry (0.11.3)
166
167
  coderay (~> 1.1.0)
167
168
  method_source (~> 0.9.0)
@@ -171,7 +172,7 @@ GEM
171
172
  pry-doc (0.11.1)
172
173
  pry (~> 0.9)
173
174
  yard (~> 0.9)
174
- rack (2.0.9)
175
+ rack (2.1.4)
175
176
  rack-protection (2.0.3)
176
177
  rack
177
178
  rack-test (0.8.2)
@@ -266,7 +267,7 @@ PLATFORMS
266
267
  DEPENDENCIES
267
268
  airbrake (= 4.3.1)
268
269
  apisonator!
269
- async-redis (~> 0.4.1)
270
+ async-redis (~> 0.5)
270
271
  async-rspec
271
272
  aws-sdk (= 2.4.2)
272
273
  benchmark-ips (~> 2.7.2)
@@ -286,7 +287,7 @@ DEPENDENCIES
286
287
  pry-byebug (~> 3.5.1)
287
288
  pry-doc (~> 0.11.1)
288
289
  puma!
289
- rack (~> 2.0.8)
290
+ rack (~> 2.1.4)
290
291
  rack-test (~> 0.8.2)
291
292
  rake (~> 13.0)
292
293
  redis!
@@ -35,7 +35,7 @@ GIT
35
35
  PATH
36
36
  remote: .
37
37
  specs:
38
- apisonator (3.0.0)
38
+ apisonator (3.2.1)
39
39
 
40
40
  GEM
41
41
  remote: https://rubygems.org/
@@ -63,14 +63,15 @@ GEM
63
63
  async-http-cache (0.1.5)
64
64
  async-http
65
65
  protocol-http (~> 0.14)
66
- async-io (1.27.5)
66
+ async-io (1.27.7)
67
67
  async (~> 1.14)
68
68
  async-pool (0.2.0)
69
69
  async (~> 1.8)
70
- async-redis (0.4.1)
70
+ async-redis (0.5.0)
71
71
  async (~> 1.8)
72
72
  async-io (~> 1.10)
73
- protocol-redis (~> 0.2.0)
73
+ async-pool (~> 0.2)
74
+ protocol-redis (~> 0.5.0)
74
75
  async-rspec (1.13.0)
75
76
  rspec (~> 3.0)
76
77
  rspec-files (~> 1.0)
@@ -107,7 +108,7 @@ GEM
107
108
  hiredis (0.6.3)
108
109
  i18n (1.8.2)
109
110
  concurrent-ruby (~> 1.0)
110
- json (2.1.0)
111
+ json (2.3.1)
111
112
  license_finder (5.9.2)
112
113
  bundler
113
114
  rubyzip
@@ -149,7 +150,7 @@ GEM
149
150
  protocol-http2 (0.11.6)
150
151
  protocol-hpack (~> 1.4)
151
152
  protocol-http (~> 0.15)
152
- protocol-redis (0.2.0)
153
+ protocol-redis (0.5.0)
153
154
  pry (0.11.3)
154
155
  coderay (~> 1.1.0)
155
156
  method_source (~> 0.9.0)
@@ -159,7 +160,7 @@ GEM
159
160
  pry-doc (0.11.1)
160
161
  pry (~> 0.9)
161
162
  yard (~> 0.9)
162
- rack (2.0.9)
163
+ rack (2.1.4)
163
164
  rack-protection (2.0.3)
164
165
  rack
165
166
  rack-test (0.8.2)
@@ -249,7 +250,7 @@ PLATFORMS
249
250
 
250
251
  DEPENDENCIES
251
252
  apisonator!
252
- async-redis (~> 0.4.1)
253
+ async-redis (~> 0.5)
253
254
  async-rspec
254
255
  benchmark-ips (~> 2.7.2)
255
256
  bugsnag (~> 6)
@@ -267,7 +268,7 @@ DEPENDENCIES
267
268
  pry-byebug (~> 3.5.1)
268
269
  pry-doc (~> 0.11.1)
269
270
  puma!
270
- rack (~> 2.0.8)
271
+ rack (~> 2.1.4)
271
272
  rack-test (~> 0.8.2)
272
273
  rake (~> 13.0)
273
274
  redis!
@@ -7,6 +7,14 @@ module ThreeScale
7
7
  ServiceToken.exists?(token, service_id) ? 200 : 404
8
8
  end
9
9
 
10
+ get '/:token/:service_id/provider_key' do |token, service_id|
11
+ if ServiceToken.exists?(token, service_id)
12
+ { status: :found, provider_key: Service.provider_key_for(service_id) }.to_json
13
+ else
14
+ respond_with_404('token/service combination not found'.freeze)
15
+ end
16
+ end
17
+
10
18
  post '/' do
11
19
  check_tokens_param!
12
20
 
@@ -1,6 +1,7 @@
1
1
  require '3scale/backend/configuration/loader'
2
2
  require '3scale/backend/environment'
3
3
  require '3scale/backend/configurable'
4
+ require '3scale/backend/errors'
4
5
 
5
6
  module ThreeScale
6
7
  module Backend
@@ -77,9 +78,6 @@ module ThreeScale
77
78
  master_metrics = [:transactions, :transactions_authorize]
78
79
  config.master.metrics = Struct.new(*master_metrics).new
79
80
 
80
- # Default config
81
- config.master_service_id = 1
82
-
83
81
  # This setting controls whether the listener can create event buckets in
84
82
  # Redis. We do not want all the listeners creating buckets yet, as we do
85
83
  # not know exactly the rate at which we can send events to Kinesis
@@ -4,14 +4,36 @@ require 'rack'
4
4
  module ThreeScale
5
5
  module Backend
6
6
  class ListenerMetrics
7
- REQUEST_TYPES = {
7
+ AUTH_AND_REPORT_REQUEST_TYPES = {
8
8
  '/transactions/authorize.xml' => 'authorize',
9
9
  '/transactions/oauth_authorize.xml' => 'authorize_oauth',
10
10
  '/transactions/authrep.xml' => 'authrep',
11
11
  '/transactions/oauth_authrep.xml' => 'authrep_oauth',
12
12
  '/transactions.xml' => 'report'
13
13
  }
14
- private_constant :REQUEST_TYPES
14
+ private_constant :AUTH_AND_REPORT_REQUEST_TYPES
15
+
16
+ # Only the first match is taken into account, that's why for example,
17
+ # "/\/services\/.*\/stats/" needs to appear before "/\/services/"
18
+ INTERNAL_API_PATHS = [
19
+ [/\/services\/.*\/alert_limits/, 'alerts'.freeze],
20
+ [/\/services\/.*\/applications\/.*\/keys/, 'application_keys'.freeze],
21
+ [/\/services\/.*\/applications\/.*\/referrer_filters/, 'application_referrer_filters'.freeze],
22
+ [/\/services\/.*\/applications\/.*\/utilization/, 'utilization'.freeze],
23
+ [/\/services\/.*\/applications/, 'applications'.freeze],
24
+ [/\/services\/.*\/errors/, 'errors'.freeze],
25
+ [/\/events/, 'events'.freeze],
26
+ [/\/services\/.*\/metrics/, 'metrics'.freeze],
27
+ [/\/service_tokens/, 'service_tokens'.freeze],
28
+ [/\/services\/.*\/stats/, 'stats'.freeze],
29
+ [/\/services\/.*\/plans\/.*\/usagelimits/, 'usage_limits'.freeze],
30
+ [/\/services/, 'services'.freeze],
31
+ ].freeze
32
+ private_constant :INTERNAL_API_PATHS
33
+
34
+ # Most requests will be under 100ms, so use a higher granularity from there
35
+ TIME_BUCKETS = [0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.25, 0.5, 0.75, 1]
36
+ private_constant :TIME_BUCKETS
15
37
 
16
38
  class << self
17
39
  ERRORS_4XX_TO_TRACK = Set[403, 404, 409].freeze
@@ -27,9 +49,12 @@ module ThreeScale
27
49
  end
28
50
 
29
51
  def report_resp_code(path, resp_code)
30
- Yabeda.apisonator_listener.response_codes.increment(
52
+ req_type = req_type(path)
53
+ prometheus_group = prometheus_group(req_type)
54
+
55
+ Yabeda.send(prometheus_group).response_codes.increment(
31
56
  {
32
- request_type: REQUEST_TYPES[path],
57
+ request_type: req_type,
33
58
  resp_code: code_group(resp_code)
34
59
  },
35
60
  by: 1
@@ -37,8 +62,11 @@ module ThreeScale
37
62
  end
38
63
 
39
64
  def report_response_time(path, request_time)
40
- Yabeda.apisonator_listener.response_times.measure(
41
- { request_type: REQUEST_TYPES[path] },
65
+ req_type = req_type(path)
66
+ prometheus_group = prometheus_group(req_type)
67
+
68
+ Yabeda.send(prometheus_group).response_times.measure(
69
+ { request_type: req_type },
42
70
  request_time
43
71
  )
44
72
  end
@@ -69,8 +97,21 @@ module ThreeScale
69
97
  comment 'Response times'
70
98
  unit :seconds
71
99
  tags %i[request_type]
72
- # Most requests will be under 100ms, so use a higher granularity from there
73
- buckets [0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.25, 0.5, 0.75, 1]
100
+ buckets TIME_BUCKETS
101
+ end
102
+ end
103
+
104
+ group :apisonator_listener_internal_api do
105
+ counter :response_codes do
106
+ comment 'Response codes'
107
+ tags %i[request_type resp_code]
108
+ end
109
+
110
+ histogram :response_times do
111
+ comment 'Response times'
112
+ unit :seconds
113
+ tags %i[request_type]
114
+ buckets TIME_BUCKETS
74
115
  end
75
116
  end
76
117
  end
@@ -93,6 +134,24 @@ module ThreeScale
93
134
  'unknown'.freeze
94
135
  end
95
136
  end
137
+
138
+ def req_type(path)
139
+ AUTH_AND_REPORT_REQUEST_TYPES[path] || internal_api_req_type(path)
140
+ end
141
+
142
+ def internal_api_req_type(path)
143
+ (_regex, type) = INTERNAL_API_PATHS.find { |(regex, _)| regex.match path }
144
+ type
145
+ end
146
+
147
+ # Returns the group as defined in .define_metrics
148
+ def prometheus_group(request_type)
149
+ if AUTH_AND_REPORT_REQUEST_TYPES.values.include? request_type
150
+ :apisonator_listener
151
+ else
152
+ :apisonator_listener_internal_api
153
+ end
154
+ end
96
155
  end
97
156
  end
98
157
  end
@@ -8,7 +8,15 @@ module ThreeScale
8
8
 
9
9
  def call(env)
10
10
  began_at = Time.now.getutc
11
- status, header, body = @app.call(env)
11
+
12
+ begin
13
+ status, header, body = @app.call(env)
14
+ rescue Exception => e
15
+ ListenerMetrics.report_resp_code(env['REQUEST_PATH'], 500)
16
+ ListenerMetrics.report_response_time(env['REQUEST_PATH'], Time.now - began_at)
17
+ raise e
18
+ end
19
+
12
20
  ListenerMetrics.report_resp_code(env['REQUEST_PATH'], status)
13
21
  ListenerMetrics.report_response_time(env['REQUEST_PATH'], Time.now - began_at)
14
22
  [status, header, body]
@@ -47,7 +47,7 @@ module ThreeScale
47
47
 
48
48
  endpoint = Async::IO::Endpoint.tcp(host, port)
49
49
  @redis_async = Async::Redis::Client.new(
50
- endpoint, connection_limit: opts[:max_connections]
50
+ endpoint, limit: opts[:max_connections]
51
51
  )
52
52
  @building_pipeline = false
53
53
  end
@@ -20,8 +20,14 @@ module ThreeScale
20
20
  def report(provider_key, service_id, transactions, context_info = {})
21
21
  service = Service.load_with_provider_key!(service_id, provider_key)
22
22
 
23
- report_enqueue(service.id, transactions, context_info)
24
- notify_report(provider_key, transactions.size)
23
+ # A usage of 0 does not affect rate-limits or stats, so we do not need
24
+ # to report it.
25
+ filtered_transactions = filter_usages_with_0(transactions.clone)
26
+
27
+ return if filtered_transactions.empty?
28
+
29
+ report_enqueue(service.id, filtered_transactions, context_info)
30
+ notify_report(provider_key, filtered_transactions.size)
25
31
  end
26
32
 
27
33
  def authorize(provider_key, params, context_info = {})
@@ -137,9 +143,17 @@ module ThreeScale
137
143
 
138
144
  usage = params[:usage]
139
145
 
140
- if (usage || params[:log]) && status.authorized?
146
+ filtered_usage = filter_metrics_without_inc(usage.clone) if usage
147
+
148
+ if ((filtered_usage && !filtered_usage.empty?) || params[:log]) && status.authorized?
141
149
  application_id = status.application.id
142
- report_enqueue(status.service_id, { 0 => {"app_id" => application_id, "usage" => usage, "log" => params[:log] } }, request: { extensions: request_info[:extensions] })
150
+
151
+ report_enqueue(
152
+ status.service_id,
153
+ { 0 => {"app_id" => application_id, "usage" => filtered_usage, "log" => params[:log] } },
154
+ request: { extensions: request_info[:extensions] }
155
+ )
156
+
143
157
  notify_authrep(provider_key, usage ? 1 : 0)
144
158
  else
145
159
  notify_authorize(provider_key)
@@ -182,6 +196,19 @@ module ThreeScale
182
196
  end
183
197
  end
184
198
 
199
+ def filter_usages_with_0(transactions)
200
+ # There are plenty of existing tests using both a string and a symbol
201
+ # when accessing the usage.
202
+ transactions.delete_if do |_idx, tx|
203
+ (usage = tx['usage'.freeze] || tx[:usage]) or next
204
+ filter_metrics_without_inc(usage).empty?
205
+ end
206
+ end
207
+
208
+ def filter_metrics_without_inc(usage)
209
+ usage.delete_if { |_metric, delta| delta.to_s == '0'.freeze }
210
+ end
211
+
185
212
  def storage
186
213
  Storage.instance
187
214
  end
@@ -30,9 +30,13 @@ module ThreeScale
30
30
  end
31
31
 
32
32
  def notify(provider_key, usage)
33
- # batch several notifications together so that we can process just one
33
+ # We need the master service ID to report its metrics. If it's not
34
+ # set, we don't need to notify anything.
35
+ # Batch several notifications together so that we can process just one
34
36
  # job for a group of them.
35
- notify_batch(provider_key, usage)
37
+ unless configuration.master_service_id.to_s.empty?
38
+ notify_batch(provider_key, usage)
39
+ end
36
40
  end
37
41
 
38
42
  def notify_batch(provider_key, usage)
@@ -7,8 +7,6 @@ module ThreeScale
7
7
  extend Configurable
8
8
  @queue = :main
9
9
 
10
- InvalidMasterServiceId = Class.new(ThreeScale::Backend::Error)
11
-
12
10
  class << self
13
11
  def perform_logged(provider_key, usage, timestamp, _enqueue_time)
14
12
  application_id = Application.load_id_by_key(master_service_id, provider_key)
@@ -16,12 +14,42 @@ module ThreeScale
16
14
  if application_id && Application.exists?(master_service_id, application_id)
17
15
  master_metrics = Metric.load_all(master_service_id)
18
16
 
19
- ProcessJob.perform([{
20
- service_id: master_service_id,
21
- application_id: application_id,
22
- timestamp: timestamp,
23
- usage: master_metrics.process_usage(usage)
24
- }])
17
+ begin
18
+ ProcessJob.perform([{
19
+ service_id: master_service_id,
20
+ application_id: application_id,
21
+ timestamp: timestamp,
22
+ usage: master_metrics.process_usage(usage)
23
+ }])
24
+ rescue MetricInvalid => e
25
+ # This happens when the master account in Porta does not have
26
+ # the notify metrics defined (by default "transactions" and
27
+ # "transactions/authorize"). These metrics need to be created in
28
+ # Porta, Apisonator does not have a way to guarantee that
29
+ # they're defined.
30
+ # Notice that this rescue prevents the job from being retried.
31
+ # Apisonator can't know when the metrics will be created (if
32
+ # ever) so it's better to log the error rather than retrying
33
+ # these jobs for an undefined period of time.
34
+ Worker.logger.notify(e)
35
+ return [false, "#{e}"]
36
+ rescue TransactionTimestampNotWithinRange => e
37
+ # This is very unlikely to happen. The timestamps in a notify
38
+ # job are not set by users, they are set by the listeners. If
39
+ # this error happens it might mean that:
40
+ # a) The worker started processing this job way after the
41
+ # listener produced it. This can happen for example if we make
42
+ # some requests to a listener with no workers. The listeners
43
+ # will enqueue some notify jobs. If we start a worker hours
44
+ # later, we might see this error.
45
+ # b) There's some kind of clock skew issue.
46
+ # c) There's a bug.
47
+ #
48
+ # We can't raise here, because then, the job will be retried,
49
+ # but it's going to fail always if it has an old timestamp.
50
+ Worker.logger.notify(e)
51
+ return [false, "#{provider_key} #{application_id} #{e}"]
52
+ end
25
53
  end
26
54
  [true, "#{provider_key} #{application_id || '--'}"]
27
55
  end
@@ -29,15 +57,7 @@ module ThreeScale
29
57
  private
30
58
 
31
59
  def master_service_id
32
- value = configuration.master_service_id
33
-
34
- unless value
35
- raise InvalidMasterServiceId,
36
- "Can't find master service id. Make sure the \"master_service_id\" "\
37
- 'configuration value is set correctly'
38
- end
39
-
40
- value.to_s
60
+ configuration.master_service_id.to_s
41
61
  end
42
62
  end
43
63
  end
@@ -1,5 +1,5 @@
1
1
  module ThreeScale
2
2
  module Backend
3
- VERSION = '3.0.0'
3
+ VERSION = '3.2.1'
4
4
  end
5
5
  end
@@ -23,7 +23,7 @@
23
23
  </dependency>
24
24
  <dependency>
25
25
  <packageName>apisonator</packageName>
26
- <version>3.0.0</version>
26
+ <version>3.2.1</version>
27
27
  <licenses>
28
28
  <license>
29
29
  <name>Apache 2.0</name>
@@ -73,7 +73,7 @@
73
73
  </dependency>
74
74
  <dependency>
75
75
  <packageName>async-io</packageName>
76
- <version>1.27.5</version>
76
+ <version>1.27.7</version>
77
77
  <licenses>
78
78
  <license>
79
79
  <name>MIT</name>
@@ -93,7 +93,7 @@
93
93
  </dependency>
94
94
  <dependency>
95
95
  <packageName>async-redis</packageName>
96
- <version>0.4.1</version>
96
+ <version>0.5.0</version>
97
97
  <licenses>
98
98
  <license>
99
99
  <name>MIT</name>
@@ -371,7 +371,7 @@
371
371
  </dependency>
372
372
  <dependency>
373
373
  <packageName>json</packageName>
374
- <version>2.1.0</version>
374
+ <version>2.3.1</version>
375
375
  <licenses>
376
376
  <license>
377
377
  <name>ruby</name>
@@ -669,7 +669,7 @@
669
669
  </dependency>
670
670
  <dependency>
671
671
  <packageName>protocol-redis</packageName>
672
- <version>0.2.0</version>
672
+ <version>0.5.0</version>
673
673
  <licenses>
674
674
  <license>
675
675
  <name>MIT</name>
@@ -719,7 +719,7 @@
719
719
  </dependency>
720
720
  <dependency>
721
721
  <packageName>rack</packageName>
722
- <version>2.0.9</version>
722
+ <version>2.1.4</version>
723
723
  <licenses>
724
724
  <license>
725
725
  <name>MIT</name>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apisonator
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Ciganek
@@ -16,7 +16,7 @@ authors:
16
16
  autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
- date: 2020-06-19 00:00:00.000000000 Z
19
+ date: 2021-01-22 00:00:00.000000000 Z
20
20
  dependencies: []
21
21
  description: This gem provides a daemon that handles authorization and reporting of
22
22
  web services managed by 3scale.