apisonator 2.100.0 → 2.101.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '02689c2d07caa6e88eb1079c13064378fafa921ffb28e4da095cd8ad5fbac578'
4
- data.tar.gz: 434d69fc1eb06088b1c4111bd41979567f1b00c22b149e5b4a7bdbda48c447a1
3
+ metadata.gz: 4740b1613c8bd2182adf9587db2a2ae6667a50ee140c99c679c232b6da3b7193
4
+ data.tar.gz: 0e34376e2e788194b44eeb5aedf7d8654110c8baa4a0885ed2c55a3a28fcb0c1
5
5
  SHA512:
6
- metadata.gz: edc21e4dedc90447e734e7afe0fe681127d9a4a88cd4ba3d9f9633b7eae3ee31488aa54b9cfaaeb6e28c158eb822c9679e325c4b6773130779fd63f5a6498fe9
7
- data.tar.gz: 3267cfad364babfafb0c563feea99ecd0ff346b7a12d224b37178ff28e13a92fcce8a25372b1901f54a1bfcf6ecdeea0f9665ac2e30dcc6fe0fa3aff15bce468
6
+ metadata.gz: c6431c06f07433710308ef8b9121d2975415cbec27d2c82db3c8f13c4a0dab364b6a9085a550a530bd000a18234bfd63d67ee555ea69299f8745734725f9f436
7
+ data.tar.gz: 90618d349784bfe5ff9d78b940f93d7b63013fb9f1ec1b9c68f03881ff9e13a165d0532a98d50c26218402cc197c3f9f730f7b34ca26589cb8f4b91fa37e6cab
@@ -2,6 +2,46 @@
2
2
 
3
3
  Notable changes to Apisonator will be tracked in this document.
4
4
 
5
+ ## 2.101.0 - 2020-06-04
6
+
7
+ ### Added
8
+
9
+ - Introduced the `CONFIG_REDIS_MAX_CONNS` and `CONFIG_QUEUES_MAX_CONNS` ENVs to
10
+ configure the max number of Redis connections when using the async mode
11
+ ([#214](https://github.com/3scale/apisonator/pull/214)).
12
+
13
+ ### Changed
14
+
15
+ - Perf optimization: loading the usage limits is now done more efficiently.
16
+ There is a noticeable improvement in requests with `no_body` enabled for
17
+ services with many metrics defined
18
+ ([#221](https://github.com/3scale/apisonator/pull/221)).
19
+ - Updated activesupport to 5.2.4.3
20
+ ([#217](https://github.com/3scale/apisonator/pull/217)).
21
+
22
+
23
+ ## 2.100.2 - 2020-05-08
24
+
25
+ ### Changed
26
+
27
+ - The Prometheus histogram buckets of the workers have been adjusted to be more
28
+ informative ([#208](https://github.com/3scale/apisonator/pull/208)).
29
+
30
+ ### Removed
31
+
32
+ - The deprecated endpoints to create, delete, and list oauth tokens have been
33
+ disabled ([#212](https://github.com/3scale/apisonator/pull/212)).
34
+
35
+
36
+ ## 2.100.1 - 2020-04-22
37
+
38
+ ### Changed
39
+
40
+ - Now we are using our own redis-rb fork. It includes a fix that should reduce
41
+ the number of 5xx errors caused by Redis connection errors
42
+ ([#205](https://github.com/3scale/apisonator/pull/205)).
43
+ - Updated hiredis to v0.6.3 ([#204](https://github.com/3scale/apisonator/pull/204)).
44
+
5
45
  ## 2.100.0 - 2020-04-21
6
46
 
7
47
  ### Added
@@ -9,7 +9,7 @@ gemspec
9
9
  # implementations (ie. pure Ruby, java, etc).
10
10
  #
11
11
  platform :ruby do
12
- gem 'hiredis', '= 0.6.1'
12
+ gem 'hiredis', '~> 0.6.1'
13
13
  gem 'yajl-ruby', '~> 1.3.1', require: 'yajl'
14
14
  gem 'pry-byebug', '~> 3.5.1', groups: [:development]
15
15
  end
@@ -25,7 +25,6 @@ group :test do
25
25
  gem 'resque_spec', '~> 0.17.0'
26
26
  gem 'timecop', '~> 0.9.1'
27
27
  gem 'rspec', '~> 3.7.0', require: nil
28
- gem 'geminabox', '~> 0.13.11', require: false
29
28
  gem 'codeclimate-test-reporter', '~> 0.6.0', require: nil
30
29
  gem 'async-rspec'
31
30
  end
@@ -52,7 +51,6 @@ gem 'daemons', '= 1.2.4'
52
51
  # Production gems
53
52
  gem 'rake', '~> 13.0'
54
53
  gem 'builder', '= 3.2.3'
55
- gem 'redis', '= 4.1.1'
56
54
  # Use a patched resque to allow reusing their Airbrake Failure class
57
55
  gem 'resque', git: 'https://github.com/3scale/resque', branch: '3scale'
58
56
  gem 'rack', '~> 2.0.8'
@@ -63,3 +61,8 @@ gem 'bugsnag', '~> 6', require: nil
63
61
  gem 'yabeda-prometheus', '~> 0.5.0'
64
62
  gem 'async-redis', '~> 0.4.1'
65
63
  gem 'falcon', '~> 0.35'
64
+
65
+ # Use a patched redis-rb that fixes an issue when trying to connect with
66
+ # sentinels and avoids retrying calls when there's a timeout to prevent
67
+ # duplicated commands. It's based on version 4.1.3.
68
+ gem 'redis', git: 'https://github.com/3scale/redis-rb', branch: 'apisonator'
@@ -5,6 +5,13 @@ GIT
5
5
  specs:
6
6
  puma (2.15.3)
7
7
 
8
+ GIT
9
+ remote: https://github.com/3scale/redis-rb
10
+ revision: 35301b3d952975300a4cb30d408ae3b5969d0440
11
+ branch: apisonator
12
+ specs:
13
+ redis (4.1.3)
14
+
8
15
  GIT
9
16
  remote: https://github.com/3scale/resque
10
17
  revision: 88839e71756ea9b6edfc9426a0af71e94109c135
@@ -28,14 +35,14 @@ GIT
28
35
  PATH
29
36
  remote: .
30
37
  specs:
31
- apisonator (2.100.0)
38
+ apisonator (2.101.0)
32
39
 
33
40
  GEM
34
41
  remote: https://rubygems.org/
35
42
  specs:
36
- activesupport (5.1.4)
43
+ activesupport (5.2.4.3)
37
44
  concurrent-ruby (~> 1.0, >= 1.0.2)
38
- i18n (~> 0.7)
45
+ i18n (>= 0.7, < 2)
39
46
  minitest (~> 5.1)
40
47
  tzinfo (~> 1.1)
41
48
  airbrake (4.3.1)
@@ -88,7 +95,7 @@ GEM
88
95
  codeclimate-test-reporter (0.6.0)
89
96
  simplecov (>= 0.7.1, < 1.0.0)
90
97
  coderay (1.1.2)
91
- concurrent-ruby (1.0.5)
98
+ concurrent-ruby (1.1.6)
92
99
  console (1.8.2)
93
100
  daemons (1.2.4)
94
101
  diff-lcs (1.3)
@@ -105,20 +112,10 @@ GEM
105
112
  process-metrics (~> 0.1.0)
106
113
  rack (>= 1.0)
107
114
  samovar (~> 2.1)
108
- faraday (0.13.1)
109
- multipart-post (>= 1.2, < 3)
110
115
  ffi (1.12.2)
111
- geminabox (0.13.11)
112
- builder
113
- faraday
114
- httpclient (>= 2.2.7)
115
- nesty
116
- reentrant_flock
117
- sinatra (>= 1.2.7)
118
116
  gli (2.16.1)
119
- hiredis (0.6.1)
120
- httpclient (2.8.3)
121
- i18n (0.9.1)
117
+ hiredis (0.6.3)
118
+ i18n (1.8.2)
122
119
  concurrent-ruby (~> 1.0)
123
120
  jmespath (1.3.1)
124
121
  json (2.1.0)
@@ -134,15 +131,13 @@ GEM
134
131
  metaclass (0.0.4)
135
132
  method_source (0.9.0)
136
133
  mini_portile2 (2.4.0)
137
- minitest (5.10.3)
134
+ minitest (5.14.1)
138
135
  mocha (1.3.0)
139
136
  metaclass (~> 0.0.1)
140
137
  mono_logger (1.1.0)
141
138
  multi_json (1.13.1)
142
- multipart-post (2.0.0)
143
139
  mustache (1.0.5)
144
140
  mustermann (1.0.2)
145
- nesty (1.0.2)
146
141
  net-scp (1.2.1)
147
142
  net-ssh (>= 2.6.5)
148
143
  net-ssh (4.2.0)
@@ -182,10 +177,8 @@ GEM
182
177
  rack-test (0.8.2)
183
178
  rack (>= 1.0, < 3)
184
179
  rake (13.0.1)
185
- redis (4.1.1)
186
180
  redis-namespace (1.6.0)
187
181
  redis (>= 3.0.4)
188
- reentrant_flock (0.1.1)
189
182
  resque_spec (0.17.0)
190
183
  resque (>= 1.19.0)
191
184
  rspec-core (>= 3.0.0)
@@ -250,7 +243,7 @@ GEM
250
243
  timers (4.3.0)
251
244
  toml (0.2.0)
252
245
  parslet (~> 1.8.0)
253
- tzinfo (1.2.4)
246
+ tzinfo (1.2.7)
254
247
  thread_safe (~> 0.1)
255
248
  vegas (0.1.11)
256
249
  rack (>= 1.0.0)
@@ -282,9 +275,8 @@ DEPENDENCIES
282
275
  codeclimate-test-reporter (~> 0.6.0)
283
276
  daemons (= 1.2.4)
284
277
  falcon (~> 0.35)
285
- geminabox (~> 0.13.11)
286
278
  gli (~> 2.16.1)
287
- hiredis (= 0.6.1)
279
+ hiredis (~> 0.6.1)
288
280
  license_finder (~> 5)
289
281
  mocha (~> 1.3)
290
282
  nokogiri (~> 1.10.8)
@@ -297,7 +289,7 @@ DEPENDENCIES
297
289
  rack (~> 2.0.8)
298
290
  rack-test (~> 0.8.2)
299
291
  rake (~> 13.0)
300
- redis (= 4.1.1)
292
+ redis!
301
293
  resque!
302
294
  resque_spec (~> 0.17.0)
303
295
  resque_unit (~> 0.4.4)!
@@ -5,6 +5,13 @@ GIT
5
5
  specs:
6
6
  puma (2.15.3)
7
7
 
8
+ GIT
9
+ remote: https://github.com/3scale/redis-rb
10
+ revision: 35301b3d952975300a4cb30d408ae3b5969d0440
11
+ branch: apisonator
12
+ specs:
13
+ redis (4.1.3)
14
+
8
15
  GIT
9
16
  remote: https://github.com/3scale/resque
10
17
  revision: 88839e71756ea9b6edfc9426a0af71e94109c135
@@ -28,14 +35,14 @@ GIT
28
35
  PATH
29
36
  remote: .
30
37
  specs:
31
- apisonator (2.100.0)
38
+ apisonator (2.101.0)
32
39
 
33
40
  GEM
34
41
  remote: https://rubygems.org/
35
42
  specs:
36
- activesupport (5.1.4)
43
+ activesupport (5.2.4.3)
37
44
  concurrent-ruby (~> 1.0, >= 1.0.2)
38
- i18n (~> 0.7)
45
+ i18n (>= 0.7, < 2)
39
46
  minitest (~> 5.1)
40
47
  tzinfo (~> 1.1)
41
48
  async (1.24.2)
@@ -78,7 +85,7 @@ GEM
78
85
  codeclimate-test-reporter (0.6.0)
79
86
  simplecov (>= 0.7.1, < 1.0.0)
80
87
  coderay (1.1.2)
81
- concurrent-ruby (1.0.5)
88
+ concurrent-ruby (1.1.6)
82
89
  console (1.8.2)
83
90
  daemons (1.2.4)
84
91
  diff-lcs (1.3)
@@ -95,20 +102,10 @@ GEM
95
102
  process-metrics (~> 0.1.0)
96
103
  rack (>= 1.0)
97
104
  samovar (~> 2.1)
98
- faraday (0.13.1)
99
- multipart-post (>= 1.2, < 3)
100
105
  ffi (1.12.2)
101
- geminabox (0.13.11)
102
- builder
103
- faraday
104
- httpclient (>= 2.2.7)
105
- nesty
106
- reentrant_flock
107
- sinatra (>= 1.2.7)
108
106
  gli (2.16.1)
109
- hiredis (0.6.1)
110
- httpclient (2.8.3)
111
- i18n (0.9.1)
107
+ hiredis (0.6.3)
108
+ i18n (1.8.2)
112
109
  concurrent-ruby (~> 1.0)
113
110
  json (2.1.0)
114
111
  license_finder (5.9.2)
@@ -123,15 +120,13 @@ GEM
123
120
  metaclass (0.0.4)
124
121
  method_source (0.9.0)
125
122
  mini_portile2 (2.4.0)
126
- minitest (5.10.3)
123
+ minitest (5.14.1)
127
124
  mocha (1.3.0)
128
125
  metaclass (~> 0.0.1)
129
126
  mono_logger (1.1.0)
130
127
  multi_json (1.13.1)
131
- multipart-post (2.0.0)
132
128
  mustache (1.0.5)
133
129
  mustermann (1.0.2)
134
- nesty (1.0.2)
135
130
  net-scp (1.2.1)
136
131
  net-ssh (>= 2.6.5)
137
132
  net-ssh (4.2.0)
@@ -170,10 +165,8 @@ GEM
170
165
  rack-test (0.8.2)
171
166
  rack (>= 1.0, < 3)
172
167
  rake (13.0.1)
173
- redis (4.1.1)
174
168
  redis-namespace (1.6.0)
175
169
  redis (>= 3.0.4)
176
- reentrant_flock (0.1.1)
177
170
  resque_spec (0.17.0)
178
171
  resque (>= 1.19.0)
179
172
  rspec-core (>= 3.0.0)
@@ -236,7 +229,7 @@ GEM
236
229
  timers (4.3.0)
237
230
  toml (0.2.0)
238
231
  parslet (~> 1.8.0)
239
- tzinfo (1.2.4)
232
+ tzinfo (1.2.7)
240
233
  thread_safe (~> 0.1)
241
234
  vegas (0.1.11)
242
235
  rack (>= 1.0.0)
@@ -264,9 +257,8 @@ DEPENDENCIES
264
257
  codeclimate-test-reporter (~> 0.6.0)
265
258
  daemons (= 1.2.4)
266
259
  falcon (~> 0.35)
267
- geminabox (~> 0.13.11)
268
260
  gli (~> 2.16.1)
269
- hiredis (= 0.6.1)
261
+ hiredis (~> 0.6.1)
270
262
  license_finder (~> 5)
271
263
  mocha (~> 1.3)
272
264
  nokogiri (~> 1.10.8)
@@ -278,7 +270,7 @@ DEPENDENCIES
278
270
  rack (~> 2.0.8)
279
271
  rack-test (~> 0.8.2)
280
272
  rake (~> 13.0)
281
- redis (= 4.1.1)
273
+ redis!
282
274
  resque!
283
275
  resque_spec (~> 0.17.0)
284
276
  resque_unit (~> 0.4.4)!
@@ -5,7 +5,6 @@ require 'builder'
5
5
  require 'hiredis'
6
6
 
7
7
  require 'redis'
8
- require '3scale/backend/extensions/redis'
9
8
 
10
9
  require 'resque'
11
10
  require 'securerandom'
@@ -223,6 +223,24 @@ module ThreeScale
223
223
  @usage_limits ||= UsageLimit.load_all(service_id, plan_id)
224
224
  end
225
225
 
226
+ def load_all_usage_limits
227
+ @usage_limits = UsageLimit.load_all(service_id, plan_id)
228
+ end
229
+
230
+ # Loads the usage limits affected by the metrics received, that is, the
231
+ # limits that are defined for those metrics plus all their ancestors in
232
+ # the metrics hierarchy.
233
+ def load_usage_limits_affected_by(metric_names)
234
+ metric_ids = metric_names.flat_map do |name|
235
+ [name] + Metric.ascendants(service_id, name)
236
+ end.uniq.map do |name|
237
+ Metric.load_id(service_id, name)
238
+ end
239
+
240
+ # IDs are sorted to be able to use the memoizer
241
+ @usage_limits = UsageLimit.load_for_affecting_metrics(service_id, plan_id, metric_ids.sort)
242
+ end
243
+
226
244
  def active?
227
245
  state == :active
228
246
  end
@@ -46,9 +46,9 @@ module ThreeScale
46
46
 
47
47
  # Add configuration sections
48
48
  config.add_section(:queues, :master_name, :sentinels, :role,
49
- :connect_timeout, :read_timeout, :write_timeout)
49
+ :connect_timeout, :read_timeout, :write_timeout, :max_connections)
50
50
  config.add_section(:redis, :url, :proxy, :sentinels, :role,
51
- :connect_timeout, :read_timeout, :write_timeout,
51
+ :connect_timeout, :read_timeout, :write_timeout, :max_connections,
52
52
  :async)
53
53
  config.add_section(:analytics_redis, :server,
54
54
  :connect_timeout, :read_timeout, :write_timeout)
@@ -12,9 +12,9 @@ module ThreeScale
12
12
  include Logging
13
13
 
14
14
  ## ------------ DOCS --------------
15
- ##~ namespace = ENV['SAAS_SWAGGER'] == "1" ? "Service Management API" : "Service Management API (on-premises)"
15
+ ##~ namespace = "Service Management API"
16
16
  ##~ sapi = source2swagger.namespace(namespace)
17
- ##~ sapi.basePath = "https://su1.3scale.net"
17
+ ##~ sapi.basePath = ""
18
18
  ##~ sapi.swaggerVersion = "0.1a"
19
19
  ##~ sapi.apiVersion = "1.0"
20
20
  ##
@@ -190,7 +190,7 @@ module ThreeScale
190
190
  private :do_api_method
191
191
 
192
192
  ## ------------ DOCS --------------
193
- ##~ namespace = ENV['SAAS_SWAGGER'] == "1" ? "Service Management API" : "Service Management API (on-premises)"
193
+ ##~ namespace = "Service Management API"
194
194
  ##~ sapi = source2swagger.namespace(namespace)
195
195
  ##~ a = sapi.apis.add
196
196
  ##~ a.set "path" => "/transactions/authorize.xml", "format" => "xml"
@@ -243,7 +243,7 @@ module ThreeScale
243
243
  end
244
244
 
245
245
  ## ------------ DOCS --------------
246
- ##~ namespace = ENV['SAAS_SWAGGER'] == "1" ? "Service Management API" : "Service Management API (on-premises)"
246
+ ##~ namespace = "Service Management API"
247
247
  ##~ sapi = source2swagger.namespace(namespace)
248
248
  ##~ a = sapi.apis.add
249
249
  ##~ a.set "path" => "/transactions/oauth_authorize.xml", "format" => "xml"
@@ -276,7 +276,7 @@ module ThreeScale
276
276
  end
277
277
 
278
278
  ## ------------ DOCS --------------
279
- ##~ namespace = ENV['SAAS_SWAGGER'] == "1" ? "Service Management API" : "Service Management API (on-premises)"
279
+ ##~ namespace = "Service Management API"
280
280
  ##~ sapi = source2swagger.namespace(namespace)
281
281
  ##~ a = sapi.apis.add
282
282
  ##~ a.set "path" => "/transactions/authrep.xml", "format" => "xml"
@@ -323,7 +323,7 @@ module ThreeScale
323
323
  end
324
324
 
325
325
  ## ------------ DOCS --------------
326
- ##~ namespace = ENV['SAAS_SWAGGER'] == "1" ? "Service Management API" : "Service Management API (on-premises)"
326
+ ##~ namespace = "Service Management API"
327
327
  ##~ sapi = source2swagger.namespace(namespace)
328
328
  ##~ a = sapi.apis.add
329
329
  ##~ a.set "path" => "/transactions/oauth_authrep.xml", "format" => "xml"
@@ -351,7 +351,7 @@ module ThreeScale
351
351
  end
352
352
 
353
353
  ## ------------ DOCS --------------
354
- ##~ namespace = ENV['SAAS_SWAGGER'] == "1" ? "Service Management API" : "Service Management API (on-premises)"
354
+ ##~ namespace = "Service Management API"
355
355
  ##~ sapi = source2swagger.namespace(namespace)
356
356
  ##~ a = sapi.apis.add
357
357
  ##~ a.set "path" => "/transactions.xml", "format" => "xml"
@@ -432,54 +432,58 @@ module ThreeScale
432
432
 
433
433
  ## OAUTH ACCESS TOKENS
434
434
 
435
- post '/services/:service_id/oauth_access_tokens.xml' do
436
- check_post_content_type!
437
- require_params! :service_id, :token
435
+ # These endpoints are deprecated and are going to be removed. For now,
436
+ # let's disable them.
437
+ if Backend.test?
438
+ post '/services/:service_id/oauth_access_tokens.xml' do
439
+ check_post_content_type!
440
+ require_params! :service_id, :token
438
441
 
439
- service_id = params[:service_id]
440
- ensure_authenticated!(params[:provider_key], params[:service_token], service_id)
442
+ service_id = params[:service_id]
443
+ ensure_authenticated!(params[:provider_key], params[:service_token], service_id)
441
444
 
442
- app_id = params[:app_id]
443
- raise ApplicationNotFound, app_id unless Application.exists?(service_id, app_id)
445
+ app_id = params[:app_id]
446
+ raise ApplicationNotFound, app_id unless Application.exists?(service_id, app_id)
444
447
 
445
- OAuth::Token::Storage.create(params[:token], service_id, app_id, params[:ttl])
446
- end
448
+ OAuth::Token::Storage.create(params[:token], service_id, app_id, params[:ttl])
449
+ end
447
450
 
448
- delete '/services/:service_id/oauth_access_tokens/:token.xml' do
449
- require_params! :service_id, :token
451
+ delete '/services/:service_id/oauth_access_tokens/:token.xml' do
452
+ require_params! :service_id, :token
450
453
 
451
- service_id = params[:service_id]
452
- ensure_authenticated!(params[:provider_key], params[:service_token], service_id)
454
+ service_id = params[:service_id]
455
+ ensure_authenticated!(params[:provider_key], params[:service_token], service_id)
453
456
 
454
- token = params[:token]
457
+ token = params[:token]
455
458
 
456
- # TODO: perhaps improve this to list the deleted tokens?
457
- raise AccessTokenInvalid, token unless OAuth::Token::Storage.delete(token, service_id)
458
- end
459
+ # TODO: perhaps improve this to list the deleted tokens?
460
+ raise AccessTokenInvalid, token unless OAuth::Token::Storage.delete(token, service_id)
461
+ end
459
462
 
460
- get '/services/:service_id/applications/:app_id/oauth_access_tokens.xml' do
461
- require_params! :service_id, :app_id
463
+ get '/services/:service_id/applications/:app_id/oauth_access_tokens.xml' do
464
+ require_params! :service_id, :app_id
462
465
 
463
- service_id = params[:service_id]
464
- ensure_authenticated!(params[:provider_key], params[:service_token], service_id)
466
+ service_id = params[:service_id]
467
+ ensure_authenticated!(params[:provider_key], params[:service_token], service_id)
465
468
 
466
- app_id = params[:app_id]
469
+ app_id = params[:app_id]
467
470
 
468
- raise ApplicationNotFound, app_id unless Application.exists?(service_id, app_id)
471
+ raise ApplicationNotFound, app_id unless Application.exists?(service_id, app_id)
469
472
 
470
- @tokens = OAuth::Token::Storage.all_by_service_and_app service_id, app_id
471
- builder :oauth_access_tokens
472
- end
473
+ @tokens = OAuth::Token::Storage.all_by_service_and_app service_id, app_id
474
+ builder :oauth_access_tokens
475
+ end
473
476
 
474
- get '/services/:service_id/oauth_access_tokens/:token.xml' do
475
- require_params! :service_id, :token
477
+ get '/services/:service_id/oauth_access_tokens/:token.xml' do
478
+ require_params! :service_id, :token
476
479
 
477
- service_id = params[:service_id]
478
- ensure_authenticated!(params[:provider_key], params[:service_token], service_id)
480
+ service_id = params[:service_id]
481
+ ensure_authenticated!(params[:provider_key], params[:service_token], service_id)
479
482
 
480
- @token_to_app_id = OAuth::Token::Storage.get_credentials(params[:token], service_id)
483
+ @token_to_app_id = OAuth::Token::Storage.get_credentials(params[:token], service_id)
481
484
 
482
- builder :oauth_app_id_by_token
485
+ builder :oauth_app_id_by_token
486
+ end
483
487
  end
484
488
 
485
489
  get '/check.txt' do
@@ -600,10 +604,6 @@ module ThreeScale
600
604
  end
601
605
  end
602
606
 
603
- def application
604
- @application ||= Application.load_by_id_or_user_key!(service_id, params[:app_id], params[:user_key])
605
- end
606
-
607
607
  def service_id
608
608
  if params[:service_id].nil? || params[:service_id].empty?
609
609
  @service_id ||= Service.default_id!(params[:provider_key])
@@ -75,10 +75,7 @@ module ThreeScale
75
75
  end
76
76
 
77
77
  def load_metric_id(name)
78
- Memoizer.memoize_block(Memoizer.build_key(self,
79
- :load_metric_id, @service_id, name)) do
80
- storage.get(encode_key("metric/service_id:#{@service_id}/name:#{name}/id"))
81
- end || raise(MetricInvalid.new(name))
78
+ Metric.load_id(@service_id, name) || raise(MetricInvalid.new(name))
82
79
  end
83
80
 
84
81
  ## accepts postive integers or positive integers preffixed with # (for sets)
@@ -46,7 +46,9 @@ module ThreeScale
46
46
  port ||= DEFAULT_PORT
47
47
 
48
48
  endpoint = Async::IO::Endpoint.tcp(host, port)
49
- @redis_async = Async::Redis::Client.new(endpoint)
49
+ @redis_async = Async::Redis::Client.new(
50
+ endpoint, connection_limit: opts[:max_connections]
51
+ )
50
52
  @building_pipeline = false
51
53
  end
52
54
 
@@ -44,17 +44,26 @@ module ThreeScale
44
44
  connect_timeout: 5,
45
45
  read_timeout: 3,
46
46
  write_timeout: 3,
47
- # this is set to zero to avoid potential double transactions
48
- # see https://github.com/redis/redis-rb/issues/668
49
- reconnect_attempts: 0,
47
+ # Note that we can set reconnect_attempts to >= 0 because we use
48
+ # our redis-rb fork which implements a workaround for this issue
49
+ # that shows that when there might be duplicated transactions when
50
+ # there's a timeout: https://github.com/redis/redis-rb/issues/668
51
+ # We should investigate if there are edge cases that can lead to
52
+ # duplicated commands because of this setting.
53
+ reconnect_attempts: 1,
50
54
  # use by default the C extension client
51
- driver: :hiredis
55
+ driver: :hiredis,
56
+ # applies only to async mode. The sync library opens 1 connection
57
+ # per process.
58
+ max_connections: 10,
52
59
  }.freeze
53
60
  private_constant :CONN_OPTIONS
54
61
 
55
62
  # CONN_WHITELIST - Connection options that can be specified in config
56
63
  # Note: we don't expose reconnect_attempts until the bug above is fixed
57
- CONN_WHITELIST = [:connect_timeout, :read_timeout, :write_timeout].freeze
64
+ CONN_WHITELIST = [
65
+ :connect_timeout, :read_timeout, :write_timeout, :max_connections
66
+ ].freeze
58
67
  private_constant :CONN_WHITELIST
59
68
 
60
69
  # Parameters regarding target server we will take from a config object
@@ -87,9 +87,13 @@ module ThreeScale
87
87
  application = Application.load_by_id_or_user_key!(service_id,
88
88
  app_id,
89
89
  params[:user_key])
90
+
91
+ extensions = request_info && request_info[:extensions] || {}
92
+
93
+ preload_usage_limits(application, extensions[:no_body], params[:usage])
94
+
90
95
  now = Time.now.getutc
91
96
  usage_values = Usage.application_usage(application, now)
92
- extensions = request_info && request_info[:extensions] || {}
93
97
  status_attrs = {
94
98
  service_id: service_id,
95
99
  application: application,
@@ -169,6 +173,27 @@ module ThreeScale
169
173
  Resque.enqueue(ReportJob, service_id, data, Time.now.getutc.to_f, context_info)
170
174
  end
171
175
 
176
+ # Loads the usage limits that are needed to authorize the current request.
177
+ # These are the cases:
178
+ # - When no_body is enabled, we only need to load the limits related with
179
+ # the metrics included in the request, that is, the ones included plus all
180
+ # their ancestors in the hierarchy. That's all we need to verify if the
181
+ # request is within the limits defined.
182
+ # - When no_body is disabled, we need to load all the limits because they
183
+ # are needed to generate the XML response.
184
+ # - When the usage reported in the request is empty, apisonator returns
185
+ # "limits_exceeded" if any of the limits defined has been violated. That's
186
+ # why in that scenario we need to load all the limits.
187
+ def preload_usage_limits(application, no_body_enabled, usage_in_params)
188
+ metric_names_in_usage = usage_in_params&.keys || {}
189
+
190
+ if no_body_enabled && !metric_names_in_usage.empty?
191
+ application.load_usage_limits_affected_by(metric_names_in_usage)
192
+ else
193
+ application.load_all_usage_limits
194
+ end
195
+ end
196
+
172
197
  def storage
173
198
  Storage.instance
174
199
  end
@@ -80,11 +80,6 @@ module ThreeScale
80
80
  values && values[usage_limit.metric_id] || 0
81
81
  end
82
82
 
83
- def value_for_application_usage_limit(usage_limit)
84
- values = @values[usage_limit.period]
85
- values && values[usage_limit.metric_id] || 0
86
- end
87
-
88
83
  # provides a hierarchy hash with metrics as symbolic names
89
84
  def hierarchy
90
85
  @hierarchy ||= Metric.hierarchy service_id
@@ -22,20 +22,15 @@ module ThreeScale
22
22
 
23
23
  def load_all(service_id, plan_id)
24
24
  metric_ids = Metric.load_all_ids(service_id)
25
- return metric_ids if metric_ids.empty?
26
-
27
- results = []
28
- with_pairs_and_values service_id, plan_id, metric_ids do |pair, value|
29
- value and results << new(service_id: service_id,
30
- plan_id: plan_id,
31
- metric_id: pair[0],
32
- period: pair[1],
33
- value: value.to_i)
34
- end
35
- results
25
+ generate_for_metrics(service_id, plan_id, metric_ids)
36
26
  end
37
27
  memoize :load_all
38
28
 
29
+ def load_for_affecting_metrics(service_id, plan_id, metric_ids)
30
+ generate_for_metrics(service_id, plan_id, metric_ids)
31
+ end
32
+ memoize :load_for_affecting_metrics
33
+
39
34
  def load_value(service_id, plan_id, metric_id, period)
40
35
  raw_value = storage.get(key(service_id, plan_id, metric_id, period))
41
36
  raw_value and raw_value.to_i
@@ -80,6 +75,20 @@ module ThreeScale
80
75
  encode_key(key_pre + period.to_s)
81
76
  end
82
77
 
78
+ def generate_for_metrics(service_id, plan_id, metric_ids)
79
+ return metric_ids if metric_ids.empty?
80
+
81
+ results = []
82
+ with_pairs_and_values service_id, plan_id, metric_ids do |pair, value|
83
+ value and results << new(service_id: service_id,
84
+ plan_id: plan_id,
85
+ metric_id: pair[0],
86
+ period: pair[1],
87
+ value: value.to_i)
88
+ end
89
+ results
90
+ end
91
+
83
92
  # yields [pair(metric_id, period), value]
84
93
  def with_pairs_and_values(service_id, plan_id, metric_ids, &blk)
85
94
  pairs, values = get_pairs_and_values_for service_id, plan_id, metric_ids
@@ -1,5 +1,5 @@
1
1
  module ThreeScale
2
2
  module Backend
3
- VERSION = '2.100.0'
3
+ VERSION = '2.101.0'
4
4
  end
5
5
  end
@@ -11,7 +11,8 @@ Yabeda.configure do
11
11
  comment "How long jobs take to run"
12
12
  unit :seconds
13
13
  tags %i[type]
14
- buckets [0.005, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
14
+ # Most requests will be under 100ms, so use a higher granularity from there
15
+ 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]
15
16
  end
16
17
  end
17
18
  end
@@ -1,46 +1,28 @@
1
+ SPEC_FILE = 'docs/active_docs/Service Management API.json'
2
+
1
3
  def run_command cmd
2
4
  puts "--> executing: #{cmd}"
3
5
  puts "--> Remember to commit the resulting specs to the Porta repo."
4
6
  system cmd
5
7
  end
6
8
 
7
- # The file name depends on the 'namespace' defined in the Listener.
8
- def spec_file(type)
9
- res = 'docs/active_docs/Service Management API'
10
- res << ' (on-premises)' if type == :on_prem
11
- "#{res}.json"
12
- end
13
-
14
- def generate_docs(type)
15
- spec = spec_file(type)
16
- cmd = type == :saas ? 'SAAS_SWAGGER=1' : 'SAAS_SWAGGER=0'
17
- cmd << ' bundle exec source2swagger -f lib/3scale/backend/listener.rb -c "##~" -o docs/active_docs/.'
9
+ def generate_docs
10
+ cmd = 'bundle exec source2swagger -f lib/3scale/backend/listener.rb -c "##~" -o docs/active_docs/.'
18
11
  run_command cmd
19
12
  # source2swagger is really bad at generating readable JSON
20
13
  require 'json'
21
- File.write(spec, JSON.pretty_generate(JSON.parse(File.read(spec))) << "\n")
14
+ File.write(SPEC_FILE, JSON.pretty_generate(JSON.parse(File.read(SPEC_FILE))) << "\n")
22
15
  end
23
16
 
24
17
  namespace :docs do
25
18
  namespace :swagger do
26
- namespace :generate do
27
- # The swagger specs generated by these tasks need to be committed to the
28
- # Porta repo: https://github.com/3scale/porta/tree/master/doc/active_docs
29
- # (Service Management API (on-premises).json and Service Management
30
- # API.json)
31
-
32
- desc "Generates all swagger docs"
33
- task all: [:saas, :on_prem]
34
-
35
- desc "Generates swagger docs for SaaS"
36
- task :saas do
37
- generate_docs(:saas)
38
- end
19
+ # The swagger specs generated by these tasks need to be committed to the
20
+ # Porta repo: https://github.com/3scale/porta/tree/master/doc/active_docs
21
+ # (Service Management API.json)
39
22
 
40
- desc "Generates swagger docs for on-prem"
41
- task :on_prem do
42
- generate_docs(:on_prem)
43
- end
23
+ desc "Generates swagger docs"
24
+ task :generate do
25
+ generate_docs
44
26
  end
45
27
  end
46
28
  end
@@ -3,7 +3,7 @@
3
3
  <dependencies>
4
4
  <dependency>
5
5
  <packageName>activesupport</packageName>
6
- <version>5.1.4</version>
6
+ <version>5.2.4.3</version>
7
7
  <licenses>
8
8
  <license>
9
9
  <name>MIT</name>
@@ -23,7 +23,7 @@
23
23
  </dependency>
24
24
  <dependency>
25
25
  <packageName>apisonator</packageName>
26
- <version>2.100.0</version>
26
+ <version>2.101.0</version>
27
27
  <licenses>
28
28
  <license>
29
29
  <name>Apache 2.0</name>
@@ -243,7 +243,7 @@
243
243
  </dependency>
244
244
  <dependency>
245
245
  <packageName>concurrent-ruby</packageName>
246
- <version>1.0.5</version>
246
+ <version>1.1.6</version>
247
247
  <licenses>
248
248
  <license>
249
249
  <name>MIT</name>
@@ -318,16 +318,6 @@
318
318
  <url>http://opensource.org/licenses/mit-license</url>
319
319
  </license>
320
320
  </licenses>
321
- </dependency>
322
- <dependency>
323
- <packageName>faraday</packageName>
324
- <version>0.13.1</version>
325
- <licenses>
326
- <license>
327
- <name>MIT</name>
328
- <url>http://opensource.org/licenses/mit-license</url>
329
- </license>
330
- </licenses>
331
321
  </dependency>
332
322
  <dependency>
333
323
  <packageName>ffi</packageName>
@@ -338,16 +328,6 @@
338
328
  <url>http://opensource.org/licenses/BSD-3-Clause</url>
339
329
  </license>
340
330
  </licenses>
341
- </dependency>
342
- <dependency>
343
- <packageName>geminabox</packageName>
344
- <version>0.13.11</version>
345
- <licenses>
346
- <license>
347
- <name>MIT-LICENSE</name>
348
- <url></url>
349
- </license>
350
- </licenses>
351
331
  </dependency>
352
332
  <dependency>
353
333
  <packageName>gli</packageName>
@@ -361,27 +341,17 @@
361
341
  </dependency>
362
342
  <dependency>
363
343
  <packageName>hiredis</packageName>
364
- <version>0.6.1</version>
344
+ <version>0.6.3</version>
365
345
  <licenses>
366
346
  <license>
367
347
  <name>New BSD</name>
368
348
  <url>http://opensource.org/licenses/BSD-3-Clause</url>
369
349
  </license>
370
350
  </licenses>
371
- </dependency>
372
- <dependency>
373
- <packageName>httpclient</packageName>
374
- <version>2.8.3</version>
375
- <licenses>
376
- <license>
377
- <name>ruby</name>
378
- <url>http://www.ruby-lang.org/en/LICENSE.txt</url>
379
- </license>
380
- </licenses>
381
351
  </dependency>
382
352
  <dependency>
383
353
  <packageName>i18n</packageName>
384
- <version>0.9.1</version>
354
+ <version>1.8.2</version>
385
355
  <licenses>
386
356
  <license>
387
357
  <name>MIT</name>
@@ -471,7 +441,7 @@
471
441
  </dependency>
472
442
  <dependency>
473
443
  <packageName>minitest</packageName>
474
- <version>5.10.3</version>
444
+ <version>5.14.1</version>
475
445
  <licenses>
476
446
  <license>
477
447
  <name>MIT</name>
@@ -512,16 +482,6 @@
512
482
  <url>http://opensource.org/licenses/mit-license</url>
513
483
  </license>
514
484
  </licenses>
515
- </dependency>
516
- <dependency>
517
- <packageName>multipart-post</packageName>
518
- <version>2.0.0</version>
519
- <licenses>
520
- <license>
521
- <name>MIT</name>
522
- <url>http://opensource.org/licenses/mit-license</url>
523
- </license>
524
- </licenses>
525
485
  </dependency>
526
486
  <dependency>
527
487
  <packageName>mustache</packageName>
@@ -542,16 +502,6 @@
542
502
  <url>http://opensource.org/licenses/mit-license</url>
543
503
  </license>
544
504
  </licenses>
545
- </dependency>
546
- <dependency>
547
- <packageName>nesty</packageName>
548
- <version>1.0.2</version>
549
- <licenses>
550
- <license>
551
- <name>MIT</name>
552
- <url>http://opensource.org/licenses/mit-license</url>
553
- </license>
554
- </licenses>
555
505
  </dependency>
556
506
  <dependency>
557
507
  <packageName>net-scp</packageName>
@@ -809,7 +759,7 @@
809
759
  </dependency>
810
760
  <dependency>
811
761
  <packageName>redis</packageName>
812
- <version>4.1.1</version>
762
+ <version>4.1.3</version>
813
763
  <licenses>
814
764
  <license>
815
765
  <name>MIT</name>
@@ -826,16 +776,6 @@
826
776
  <url>http://opensource.org/licenses/mit-license</url>
827
777
  </license>
828
778
  </licenses>
829
- </dependency>
830
- <dependency>
831
- <packageName>reentrant_flock</packageName>
832
- <version>0.1.1</version>
833
- <licenses>
834
- <license>
835
- <name>MIT</name>
836
- <url>http://opensource.org/licenses/mit-license</url>
837
- </license>
838
- </licenses>
839
779
  </dependency>
840
780
  <dependency>
841
781
  <packageName>resque</packageName>
@@ -1123,7 +1063,7 @@
1123
1063
  </dependency>
1124
1064
  <dependency>
1125
1065
  <packageName>tzinfo</packageName>
1126
- <version>1.2.4</version>
1066
+ <version>1.2.7</version>
1127
1067
  <licenses>
1128
1068
  <license>
1129
1069
  <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: 2.100.0
4
+ version: 2.101.0
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-04-22 00:00:00.000000000 Z
19
+ date: 2020-06-04 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.
@@ -88,7 +88,6 @@ files:
88
88
  - lib/3scale/backend/extensions/array.rb
89
89
  - lib/3scale/backend/extensions/hash.rb
90
90
  - lib/3scale/backend/extensions/nil_class.rb
91
- - lib/3scale/backend/extensions/redis.rb
92
91
  - lib/3scale/backend/extensions/string.rb
93
92
  - lib/3scale/backend/extensions/time.rb
94
93
  - lib/3scale/backend/failed_jobs_scheduler.rb
@@ -1,44 +0,0 @@
1
- # Monkey-patches a method in Redis::Client::Connector::Sentinel to fix a bug
2
- # with sentinel passwords. It applies the fix in
3
- # https://github.com/redis/redis-rb/pull/856.
4
- #
5
- # The fix was included in 4.1.2, but we cannot upgrade because that version
6
- # drops support for ruby < 2.3.0 which we still need to support.
7
- #
8
- # This should only be temporary. It should be deleted when updating the gem.
9
- class Redis
10
- class Client
11
- class Connector
12
- class Sentinel
13
- def sentinel_detect
14
- @sentinels.each do |sentinel|
15
- client = Redis::Client.new(@options.merge({:host => sentinel[:host],
16
- :port => sentinel[:port],
17
- password: sentinel[:password],
18
- :reconnect_attempts => 0,
19
- }))
20
-
21
- begin
22
- if result = yield(client)
23
- # This sentinel responded. Make sure we ask it first next time.
24
- @sentinels.delete(sentinel)
25
- @sentinels.unshift(sentinel)
26
-
27
- return result
28
- end
29
- rescue BaseConnectionError
30
- rescue RuntimeError => exception
31
- # Needed because when the sentinel address cannot be resolved it
32
- # raises this instead of "BaseConnectionError"
33
- raise unless exception.message =~ /Name or service not known/
34
- ensure
35
- client.disconnect
36
- end
37
- end
38
-
39
- raise CannotConnectError, "No sentinels available."
40
- end
41
- end
42
- end
43
- end
44
- end