apisonator 2.100.0 → 2.101.0

Sign up to get free protection for your applications and to get access to all the features.
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