apisonator 2.100.2 → 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: 36a24cd40b3b9d707a5b4c06243a17c11fa0d3e42929dd0c5f5edc5aae5e35fd
4
- data.tar.gz: c523234e3ce2afeaf1b536a99b138532020643574cd24173e8457187c1cc9693
3
+ metadata.gz: 4740b1613c8bd2182adf9587db2a2ae6667a50ee140c99c679c232b6da3b7193
4
+ data.tar.gz: 0e34376e2e788194b44eeb5aedf7d8654110c8baa4a0885ed2c55a3a28fcb0c1
5
5
  SHA512:
6
- metadata.gz: 93da0370affbadcbf04cba8e213faa5d7cc2ff03ec2e848436596c54b5fec05d6bf0847da4d799243d62c46f7cab6c8121010c975a174b6d5beb5f4d63280019
7
- data.tar.gz: '07685172c1e7f102a9fe0ed967cbcd61dfbbe138d8f6447a0183e5a6ba28a7873b96e52ff72206d268fa233642f1195de0b6a8a7ab777e4e90f39146d35fa618'
6
+ metadata.gz: c6431c06f07433710308ef8b9121d2975415cbec27d2c82db3c8f13c4a0dab364b6a9085a550a530bd000a18234bfd63d67ee555ea69299f8745734725f9f436
7
+ data.tar.gz: 90618d349784bfe5ff9d78b940f93d7b63013fb9f1ec1b9c68f03881ff9e13a165d0532a98d50c26218402cc197c3f9f730f7b34ca26589cb8f4b91fa37e6cab
@@ -2,6 +2,24 @@
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
+
5
23
  ## 2.100.2 - 2020-05-08
6
24
 
7
25
  ### Changed
@@ -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
@@ -35,14 +35,14 @@ GIT
35
35
  PATH
36
36
  remote: .
37
37
  specs:
38
- apisonator (2.100.2)
38
+ apisonator (2.101.0)
39
39
 
40
40
  GEM
41
41
  remote: https://rubygems.org/
42
42
  specs:
43
- activesupport (5.1.4)
43
+ activesupport (5.2.4.3)
44
44
  concurrent-ruby (~> 1.0, >= 1.0.2)
45
- i18n (~> 0.7)
45
+ i18n (>= 0.7, < 2)
46
46
  minitest (~> 5.1)
47
47
  tzinfo (~> 1.1)
48
48
  airbrake (4.3.1)
@@ -95,7 +95,7 @@ GEM
95
95
  codeclimate-test-reporter (0.6.0)
96
96
  simplecov (>= 0.7.1, < 1.0.0)
97
97
  coderay (1.1.2)
98
- concurrent-ruby (1.0.5)
98
+ concurrent-ruby (1.1.6)
99
99
  console (1.8.2)
100
100
  daemons (1.2.4)
101
101
  diff-lcs (1.3)
@@ -112,20 +112,10 @@ GEM
112
112
  process-metrics (~> 0.1.0)
113
113
  rack (>= 1.0)
114
114
  samovar (~> 2.1)
115
- faraday (0.13.1)
116
- multipart-post (>= 1.2, < 3)
117
115
  ffi (1.12.2)
118
- geminabox (0.13.11)
119
- builder
120
- faraday
121
- httpclient (>= 2.2.7)
122
- nesty
123
- reentrant_flock
124
- sinatra (>= 1.2.7)
125
116
  gli (2.16.1)
126
117
  hiredis (0.6.3)
127
- httpclient (2.8.3)
128
- i18n (0.9.1)
118
+ i18n (1.8.2)
129
119
  concurrent-ruby (~> 1.0)
130
120
  jmespath (1.3.1)
131
121
  json (2.1.0)
@@ -141,15 +131,13 @@ GEM
141
131
  metaclass (0.0.4)
142
132
  method_source (0.9.0)
143
133
  mini_portile2 (2.4.0)
144
- minitest (5.10.3)
134
+ minitest (5.14.1)
145
135
  mocha (1.3.0)
146
136
  metaclass (~> 0.0.1)
147
137
  mono_logger (1.1.0)
148
138
  multi_json (1.13.1)
149
- multipart-post (2.0.0)
150
139
  mustache (1.0.5)
151
140
  mustermann (1.0.2)
152
- nesty (1.0.2)
153
141
  net-scp (1.2.1)
154
142
  net-ssh (>= 2.6.5)
155
143
  net-ssh (4.2.0)
@@ -191,7 +179,6 @@ GEM
191
179
  rake (13.0.1)
192
180
  redis-namespace (1.6.0)
193
181
  redis (>= 3.0.4)
194
- reentrant_flock (0.1.1)
195
182
  resque_spec (0.17.0)
196
183
  resque (>= 1.19.0)
197
184
  rspec-core (>= 3.0.0)
@@ -256,7 +243,7 @@ GEM
256
243
  timers (4.3.0)
257
244
  toml (0.2.0)
258
245
  parslet (~> 1.8.0)
259
- tzinfo (1.2.4)
246
+ tzinfo (1.2.7)
260
247
  thread_safe (~> 0.1)
261
248
  vegas (0.1.11)
262
249
  rack (>= 1.0.0)
@@ -288,7 +275,6 @@ DEPENDENCIES
288
275
  codeclimate-test-reporter (~> 0.6.0)
289
276
  daemons (= 1.2.4)
290
277
  falcon (~> 0.35)
291
- geminabox (~> 0.13.11)
292
278
  gli (~> 2.16.1)
293
279
  hiredis (~> 0.6.1)
294
280
  license_finder (~> 5)
@@ -35,14 +35,14 @@ GIT
35
35
  PATH
36
36
  remote: .
37
37
  specs:
38
- apisonator (2.100.2)
38
+ apisonator (2.101.0)
39
39
 
40
40
  GEM
41
41
  remote: https://rubygems.org/
42
42
  specs:
43
- activesupport (5.1.4)
43
+ activesupport (5.2.4.3)
44
44
  concurrent-ruby (~> 1.0, >= 1.0.2)
45
- i18n (~> 0.7)
45
+ i18n (>= 0.7, < 2)
46
46
  minitest (~> 5.1)
47
47
  tzinfo (~> 1.1)
48
48
  async (1.24.2)
@@ -85,7 +85,7 @@ GEM
85
85
  codeclimate-test-reporter (0.6.0)
86
86
  simplecov (>= 0.7.1, < 1.0.0)
87
87
  coderay (1.1.2)
88
- concurrent-ruby (1.0.5)
88
+ concurrent-ruby (1.1.6)
89
89
  console (1.8.2)
90
90
  daemons (1.2.4)
91
91
  diff-lcs (1.3)
@@ -102,20 +102,10 @@ GEM
102
102
  process-metrics (~> 0.1.0)
103
103
  rack (>= 1.0)
104
104
  samovar (~> 2.1)
105
- faraday (0.13.1)
106
- multipart-post (>= 1.2, < 3)
107
105
  ffi (1.12.2)
108
- geminabox (0.13.11)
109
- builder
110
- faraday
111
- httpclient (>= 2.2.7)
112
- nesty
113
- reentrant_flock
114
- sinatra (>= 1.2.7)
115
106
  gli (2.16.1)
116
107
  hiredis (0.6.3)
117
- httpclient (2.8.3)
118
- i18n (0.9.1)
108
+ i18n (1.8.2)
119
109
  concurrent-ruby (~> 1.0)
120
110
  json (2.1.0)
121
111
  license_finder (5.9.2)
@@ -130,15 +120,13 @@ GEM
130
120
  metaclass (0.0.4)
131
121
  method_source (0.9.0)
132
122
  mini_portile2 (2.4.0)
133
- minitest (5.10.3)
123
+ minitest (5.14.1)
134
124
  mocha (1.3.0)
135
125
  metaclass (~> 0.0.1)
136
126
  mono_logger (1.1.0)
137
127
  multi_json (1.13.1)
138
- multipart-post (2.0.0)
139
128
  mustache (1.0.5)
140
129
  mustermann (1.0.2)
141
- nesty (1.0.2)
142
130
  net-scp (1.2.1)
143
131
  net-ssh (>= 2.6.5)
144
132
  net-ssh (4.2.0)
@@ -179,7 +167,6 @@ GEM
179
167
  rake (13.0.1)
180
168
  redis-namespace (1.6.0)
181
169
  redis (>= 3.0.4)
182
- reentrant_flock (0.1.1)
183
170
  resque_spec (0.17.0)
184
171
  resque (>= 1.19.0)
185
172
  rspec-core (>= 3.0.0)
@@ -242,7 +229,7 @@ GEM
242
229
  timers (4.3.0)
243
230
  toml (0.2.0)
244
231
  parslet (~> 1.8.0)
245
- tzinfo (1.2.4)
232
+ tzinfo (1.2.7)
246
233
  thread_safe (~> 0.1)
247
234
  vegas (0.1.11)
248
235
  rack (>= 1.0.0)
@@ -270,7 +257,6 @@ DEPENDENCIES
270
257
  codeclimate-test-reporter (~> 0.6.0)
271
258
  daemons (= 1.2.4)
272
259
  falcon (~> 0.35)
273
- geminabox (~> 0.13.11)
274
260
  gli (~> 2.16.1)
275
261
  hiredis (~> 0.6.1)
276
262
  license_finder (~> 5)
@@ -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)
@@ -604,10 +604,6 @@ module ThreeScale
604
604
  end
605
605
  end
606
606
 
607
- def application
608
- @application ||= Application.load_by_id_or_user_key!(service_id, params[:app_id], params[:user_key])
609
- end
610
-
611
607
  def service_id
612
608
  if params[:service_id].nil? || params[:service_id].empty?
613
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
 
@@ -52,13 +52,18 @@ module ThreeScale
52
52
  # duplicated commands because of this setting.
53
53
  reconnect_attempts: 1,
54
54
  # use by default the C extension client
55
- driver: :hiredis
55
+ driver: :hiredis,
56
+ # applies only to async mode. The sync library opens 1 connection
57
+ # per process.
58
+ max_connections: 10,
56
59
  }.freeze
57
60
  private_constant :CONN_OPTIONS
58
61
 
59
62
  # CONN_WHITELIST - Connection options that can be specified in config
60
63
  # Note: we don't expose reconnect_attempts until the bug above is fixed
61
- CONN_WHITELIST = [:connect_timeout, :read_timeout, :write_timeout].freeze
64
+ CONN_WHITELIST = [
65
+ :connect_timeout, :read_timeout, :write_timeout, :max_connections
66
+ ].freeze
62
67
  private_constant :CONN_WHITELIST
63
68
 
64
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.2'
3
+ VERSION = '2.101.0'
4
4
  end
5
5
  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.2</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>
@@ -368,20 +348,10 @@
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>
@@ -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.2
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-05-08 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.