apisonator 3.3.0 → 3.4.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: 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