apisonator 3.3.0 → 3.4.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: a8e132216edb5cd3b44967acab917d4ca4f50c692c22fb5b81c7ffff9c5d598b
4
- data.tar.gz: e2e31c92b450398dbcd3a3dcc3d31ed39b2d530048de23aa06b95c4930809249
3
+ metadata.gz: 7a260bc57e82268c54885b58a12c79d28c9b7c53f8fb5e48182c887488888184
4
+ data.tar.gz: 7dbed84c520c06e914d15e99f6e1b78365a1b695d8cf8e1fd66a58c02fa36fa9
5
5
  SHA512:
6
- metadata.gz: 288b9c506a32caf81e2b3bcbf06b347e1f39f32a295a61d146ebc9b7f5953458f27114c3eceb08ef00da6293487d02f49b5c7688af16f87c0aa0ff4c70cfa48f
7
- data.tar.gz: 025f8fcf1edb087de5e97ad43ecca61e25c97f061f0002b75d210a1052fa76355c5ea8a34515018d41b21428791d255341e2f36d2c178872ae549d3f97f2e52e
6
+ metadata.gz: 4d0bdd90d90972bc416faf04a852ff56c3895da1cb191b264617f71add2f22c5942d928d85c9877faceab4f00e7fe26955dfeed7c6cbc615a8fe555b7c6e251a
7
+ data.tar.gz: 22b6dbdb74d73117ba7358d231b5f747f54746687e452285b77883df4b352d20d59b3997b38a0c5c7b6cba9bce618b41900d6a0ee3ea1e169727470bce8158cb
data/CHANGELOG.md CHANGED
@@ -2,6 +2,74 @@
2
2
 
3
3
  Notable changes to Apisonator will be tracked in this document.
4
4
 
5
+ ## 3.4.0 - 2021-06-14
6
+
7
+ ### Added
8
+
9
+ - New extension that list the keys of an application
10
+ ([#284](https://github.com/3scale/apisonator/pull/284)).
11
+
12
+ ### Changed
13
+
14
+ - It is now possible to use OIDC in the auth and authrep endpoints
15
+ ([#280](https://github.com/3scale/apisonator/pull/280)).
16
+ - Updated multi-json to 1.15.0
17
+ ([#278](https://github.com/3scale/apisonator/pull/278)).
18
+
19
+ ### Removed
20
+
21
+ - Deleted unused service attributes related with deleted end-users functionality
22
+ ([#277](https://github.com/3scale/apisonator/pull/277)).
23
+
24
+ ## 3.3.3 - 2021-03-09
25
+
26
+ ### Changed
27
+
28
+ - Check if alerts can be raised before calculating utilization (perf
29
+ optimization) ([#275](https://github.com/3scale/apisonator/pull/275)).
30
+
31
+ ### Removed
32
+
33
+ - Stop maintaining unused "current_max" key in Alerts
34
+ ([#272](https://github.com/3scale/apisonator/pull/272)).
35
+
36
+ ## 3.3.2 - 2021-02-23
37
+
38
+ ### Fixed
39
+
40
+ - Fixed nil exception in `Aggregator.process`
41
+ ([#269](https://github.com/3scale/apisonator/pull/269)).
42
+
43
+ ### Changed
44
+
45
+ - Updated to Ruby 2.7 in Docker images
46
+ ([#265](https://github.com/3scale/apisonator/pull/265)) and
47
+ ([#266](https://github.com/3scale/apisonator/pull/266)).
48
+ - Updated pry to 0.14.0 and pry-doc to 1.1.0
49
+ ([#267](https://github.com/3scale/apisonator/pull/267)).
50
+ - Updated Docker image to be based on RHEL UBI 8
51
+ ([#268](https://github.com/3scale/apisonator/pull/268)).
52
+
53
+ ### Removed
54
+
55
+ - Removed redundant prometheus config params
56
+ (`listener_prometheus_metrics.enabled` and `listener_prometheus_metrics.port`)
57
+ ([#270](https://github.com/3scale/apisonator/pull/270)).
58
+
59
+ ## 3.3.1.1 - 2021-02-12
60
+
61
+ ### Changed
62
+
63
+ - Updated our Puma fork to v4.3.7
64
+ ([#261](https://github.com/3scale/apisonator/pull/261)).
65
+
66
+ ## 3.3.1 - 2021-02-11
67
+
68
+ ### Fixed
69
+
70
+ - Usages with `#0` (set to 0) no longer generate unnecessary stats keys in Redis
71
+ ([#258](https://github.com/3scale/apisonator/pull/258)).
72
+
5
73
  ## 3.3.0 - 2021-02-09
6
74
 
7
75
  ### Added
data/Gemfile.base CHANGED
@@ -15,11 +15,15 @@ platform :ruby do
15
15
  end
16
16
 
17
17
  group :test do
18
+ # Newer versions of rack-test don't work well with rspec-api-documentation.
19
+ # See https://github.com/rack/rack-test/pull/223 &
20
+ # https://github.com/zipmark/rspec_api_documentation/issues/342
21
+ gem 'rack-test', '= 0.8.2'
22
+
18
23
  gem 'benchmark-ips', '~> 2.7.2'
19
24
  gem 'mocha', '~> 1.3'
20
25
  gem 'nokogiri', '~> 1.10.8'
21
26
  gem 'pkg-config', '~> 1.1.7'
22
- gem 'rack-test', '~> 0.8.2'
23
27
  gem 'resque_unit', '~> 0.4.4', source: 'https://rubygems.org'
24
28
  gem 'test-unit', '~> 3.2.6'
25
29
  gem 'resque_spec', '~> 0.17.0'
@@ -32,8 +36,8 @@ end
32
36
  group :development do
33
37
  gem 'sshkit'
34
38
  gem 'source2swagger', git: 'https://github.com/3scale/source2swagger', branch: 'backend'
35
- gem 'pry', '~> 0.11.3'
36
- gem 'pry-doc', '~> 0.11.1'
39
+ gem 'pry', '~> 0.14'
40
+ gem 'pry-doc', '~> 1.1'
37
41
  gem 'license_finder', '~> 5'
38
42
  end
39
43
 
@@ -42,7 +46,7 @@ group :development, :test do
42
46
  end
43
47
 
44
48
  # Default server by platform
45
- gem 'puma', git: 'https://github.com/3scale/puma', ref: 'b034371406690d3e6c2a9301c4a48bd721f3efc3'
49
+ gem 'puma', git: 'https://github.com/3scale/puma', branch: '3scale-4.3.7'
46
50
  # gems required by the runner
47
51
  gem 'gli', '~> 2.16.1', require: nil
48
52
  # Workers
data/Gemfile.lock CHANGED
@@ -1,9 +1,10 @@
1
1
  GIT
2
2
  remote: https://github.com/3scale/puma
3
- revision: b034371406690d3e6c2a9301c4a48bd721f3efc3
4
- ref: b034371406690d3e6c2a9301c4a48bd721f3efc3
3
+ revision: c0601d08695839b8ffd0f380e91c3b91c1e8b754
4
+ branch: 3scale-4.3.7
5
5
  specs:
6
- puma (2.15.3)
6
+ puma (4.3.7)
7
+ nio4r (~> 2.0)
7
8
 
8
9
  GIT
9
10
  remote: https://github.com/3scale/redis-rb
@@ -35,7 +36,7 @@ GIT
35
36
  PATH
36
37
  remote: .
37
38
  specs:
38
- apisonator (3.3.0)
39
+ apisonator (3.4.0)
39
40
 
40
41
  GEM
41
42
  remote: https://rubygems.org/
@@ -95,7 +96,7 @@ GEM
95
96
  chronic (0.10.2)
96
97
  codeclimate-test-reporter (0.6.0)
97
98
  simplecov (>= 0.7.1, < 1.0.0)
98
- coderay (1.1.2)
99
+ coderay (1.1.3)
99
100
  concurrent-ruby (1.1.6)
100
101
  console (1.8.2)
101
102
  daemons (1.2.4)
@@ -130,13 +131,13 @@ GEM
130
131
  localhost (1.1.6)
131
132
  mapping (1.1.1)
132
133
  metaclass (0.0.4)
133
- method_source (0.9.0)
134
+ method_source (1.0.0)
134
135
  mini_portile2 (2.4.0)
135
136
  minitest (5.14.1)
136
137
  mocha (1.3.0)
137
138
  metaclass (~> 0.0.1)
138
139
  mono_logger (1.1.0)
139
- multi_json (1.13.1)
140
+ multi_json (1.15.0)
140
141
  mustache (1.0.5)
141
142
  mustermann (1.0.2)
142
143
  net-scp (1.2.1)
@@ -163,15 +164,15 @@ GEM
163
164
  protocol-hpack (~> 1.4)
164
165
  protocol-http (~> 0.15)
165
166
  protocol-redis (0.5.0)
166
- pry (0.11.3)
167
- coderay (~> 1.1.0)
168
- method_source (~> 0.9.0)
167
+ pry (0.14.0)
168
+ coderay (~> 1.1)
169
+ method_source (~> 1.0)
169
170
  pry-byebug (3.5.1)
170
171
  byebug (~> 9.1)
171
172
  pry (~> 0.10)
172
- pry-doc (0.11.1)
173
- pry (~> 0.9)
174
- yard (~> 0.9)
173
+ pry-doc (1.1.0)
174
+ pry (~> 0.11)
175
+ yard (~> 0.9.11)
175
176
  rack (2.1.4)
176
177
  rack-protection (2.0.3)
177
178
  rack
@@ -259,7 +260,7 @@ GEM
259
260
  prometheus-client (~> 1.0)
260
261
  yabeda (~> 0.5)
261
262
  yajl-ruby (1.3.1)
262
- yard (0.9.20)
263
+ yard (0.9.26)
263
264
 
264
265
  PLATFORMS
265
266
  ruby
@@ -283,12 +284,12 @@ DEPENDENCIES
283
284
  nokogiri (~> 1.10.8)
284
285
  pg (= 0.20.0)
285
286
  pkg-config (~> 1.1.7)
286
- pry (~> 0.11.3)
287
+ pry (~> 0.14)
287
288
  pry-byebug (~> 3.5.1)
288
- pry-doc (~> 0.11.1)
289
+ pry-doc (~> 1.1)
289
290
  puma!
290
291
  rack (~> 2.1.4)
291
- rack-test (~> 0.8.2)
292
+ rack-test (= 0.8.2)
292
293
  rake (~> 13.0)
293
294
  redis!
294
295
  redis-namespace (~> 1.8.0)
data/Gemfile.on_prem.lock CHANGED
@@ -1,9 +1,10 @@
1
1
  GIT
2
2
  remote: https://github.com/3scale/puma
3
- revision: b034371406690d3e6c2a9301c4a48bd721f3efc3
4
- ref: b034371406690d3e6c2a9301c4a48bd721f3efc3
3
+ revision: c0601d08695839b8ffd0f380e91c3b91c1e8b754
4
+ branch: 3scale-4.3.7
5
5
  specs:
6
- puma (2.15.3)
6
+ puma (4.3.7)
7
+ nio4r (~> 2.0)
7
8
 
8
9
  GIT
9
10
  remote: https://github.com/3scale/redis-rb
@@ -35,7 +36,7 @@ GIT
35
36
  PATH
36
37
  remote: .
37
38
  specs:
38
- apisonator (3.3.0)
39
+ apisonator (3.4.0)
39
40
 
40
41
  GEM
41
42
  remote: https://rubygems.org/
@@ -85,7 +86,7 @@ GEM
85
86
  byebug (9.1.0)
86
87
  codeclimate-test-reporter (0.6.0)
87
88
  simplecov (>= 0.7.1, < 1.0.0)
88
- coderay (1.1.2)
89
+ coderay (1.1.3)
89
90
  concurrent-ruby (1.1.6)
90
91
  console (1.8.2)
91
92
  daemons (1.2.4)
@@ -119,13 +120,13 @@ GEM
119
120
  localhost (1.1.6)
120
121
  mapping (1.1.1)
121
122
  metaclass (0.0.4)
122
- method_source (0.9.0)
123
+ method_source (1.0.0)
123
124
  mini_portile2 (2.4.0)
124
125
  minitest (5.14.1)
125
126
  mocha (1.3.0)
126
127
  metaclass (~> 0.0.1)
127
128
  mono_logger (1.1.0)
128
- multi_json (1.13.1)
129
+ multi_json (1.15.0)
129
130
  mustache (1.0.5)
130
131
  mustermann (1.0.2)
131
132
  net-scp (1.2.1)
@@ -151,15 +152,15 @@ GEM
151
152
  protocol-hpack (~> 1.4)
152
153
  protocol-http (~> 0.15)
153
154
  protocol-redis (0.5.0)
154
- pry (0.11.3)
155
- coderay (~> 1.1.0)
156
- method_source (~> 0.9.0)
155
+ pry (0.14.0)
156
+ coderay (~> 1.1)
157
+ method_source (~> 1.0)
157
158
  pry-byebug (3.5.1)
158
159
  byebug (~> 9.1)
159
160
  pry (~> 0.10)
160
- pry-doc (0.11.1)
161
- pry (~> 0.9)
162
- yard (~> 0.9)
161
+ pry-doc (1.1.0)
162
+ pry (~> 0.11)
163
+ yard (~> 0.9.11)
163
164
  rack (2.1.4)
164
165
  rack-protection (2.0.3)
165
166
  rack
@@ -243,7 +244,7 @@ GEM
243
244
  prometheus-client (~> 1.0)
244
245
  yabeda (~> 0.5)
245
246
  yajl-ruby (1.3.1)
246
- yard (0.9.20)
247
+ yard (0.9.26)
247
248
 
248
249
  PLATFORMS
249
250
  ruby
@@ -264,12 +265,12 @@ DEPENDENCIES
264
265
  mocha (~> 1.3)
265
266
  nokogiri (~> 1.10.8)
266
267
  pkg-config (~> 1.1.7)
267
- pry (~> 0.11.3)
268
+ pry (~> 0.14)
268
269
  pry-byebug (~> 3.5.1)
269
- pry-doc (~> 0.11.1)
270
+ pry-doc (~> 1.1)
270
271
  puma!
271
272
  rack (~> 2.1.4)
272
- rack-test (~> 0.8.2)
273
+ rack-test (= 0.8.2)
273
274
  rake (~> 13.0)
274
275
  redis!
275
276
  redis-namespace (~> 1.8.0)
@@ -6,32 +6,13 @@ module ThreeScale
6
6
  respond_with_404('service not found') unless Service.exists?(params[:service_id])
7
7
  end
8
8
 
9
- # This is very slow and needs to be disabled until the performance
10
- # issues are solved. In the meanwhile, the job will just return OK.
11
- =begin
12
- delete '' do |service_id|
13
- delete_stats_job_attrs = api_params Stats::DeleteJobDef
14
- delete_stats_job_attrs[:service_id] = service_id
15
- delete_stats_job_attrs[:from] = delete_stats_job_attrs[:from].to_i
16
- delete_stats_job_attrs[:to] = delete_stats_job_attrs[:to].to_i
17
- begin
18
- Stats::DeleteJobDef.new(delete_stats_job_attrs).run_async
19
- rescue DeleteServiceStatsValidationError => e
20
- [400, headers, { status: :error, error: e.message }.to_json]
21
- else
22
- { status: :to_be_deleted }.to_json
23
- end
24
- =end
25
-
26
- # This is an alternative to the above. It just adds the service to a
27
- # Redis set to marked is as "to be deleted".
28
- # Later a script can read that set and actually delete the keys.
29
- # Read the docs of the Stats::Cleaner class for more details.
9
+ # This adds the service to a Redis set to mark is as "to be deleted".
10
+ # Later a script can read that set and actually delete the keys. Read
11
+ # the docs of the Stats::Cleaner class for more details.
30
12
  #
31
- # Notice that this method ignores the "from" and "to" parameters. When
32
- # system calls this method, they're always interested in deleting all
33
- # the keys. They were just passing "from" and "to" to make the
34
- # implementation of the option above easier.
13
+ # Notice that this method ignores the "from" and "to" parameters used in
14
+ # previous versions. When system calls this method, they're always
15
+ # interested in deleting all the keys.
35
16
  delete '' do |service_id|
36
17
  Stats::Cleaner.mark_service_to_be_deleted(service_id)
37
18
  { status: :to_be_deleted }.to_json
@@ -1,21 +1,15 @@
1
1
  module ThreeScale
2
2
  module Backend
3
3
  class AlertLimit
4
- module KeyHelpers
5
- def key(service_id)
6
- "alerts/service_id:#{service_id}/allowed_set"
7
- end
8
- end
9
-
10
- include KeyHelpers
11
- extend KeyHelpers
4
+ include Alerts::KeyHelpers
5
+ extend Alerts::KeyHelpers
12
6
 
13
7
  include Storable
14
8
 
15
9
  attr_accessor :service_id, :value
16
10
 
17
11
  def save
18
- storage.sadd(key(service_id), value.to_i) if valid?
12
+ storage.sadd(key_allowed_set(service_id), value.to_i) if valid?
19
13
  end
20
14
 
21
15
  def to_hash
@@ -26,7 +20,7 @@ module ThreeScale
26
20
  end
27
21
 
28
22
  def self.load_all(service_id)
29
- values = storage.smembers(key(service_id))
23
+ values = storage.smembers(key_allowed_set(service_id))
30
24
  values.map do |value|
31
25
  new(service_id: service_id, value: value.to_i)
32
26
  end
@@ -38,7 +32,7 @@ module ThreeScale
38
32
  end
39
33
 
40
34
  def self.delete(service_id, value)
41
- storage.srem(key(service_id), value.to_i) if valid_value?(value)
35
+ storage.srem(key_allowed_set(service_id), value.to_i) if valid_value?(value)
42
36
  end
43
37
 
44
38
  def self.valid_value?(value)
@@ -6,11 +6,10 @@ module ThreeScale
6
6
 
7
7
  # The compacted hour in the params refers to the
8
8
  # TimeHacks.to_compact_s method.
9
- def alert_keys(service_id, app_id, discrete_utilization, compacted_hour_start)
9
+ def alert_keys(service_id, app_id, discrete_utilization)
10
10
  {
11
11
  already_notified: key_already_notified(service_id, app_id, discrete_utilization),
12
12
  allowed: key_allowed_set(service_id),
13
- current_max: key_current_max(service_id, app_id, compacted_hour_start),
14
13
  current_id: key_current_id
15
14
  }
16
15
  end
@@ -31,11 +30,6 @@ module ThreeScale
31
30
  "#{prefix}allowed_set"
32
31
  end
33
32
 
34
- def key_current_max(service_id, app_id, compacted_hour_start)
35
- prefix = key_prefix(service_id, app_id)
36
- "#{prefix}#{compacted_hour_start}/current_max"
37
- end
38
-
39
33
  def key_current_id
40
34
  'alerts/current_id'.freeze
41
35
  end
@@ -43,6 +37,7 @@ module ThreeScale
43
37
 
44
38
  extend self
45
39
  extend KeyHelpers
40
+ include Memoizer::Decorator
46
41
 
47
42
  ALERT_TTL = 24*3600 # 1 day (only one message per day)
48
43
  ## zero must be here and sorted, yes or yes
@@ -50,6 +45,16 @@ module ThreeScale
50
45
  FIRST_ALERT_BIN = ALERT_BINS.first
51
46
  RALERT_BINS = ALERT_BINS.reverse.freeze
52
47
 
48
+ def can_raise_more_alerts?(service_id, app_id)
49
+ allowed_bins = allowed_set_for_service(service_id).sort
50
+
51
+ return false if allowed_bins.empty?
52
+
53
+ # If the bin with the highest value has already been notified, there's
54
+ # no need to notify anything else.
55
+ not notified?(service_id, app_id, allowed_bins.last)
56
+ end
57
+
53
58
  def utilization(app_usage_reports)
54
59
  max_utilization = -1.0
55
60
  max_record = nil
@@ -77,25 +82,12 @@ module ThreeScale
77
82
 
78
83
  def update_utilization(service_id, app_id, max_utilization, max_record, timestamp)
79
84
  discrete = utilization_discrete(max_utilization)
80
- max_utilization_i = (max_utilization * 100.0).round
81
85
 
82
- beginning_of_day = Period::Boundary.day_start(timestamp)
83
- period_hour = Period::Boundary.hour_start(timestamp).to_compact_s
84
- # UNIX timestamp for key expiration - add 1 day + 5 mins
85
- expire_at = (beginning_of_day + 86700).to_i
86
+ keys = alert_keys(service_id, app_id, discrete)
86
87
 
87
- keys = alert_keys(service_id, app_id, discrete, period_hour)
88
-
89
- already_alerted, allowed, current_max, _ = storage.pipelined do
88
+ already_alerted, allowed = storage.pipelined do
90
89
  storage.get(keys[:already_notified])
91
90
  storage.sismember(keys[:allowed], discrete)
92
- storage.get(keys[:current_max])
93
- storage.expireat(keys[:current_max], expire_at)
94
- end
95
-
96
- ## update the status of utilization
97
- if max_utilization_i > current_max.to_i
98
- storage.set(keys[:current_max], max_utilization_i)
99
91
  end
100
92
 
101
93
  if already_alerted.nil? && allowed && discrete.to_i > 0
@@ -129,6 +121,16 @@ module ThreeScale
129
121
  "#{record.current_value}/#{record.max_value}"
130
122
  end
131
123
 
124
+ def allowed_set_for_service(service_id)
125
+ storage.smembers(key_allowed_set(service_id)).map(&:to_i) # Redis returns strings always
126
+ end
127
+ memoize :allowed_set_for_service
128
+
129
+ def notified?(service_id, app_id, bin)
130
+ storage.get(key_already_notified(service_id, app_id, bin))
131
+ end
132
+ memoize :notified?
133
+
132
134
  def storage
133
135
  Storage.instance
134
136
  end
@@ -32,8 +32,6 @@ module ThreeScale
32
32
 
33
33
  CONFIG_DELETE_STATS_BATCH_SIZE = 50
34
34
  private_constant :CONFIG_DELETE_STATS_BATCH_SIZE
35
- CONFIG_DELETE_STATS_PARTITION_BATCH_SIZE = 1000
36
- private_constant :CONFIG_DELETE_STATS_PARTITION_BATCH_SIZE
37
35
 
38
36
  @configuration = Configuration::Loader.new
39
37
 
@@ -54,13 +52,12 @@ module ThreeScale
54
52
  config.add_section(:analytics_redis, :server,
55
53
  :connect_timeout, :read_timeout, :write_timeout)
56
54
  config.add_section(:hoptoad, :service, :api_key)
57
- config.add_section(:stats, :bucket_size, :delete_batch_size, :delete_partition_batch_size)
55
+ config.add_section(:stats, :bucket_size, :delete_batch_size)
58
56
  config.add_section(:redshift, :host, :port, :dbname, :user, :password)
59
57
  config.add_section(:statsd, :host, :port)
60
58
  config.add_section(:internal_api, :user, :password)
61
59
  config.add_section(:master, :metrics)
62
60
  config.add_section(:worker_prometheus_metrics, :enabled, :port)
63
- config.add_section(:listener_prometheus_metrics, :enabled, :port)
64
61
 
65
62
  config.add_section(
66
63
  :async_worker,
@@ -125,9 +122,6 @@ module ThreeScale
125
122
  config.stats.delete_batch_size = parse_int(config.stats.delete_batch_size,
126
123
  CONFIG_DELETE_STATS_BATCH_SIZE)
127
124
 
128
- config.stats.delete_partition_batch_size = parse_int(config.stats.delete_partition_batch_size,
129
- CONFIG_DELETE_STATS_PARTITION_BATCH_SIZE)
130
-
131
125
  # often we don't have a log_file setting - generate it here from
132
126
  # the log_path setting.
133
127
  log_file = config.log_file
@@ -292,12 +292,6 @@ module ThreeScale
292
292
  end
293
293
  end
294
294
 
295
- class DeleteServiceStatsValidationError < Error
296
- def initialize(service_id, msg)
297
- super "Delete stats job context validation error. Service: #{service_id}. Error: #{msg}"
298
- end
299
- end
300
-
301
295
  class EndUsersNoLongerSupported < BadRequest
302
296
  def initialize
303
297
  super 'End-users are no longer supported, do not specify the user_id parameter'.freeze
@@ -17,7 +17,10 @@ module ThreeScale
17
17
 
18
18
  Backend::Logging::External.setup_rack self
19
19
 
20
- if Backend.configuration.listener_prometheus_metrics.enabled
20
+ # Notice that this cannot be specified via config, it needs to be an
21
+ # ENV because the metric server is started in Puma/Falcon
22
+ # "before_fork" and the configuration is not loaded at that point.
23
+ if ENV['CONFIG_LISTENER_PROMETHEUS_METRICS_ENABLED'].to_s.downcase.freeze == 'true'.freeze
21
24
  use Rack::Prometheus
22
25
  end
23
26
 
@@ -4,16 +4,12 @@ module ThreeScale
4
4
  include Storable
5
5
 
6
6
  # list of attributes to be fetched from storage
7
- ATTRIBUTES = %i[state referrer_filters_required backend_version
8
- user_registration_required default_user_plan_id
9
- default_user_plan_name provider_key].freeze
7
+ ATTRIBUTES = %i[state referrer_filters_required backend_version provider_key].freeze
10
8
  private_constant :ATTRIBUTES
11
9
 
12
10
  attr_reader :state
13
- attr_accessor :provider_key, :id, :backend_version,
14
- :default_user_plan_id, :default_user_plan_name
15
- attr_writer :referrer_filters_required, :user_registration_required,
16
- :default_service
11
+ attr_accessor :provider_key, :id, :backend_version
12
+ attr_writer :referrer_filters_required, :default_service
17
13
 
18
14
  class << self
19
15
  include Memoizer::Decorator
@@ -104,8 +100,6 @@ module ThreeScale
104
100
  memoize :list
105
101
 
106
102
  def save!(attributes = {})
107
- massage_set_user_registration_required attributes
108
-
109
103
  new(attributes).save!
110
104
  end
111
105
 
@@ -139,26 +133,10 @@ module ThreeScale
139
133
  def massage_service_attrs(service_attrs)
140
134
  service_attrs[:referrer_filters_required] =
141
135
  service_attrs[:referrer_filters_required].to_i > 0
142
- service_attrs[:user_registration_required] =
143
- massage_get_user_registration_required(
144
- service_attrs[:user_registration_required])
145
136
 
146
137
  service_attrs
147
138
  end
148
139
 
149
- # nil => true, 1 => true, '1' => true, 0 => false, '0' => false
150
- def massage_get_user_registration_required(value)
151
- value.nil? ? true : value.to_i > 0
152
- end
153
-
154
- def massage_set_user_registration_required(attributes)
155
- if attributes[:user_registration_required].nil?
156
- val = storage.get(storage_key(attributes[:id], :user_registration_required))
157
- attributes[:user_registration_required] =
158
- (!val.nil? && val.to_i == 0) ? false : true
159
- end
160
- end
161
-
162
140
  def get_attr(id, attribute)
163
141
  storage.get(storage_key(id, attribute))
164
142
  end
@@ -195,10 +173,6 @@ module ThreeScale
195
173
  @referrer_filters_required
196
174
  end
197
175
 
198
- def user_registration_required?
199
- @user_registration_required
200
- end
201
-
202
176
  def save!
203
177
  set_as_default_if_needed
204
178
  persist
@@ -227,9 +201,6 @@ module ThreeScale
227
201
  provider_key: provider_key,
228
202
  backend_version: backend_version,
229
203
  referrer_filters_required: referrer_filters_required?,
230
- user_registration_required: user_registration_required?,
231
- default_user_plan_id: default_user_plan_id,
232
- default_user_plan_name: default_user_plan_name,
233
204
  default_service: default_service?
234
205
  }
235
206
  end
@@ -294,9 +265,6 @@ module ThreeScale
294
265
 
295
266
  def persist_attributes
296
267
  persist_attribute :referrer_filters_required, referrer_filters_required? ? 1 : 0
297
- persist_attribute :user_registration_required, user_registration_required? ? 1 : 0
298
- persist_attribute :default_user_plan_id, default_user_plan_id, true
299
- persist_attribute :default_user_plan_name, default_user_plan_name, true
300
268
  persist_attribute :backend_version, backend_version, true
301
269
  persist_attribute :provider_key, provider_key
302
270
  persist_attribute :state, state.to_s if state
@@ -1,8 +1,4 @@
1
1
  require '3scale/backend/stats/codes_commons'
2
2
  require '3scale/backend/stats/period_commons'
3
3
  require '3scale/backend/stats/aggregator'
4
- require '3scale/backend/stats/delete_job_def'
5
- require '3scale/backend/stats/key_generator'
6
- require '3scale/backend/stats/partition_generator_job'
7
- require '3scale/backend/stats/partition_eraser_job'
8
4
  require '3scale/backend/stats/cleaner'
@@ -145,6 +145,16 @@ module ThreeScale
145
145
  application = Backend::Application.load(service_id,
146
146
  values[:application_id])
147
147
 
148
+ # The app could have been deleted at some point since the job was
149
+ # enqueued. No need to update alerts in that case.
150
+ next unless application
151
+
152
+ # The operations below are costly. They load all the usage limits
153
+ # and current usages to find the current utilization levels.
154
+ # That's why before that, we check if there are any alerts that
155
+ # can be raised.
156
+ next unless Alerts.can_raise_more_alerts?(service_id, values[:application_id])
157
+
148
158
  application.load_metric_names
149
159
  usage = Usage.application_usage(application, current_timestamp)
150
160
  status = Transactor::Status.new(service_id: service_id,
@@ -20,7 +20,14 @@ module ThreeScale
20
20
  key = counter_key(prefix_key, granularity.new(timestamp))
21
21
  expire_time = Stats::PeriodCommons.expire_time_for_granularity(granularity)
22
22
 
23
- store_key(cmd, key, value, expire_time)
23
+ # We don't need to store stats keys set to 0. It wastes Redis
24
+ # memory because for rate-limiting and stats, a key of set to 0
25
+ # is equivalent to a key that does not exist.
26
+ if cmd == :set && value == 0
27
+ storage.del(key)
28
+ else
29
+ store_key(cmd, key, value, expire_time)
30
+ end
24
31
 
25
32
  unless Stats::PeriodCommons::EXCLUDED_FOR_BUCKETS.include?(granularity)
26
33
  keys_for_bucket << key
@@ -12,9 +12,6 @@ module ThreeScale
12
12
  GRANULARITY_EXPIRATION_TIME = { Period[:minute] => 180 }.freeze
13
13
  private_constant :GRANULARITY_EXPIRATION_TIME
14
14
 
15
- PERMANENT_SERVICE_GRANULARITIES = (SERVICE_GRANULARITIES - GRANULARITY_EXPIRATION_TIME.keys).freeze
16
- PERMANENT_EXPANDED_GRANULARITIES = (EXPANDED_GRANULARITIES - GRANULARITY_EXPIRATION_TIME.keys).freeze
17
-
18
15
  # We are not going to send metrics with granularity 'eternity' or
19
16
  # 'week' to Kinesis, so there is no point in storing them in Redis
20
17
  # buckets.
@@ -61,6 +61,8 @@ module ThreeScale
61
61
 
62
62
  def validate(oauth, provider_key, report_usage, params, request_info)
63
63
  service = Service.load_with_provider_key!(params[:service_id], provider_key)
64
+ oidc_service = !oauth && service.backend_version == 'oauth'.freeze
65
+
64
66
  # service_id cannot be taken from params since it might be missing there
65
67
  service_id = service.id
66
68
 
@@ -70,12 +72,18 @@ module ThreeScale
70
72
  # significant.
71
73
  params[:app_id] = nil if app_id && app_id.empty?
72
74
 
73
- if oauth
74
- raise ApplicationNotFound.new nil if app_id.nil?
75
- validators = Validators::OAUTH_VALIDATORS
76
- else
77
- validators = Validators::VALIDATORS
78
- end
75
+ # While OIDC without an app_id makes little sense, we would break existing
76
+ # behaviour when calling non oauth_auth*.xml endpoints if we returned an
77
+ # error here, so only do this for oauth_auth*.xml endpoints.
78
+ raise ApplicationNotFound.new nil if oauth && app_id.nil?
79
+
80
+ validators = if oidc_service
81
+ Validators::OIDC_VALIDATORS
82
+ elsif oauth
83
+ Validators::OAUTH_VALIDATORS
84
+ else
85
+ Validators::VALIDATORS
86
+ end
79
87
 
80
88
  params[:user_key] = nil if params[:user_key] && params[:user_key].empty?
81
89
  application = Application.load_by_id_or_user_key!(service_id,
@@ -98,8 +106,9 @@ module ThreeScale
98
106
  # hierarchy parameter adds information in the response needed
99
107
  # to derive which limits affect directly or indirectly the
100
108
  # metrics for which authorization is requested.
101
- hierarchy: extensions[:hierarchy] == '1',
102
- flat_usage: extensions[:flat_usage] == '1'
109
+ hierarchy: extensions[:hierarchy] == '1'.freeze,
110
+ flat_usage: extensions[:flat_usage] == '1'.freeze,
111
+ list_app_keys: extensions[:list_app_keys] == '1'.freeze
103
112
  }
104
113
 
105
114
  application.load_metric_names
@@ -108,24 +117,6 @@ module ThreeScale
108
117
  apply_validators(validators, status_attrs, params)
109
118
  end
110
119
 
111
- def get_token_ids(token, service_id, app_id)
112
- begin
113
- token_aid = OAuth::Token::Storage.get_credentials(token, service_id)
114
- rescue AccessTokenInvalid => e
115
- # Yep, well, er. Someone specified that it is OK to have an
116
- # invalid token if an app_id is specified. Somehow passing in
117
- # a user_key is still not enough, though...
118
- raise e if app_id.nil?
119
- end
120
-
121
- # We only take the token ids into account if we had no parameter ids
122
- if app_id.nil?
123
- app_id = token_aid
124
- end
125
-
126
- app_id
127
- end
128
-
129
120
  def do_authorize(method, provider_key, params, context_info)
130
121
  notify_authorize(provider_key)
131
122
  validate(method == :oauth_authorize, provider_key, false, params, context_info[:request])
@@ -8,17 +8,23 @@ module ThreeScale
8
8
  # We only use 'redirect_uri' if a request sent such a param. See #397.
9
9
  REDIRECT_URI_FIELD = 'redirect_url'.freeze
10
10
  private_constant :REDIRECT_URI_FIELD
11
+ # Maximum number of keys to list when using the list_app_keys extension
12
+ # At the time of writing System/Porta has a limit of 5 different app_keys
13
+ # at any given moment, but this could change anytime.
14
+ LIST_APP_KEYS_MAX = 256
15
+ private_constant :LIST_APP_KEYS_MAX
11
16
 
12
17
  def initialize(attributes)
13
- @service_id = attributes[:service_id]
14
- @application = attributes[:application]
15
- @oauth = attributes[:oauth]
16
- @usage = attributes[:usage]
17
- @predicted_usage = attributes[:predicted_usage]
18
- @values = filter_values(attributes[:values] || {})
19
- @timestamp = attributes[:timestamp] || Time.now.getutc
20
- @hierarchy_ext = attributes[:hierarchy]
21
- @flat_usage_ext = attributes[:flat_usage]
18
+ @service_id = attributes[:service_id]
19
+ @application = attributes[:application]
20
+ @oauth = attributes[:oauth]
21
+ @usage = attributes[:usage]
22
+ @predicted_usage = attributes[:predicted_usage]
23
+ @values = filter_values(attributes[:values] || {})
24
+ @timestamp = attributes[:timestamp] || Time.now.getutc
25
+ @hierarchy_ext = attributes[:hierarchy]
26
+ @flat_usage_ext = attributes[:flat_usage]
27
+ @list_app_keys_ext = attributes[:list_app_keys]
22
28
 
23
29
  raise 'service_id not specified' if @service_id.nil?
24
30
  raise ':application is required' if @application.nil?
@@ -106,6 +112,7 @@ module ThreeScale
106
112
  add_plan_section(xml, 'plan'.freeze, plan_name)
107
113
  add_reports_section(xml, application_usage_reports)
108
114
  hierarchy_reports.concat application_usage_reports if hierarchy_reports
115
+ add_app_keys_section xml if @list_app_keys_ext
109
116
  end
110
117
 
111
118
  if hierarchy_reports
@@ -161,6 +168,17 @@ module ThreeScale
161
168
  xml << '</hierarchy>'.freeze
162
169
  end
163
170
 
171
+ def add_app_keys_section(xml)
172
+ xml << '<app_keys app="'.freeze
173
+ xml << @application.id << '" svc="'.freeze
174
+ xml << @service_id << '">'.freeze
175
+ @application.keys.take(LIST_APP_KEYS_MAX).each do |key|
176
+ xml << '<key id="'.freeze
177
+ xml << key << '"/>'.freeze
178
+ end
179
+ xml << '</app_keys>'.freeze
180
+ end
181
+
164
182
  # helper to iterate over reports and get relevant hierarchy info
165
183
  def with_report_and_hierarchy(reports)
166
184
  reports.each do |ur|
@@ -21,6 +21,13 @@ module ThreeScale
21
21
  OAUTH_VALIDATORS = ([Validators::OauthSetting,
22
22
  Validators::OauthKey,
23
23
  Validators::RedirectURI] + COMMON_VALIDATORS).freeze
24
+
25
+ # OIDC specific validators will only check app keys when app_key is given.
26
+ #
27
+ # No need to add OauthSetting, since we need to check that to tell
28
+ # OIDC apart from the rest when calling authrep.xml (note lack of
29
+ # the oauth_ prefix).
30
+ OIDC_VALIDATORS = ([Validators::OauthKey] + COMMON_VALIDATORS).freeze
24
31
  end
25
32
  end
26
33
  end
@@ -3,7 +3,7 @@ module ThreeScale
3
3
  module Validators
4
4
  class OauthSetting < Base
5
5
  def apply
6
- if service.backend_version == 'oauth'
6
+ if service.backend_version == 'oauth'.freeze
7
7
  succeed!
8
8
  else
9
9
  fail!(OauthNotEnabled.new)
@@ -1,5 +1,5 @@
1
1
  module ThreeScale
2
2
  module Backend
3
- VERSION = '3.3.0'
3
+ VERSION = '3.4.0'
4
4
  end
5
5
  end
@@ -4,7 +4,7 @@
4
4
  require_relative '../3scale/backend/listener_metrics'
5
5
 
6
6
  # Config is not loaded at this point, so read ENV instead.
7
- if ENV['CONFIG_LISTENER_PROMETHEUS_METRICS_ENABLED'].to_s == 'true'
7
+ if ENV['CONFIG_LISTENER_PROMETHEUS_METRICS_ENABLED'].to_s.downcase.freeze == 'true'.freeze
8
8
  prometheus_port = ENV['CONFIG_LISTENER_PROMETHEUS_METRICS_PORT']
9
9
  ThreeScale::Backend::ListenerMetrics.start_metrics_server(prometheus_port)
10
10
  end
data/licenses.xml CHANGED
@@ -23,7 +23,7 @@
23
23
  </dependency>
24
24
  <dependency>
25
25
  <packageName>apisonator</packageName>
26
- <version>3.3.0</version>
26
+ <version>3.4.0</version>
27
27
  <licenses>
28
28
  <license>
29
29
  <name>Apache 2.0</name>
@@ -233,7 +233,7 @@
233
233
  </dependency>
234
234
  <dependency>
235
235
  <packageName>coderay</packageName>
236
- <version>1.1.2</version>
236
+ <version>1.1.3</version>
237
237
  <licenses>
238
238
  <license>
239
239
  <name>MIT</name>
@@ -421,7 +421,7 @@
421
421
  </dependency>
422
422
  <dependency>
423
423
  <packageName>method_source</packageName>
424
- <version>0.9.0</version>
424
+ <version>1.0.0</version>
425
425
  <licenses>
426
426
  <license>
427
427
  <name>MIT</name>
@@ -475,7 +475,7 @@
475
475
  </dependency>
476
476
  <dependency>
477
477
  <packageName>multi_json</packageName>
478
- <version>1.13.1</version>
478
+ <version>1.15.0</version>
479
479
  <licenses>
480
480
  <license>
481
481
  <name>MIT</name>
@@ -679,7 +679,7 @@
679
679
  </dependency>
680
680
  <dependency>
681
681
  <packageName>pry</packageName>
682
- <version>0.11.3</version>
682
+ <version>0.14.0</version>
683
683
  <licenses>
684
684
  <license>
685
685
  <name>MIT</name>
@@ -699,7 +699,7 @@
699
699
  </dependency>
700
700
  <dependency>
701
701
  <packageName>pry-doc</packageName>
702
- <version>0.11.1</version>
702
+ <version>1.1.0</version>
703
703
  <licenses>
704
704
  <license>
705
705
  <name>MIT</name>
@@ -709,7 +709,7 @@
709
709
  </dependency>
710
710
  <dependency>
711
711
  <packageName>puma</packageName>
712
- <version>2.15.3</version>
712
+ <version>4.3.7</version>
713
713
  <licenses>
714
714
  <license>
715
715
  <name>New BSD</name>
@@ -1143,7 +1143,7 @@
1143
1143
  </dependency>
1144
1144
  <dependency>
1145
1145
  <packageName>yard</packageName>
1146
- <version>0.9.20</version>
1146
+ <version>0.9.26</version>
1147
1147
  <licenses>
1148
1148
  <license>
1149
1149
  <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.3.0
4
+ version: 3.4.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: 2021-02-09 00:00:00.000000000 Z
19
+ date: 2021-06-14 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.
@@ -136,11 +136,7 @@ files:
136
136
  - lib/3scale/backend/stats/bucket_storage.rb
137
137
  - lib/3scale/backend/stats/cleaner.rb
138
138
  - lib/3scale/backend/stats/codes_commons.rb
139
- - lib/3scale/backend/stats/delete_job_def.rb
140
- - lib/3scale/backend/stats/key_generator.rb
141
139
  - lib/3scale/backend/stats/keys.rb
142
- - lib/3scale/backend/stats/partition_eraser_job.rb
143
- - lib/3scale/backend/stats/partition_generator_job.rb
144
140
  - lib/3scale/backend/stats/period_commons.rb
145
141
  - lib/3scale/backend/stats/stats_parser.rb
146
142
  - lib/3scale/backend/stats/storage.rb
@@ -211,8 +207,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
211
207
  - !ruby/object:Gem::Version
212
208
  version: 1.3.7
213
209
  requirements: []
214
- rubyforge_project:
215
- rubygems_version: 2.7.8
210
+ rubygems_version: 3.2.10
216
211
  signing_key:
217
212
  specification_version: 4
218
213
  summary: 3scale web service management system backend
@@ -1,60 +0,0 @@
1
- module ThreeScale
2
- module Backend
3
- module Stats
4
- class DeleteJobDef
5
- ATTRIBUTES = %i[service_id applications metrics from to context_info].freeze
6
- private_constant :ATTRIBUTES
7
- attr_reader(*ATTRIBUTES)
8
-
9
- def self.attribute_names
10
- ATTRIBUTES
11
- end
12
-
13
- def initialize(params = {})
14
- ATTRIBUTES.each do |key|
15
- instance_variable_set("@#{key}".to_sym, params[key]) unless params[key].nil?
16
- end
17
- validate
18
- end
19
-
20
- def run_async
21
- Resque.enqueue(PartitionGeneratorJob, Time.now.getutc.to_f, service_id, applications,
22
- metrics, from, to, context_info)
23
- end
24
-
25
- def to_json
26
- to_hash.to_json
27
- end
28
-
29
- def to_hash
30
- Hash[ATTRIBUTES.collect { |key| [key, send(key)] }]
31
- end
32
-
33
- private
34
-
35
- def validate
36
- # from and to valid epoch times
37
- raise_validation_error('from field not integer') unless from.is_a? Integer
38
- raise_validation_error('from field is zero') if from.zero?
39
- raise_validation_error('to field not integer') unless to.is_a? Integer
40
- raise_validation_error('to field is zero') if to.zero?
41
- raise_validation_error('from < to fields') if Time.at(to) < Time.at(from)
42
- # application is array
43
- raise_validation_error('applications field') unless applications.is_a? Array
44
- raise_validation_error('applications values') unless applications.all? do |x|
45
- x.is_a?(String) || x.is_a?(Integer)
46
- end
47
- # metrics is array
48
- raise_validation_error('metrics field') unless metrics.is_a? Array
49
- raise_validation_error('metrics values') unless metrics.all? do |x|
50
- x.is_a?(String) || x.is_a?(Integer)
51
- end
52
- end
53
-
54
- def raise_validation_error(msg)
55
- raise DeleteServiceStatsValidationError.new(service_id, msg)
56
- end
57
- end
58
- end
59
- end
60
- end
@@ -1,73 +0,0 @@
1
- module ThreeScale
2
- module Backend
3
- module Stats
4
- class KeyGenerator
5
- attr_reader :service_id, :applications, :metrics, :from, :to
6
-
7
- def initialize(service_id:, applications: [], metrics: [], from:, to:, **)
8
- @service_id = service_id
9
- @applications = applications
10
- @metrics = metrics
11
- @from = from
12
- @to = to
13
- end
14
-
15
- def keys
16
- response_code_service_keys +
17
- response_code_application_keys +
18
- usage_service_keys +
19
- usage_application_keys
20
- end
21
-
22
- private
23
-
24
- def periods(granularities)
25
- granularities.flat_map do |granularity|
26
- (Period[granularity].new(Time.at(from))..Period[granularity].new(Time.at(to))).to_a
27
- end
28
- end
29
-
30
- def response_codes
31
- CodesCommons::TRACKED_CODES + CodesCommons::TRACKED_CODE_GROUPS
32
- end
33
-
34
- def response_code_service_keys
35
- periods(PeriodCommons::PERMANENT_SERVICE_GRANULARITIES).flat_map do |period|
36
- response_codes.flat_map do |response_code|
37
- Keys.service_response_code_value_key(service_id, response_code, period)
38
- end
39
- end
40
- end
41
-
42
- def response_code_application_keys
43
- periods(PeriodCommons::PERMANENT_EXPANDED_GRANULARITIES).flat_map do |period|
44
- response_codes.flat_map do |response_code|
45
- applications.flat_map do |application|
46
- Keys.application_response_code_value_key(service_id, application,
47
- response_code, period)
48
- end
49
- end
50
- end
51
- end
52
-
53
- def usage_service_keys
54
- periods(PeriodCommons::PERMANENT_SERVICE_GRANULARITIES).flat_map do |period|
55
- metrics.flat_map do |metric|
56
- Keys.service_usage_value_key(service_id, metric, period)
57
- end
58
- end
59
- end
60
-
61
- def usage_application_keys
62
- periods(PeriodCommons::PERMANENT_EXPANDED_GRANULARITIES).flat_map do |period|
63
- metrics.flat_map do |metric|
64
- applications.flat_map do |application|
65
- Keys.application_usage_value_key(service_id, application, metric, period)
66
- end
67
- end
68
- end
69
- end
70
- end
71
- end
72
- end
73
- end
@@ -1,58 +0,0 @@
1
- module ThreeScale
2
- module Backend
3
- module Stats
4
- # Job for deleting service stats
5
- # Perform actual key deletion from a key partition definition
6
- class PartitionEraserJob < BackgroundJob
7
- # low priority queue
8
- @queue = :stats
9
-
10
- class << self
11
- include StorageHelpers
12
- include Configurable
13
-
14
- def perform_logged(_enqueue_time, service_id, applications, metrics,
15
- from, to, offset, length, context_info = {})
16
- job = DeleteJobDef.new(
17
- service_id: service_id,
18
- applications: applications,
19
- metrics: metrics,
20
- from: from,
21
- to: to
22
- )
23
-
24
- validate_job(job, offset, length)
25
-
26
- stats_key_gen = KeyGenerator.new(job.to_hash)
27
-
28
- stats_key_gen.keys.drop(offset).take(length).each_slice(configuration.stats.delete_batch_size) do |slice|
29
- storage.del(slice)
30
- end
31
-
32
- [true, { job: job.to_hash, offset: offset, lenght: length }.to_json]
33
- rescue Backend::Error => error
34
- [false, "#{service_id} #{error}"]
35
- end
36
-
37
- private
38
-
39
- def validate_job(job, offset, length)
40
- unless offset.is_a? Integer
41
- raise DeleteServiceStatsValidationError.new(job.service_id, 'offset field value ' \
42
- "[#{offset}] validation error")
43
- end
44
-
45
- unless length.is_a? Integer
46
- raise DeleteServiceStatsValidationError.new(job.service_id, 'length field value ' \
47
- "[#{length}] validation error")
48
- end
49
- end
50
-
51
- def enqueue_time(args)
52
- args[0]
53
- end
54
- end
55
- end
56
- end
57
- end
58
- end
@@ -1,46 +0,0 @@
1
- module ThreeScale
2
- module Backend
3
- module Stats
4
- # Job for deleting service stats
5
- # Maps delete job definition to a set of non overlapping key set partitions
6
- class PartitionGeneratorJob < BackgroundJob
7
- # low priority queue
8
- @queue = :stats
9
-
10
- class << self
11
- include Configurable
12
-
13
- def perform_logged(_enqueue_time, service_id, applications, metrics,
14
- from, to, context_info = {})
15
- job = DeleteJobDef.new(
16
- service_id: service_id,
17
- applications: applications,
18
- metrics: metrics,
19
- from: from,
20
- to: to
21
- )
22
-
23
- stats_key_gen = KeyGenerator.new(job.to_hash)
24
-
25
- # Generate partitions
26
- 0.step(stats_key_gen.keys.count, configuration.stats.delete_partition_batch_size).each do |idx|
27
- Resque.enqueue(PartitionEraserJob, Time.now.getutc.to_f, service_id, applications,
28
- metrics, from, to, idx,
29
- configuration.stats.delete_partition_batch_size, context_info)
30
- end
31
-
32
- [true, job.to_json]
33
- rescue Backend::Error => error
34
- [false, "#{service_id} #{error}"]
35
- end
36
-
37
- private
38
-
39
- def enqueue_time(args)
40
- args[0]
41
- end
42
- end
43
- end
44
- end
45
- end
46
- end