zuora_connect 2.1.1 → 3.0.0.pre.e
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 +4 -4
- data/app/controllers/zuora_connect/static_controller.rb +84 -17
- data/app/models/zuora_connect/app_instance_base.rb +175 -106
- data/app/models/zuora_connect/zuora_user.rb +1 -1
- data/config/initializers/postgresql_adapter.rb +71 -1
- data/config/initializers/prometheus.rb +80 -23
- data/config/initializers/redis.rb +4 -4
- data/config/initializers/resque.rb +14 -12
- data/config/initializers/unicorn.rb +30 -2
- data/config/routes.rb +5 -1
- data/lib/metrics/net.rb +7 -7
- data/lib/middleware/json_parse_errors.rb +13 -2
- data/lib/middleware/metrics_middleware.rb +48 -72
- data/lib/resque/dynamic_queues.rb +1 -1
- data/lib/resque/plugins/app_instance_job.rb +6 -10
- data/lib/zuora_connect.rb +6 -63
- data/lib/zuora_connect/controllers/helpers.rb +229 -89
- data/lib/zuora_connect/engine.rb +2 -1
- data/lib/zuora_connect/railtie.rb +6 -64
- data/lib/zuora_connect/version.rb +1 -1
- data/lib/zuora_connect/zuora_audit.rb +31 -0
- metadata +19 -7
- data/app/models/zuora_connect/telegraf.rb +0 -97
- data/lib/logging/connect_formatter.rb +0 -44
- data/lib/metrics/influx/point_value.rb +0 -79
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f36eda986a37f2574d06c4e34785ba6da29d6dc1b4308744e8e73defd48c25a
|
4
|
+
data.tar.gz: 9b29a5f07f44fd2ba9df5440498fd1de7a9683654ca0ec7c742def938df8c166
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce99e27b914104c581943f5abed30d298841e402d6a76c53884c2041a4d1bf9780f063357f865ead9e8b144ade8dc8ac7d5fbdd64bfe54bb9a833df32ad30fa3
|
7
|
+
data.tar.gz: 5b108c5a4048412c39f0f5fb99c76532c0671012fb47c92397239c999fe7c0ea48af10132e41acb80f9957a6415282faea9c840c84f9c104bb268cce9de8812d
|
@@ -1,23 +1,20 @@
|
|
1
1
|
module ZuoraConnect
|
2
2
|
class StaticController < ApplicationController
|
3
|
-
before_action :authenticate_connect_app_request, :except => [:
|
4
|
-
before_action :clear_connect_app_session, :only => [:
|
5
|
-
after_action :persist_connect_app_session, :except => [:
|
6
|
-
|
7
|
-
skip_before_action :verify_authenticity_token, :only => [:initialize_app]
|
8
|
-
|
9
|
-
|
10
|
-
type = params[:type].present? ? params[:type] : "versions"
|
11
|
-
render json: ZuoraConnect::AppInstance.get_metrics(type).to_json, status: 200
|
12
|
-
end
|
3
|
+
before_action :authenticate_connect_app_request, :except => [:health, :initialize_app, :provision, :instance_user]
|
4
|
+
before_action :clear_connect_app_session, :only => [:health, :initialize_app, :provision, :instance_user]
|
5
|
+
after_action :persist_connect_app_session, :except => [:health, :initialize_app, :provision, :instance_user]
|
6
|
+
|
7
|
+
skip_before_action :verify_authenticity_token, :only => [:initialize_app, :provision]
|
8
|
+
http_basic_authenticate_with name: ENV['PROVISION_USER'], password: ENV['PROVISION_SECRET'], :only => [:provision, :instance_user]
|
9
|
+
|
13
10
|
|
14
11
|
def health
|
15
12
|
if params[:error].present?
|
16
|
-
begin
|
13
|
+
begin
|
17
14
|
raise ZuoraConnect::Exceptions::Error.new('This is an error')
|
18
15
|
rescue => ex
|
19
16
|
case params[:error]
|
20
|
-
when 'Log'
|
17
|
+
when 'Log'
|
21
18
|
Rails.logger.error("Error in Health", ex)
|
22
19
|
when 'Exception'
|
23
20
|
raise
|
@@ -34,11 +31,13 @@ module ZuoraConnect
|
|
34
31
|
def initialize_app
|
35
32
|
begin
|
36
33
|
authenticate_connect_app_request
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
34
|
+
unless performed?
|
35
|
+
@appinstance.new_session(:session => @appinstance.data_lookup(:session => session))
|
36
|
+
render json: {
|
37
|
+
message: 'Success',
|
38
|
+
status: 200
|
39
|
+
}, status: 200
|
40
|
+
end
|
42
41
|
rescue => ex
|
43
42
|
Rails.logger.error("Failed to Initialize application", ex)
|
44
43
|
if performed?
|
@@ -52,6 +51,74 @@ module ZuoraConnect
|
|
52
51
|
end
|
53
52
|
end
|
54
53
|
|
54
|
+
def provision
|
55
|
+
create_new_instance
|
56
|
+
unless performed?
|
57
|
+
render json: {
|
58
|
+
status: 200,
|
59
|
+
message: 'Success',
|
60
|
+
app_instance_id: @appinstance.id
|
61
|
+
}, status: 200
|
62
|
+
end
|
63
|
+
rescue StandardError => e
|
64
|
+
message = 'Failed to provision new instance'
|
65
|
+
if performed?
|
66
|
+
Rails.logger.error("#{message}: #{performed?}", e)
|
67
|
+
else
|
68
|
+
Rails.logger.error(message, e)
|
69
|
+
render json: {
|
70
|
+
status: 500,
|
71
|
+
message: message
|
72
|
+
}, status: 500
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def instance_user
|
77
|
+
ZuoraConnect::AppInstance.read_master_db do
|
78
|
+
ZuoraConnect.logger.with_fields = {} if ZuoraConnect.logger.is_a?(Ougai::Logger)
|
79
|
+
Rails.logger.with_fields = {} if Rails.logger.is_a?(Ougai::Logger)
|
80
|
+
|
81
|
+
if defined?(ElasticAPM) && ElasticAPM.running? && ElasticAPM.respond_to?(:set_label)
|
82
|
+
ElasticAPM.set_label(:trace_id, request.uuid)
|
83
|
+
end
|
84
|
+
|
85
|
+
unless params[:id].present?
|
86
|
+
render json: {
|
87
|
+
status: 400,
|
88
|
+
message: 'No app instance id provided'
|
89
|
+
}, status: :bad_request
|
90
|
+
return
|
91
|
+
end
|
92
|
+
|
93
|
+
@appinstance = ZuoraConnect::AppInstance.find(params[:id]).new_session
|
94
|
+
end
|
95
|
+
|
96
|
+
zuora_client = @appinstance.send(ZuoraConnect::AppInstance::LOGIN_TENANT_DESTINATION).client
|
97
|
+
client_describe, = zuora_client.rest_call(
|
98
|
+
url: zuora_client.rest_endpoint('genesis/user/info').gsub('v1/', ''),
|
99
|
+
session_type: zuora_client.class == ZuoraAPI::Oauth ? :bearer : :basic
|
100
|
+
)
|
101
|
+
|
102
|
+
render json: {
|
103
|
+
status: 200,
|
104
|
+
message: 'Success',
|
105
|
+
user_id: client_describe['coreUserId'],
|
106
|
+
username: client_describe['username'],
|
107
|
+
email: client_describe['workEmail']
|
108
|
+
}, status: 200
|
109
|
+
rescue ActiveRecord::RecordNotFound
|
110
|
+
render json: {
|
111
|
+
status: 400,
|
112
|
+
message: 'No app instance found'
|
113
|
+
}, status: :bad_request
|
114
|
+
rescue StandardError => e
|
115
|
+
Rails.logger.error('Error occurred getting user details', e)
|
116
|
+
render json: {
|
117
|
+
status: 500,
|
118
|
+
message: 'Failed to get user details'
|
119
|
+
}, status: 500
|
120
|
+
end
|
121
|
+
|
55
122
|
private
|
56
123
|
|
57
124
|
def clear_connect_app_session
|
@@ -11,8 +11,7 @@ module ZuoraConnect
|
|
11
11
|
before_destroy :prune_data
|
12
12
|
|
13
13
|
self.table_name = "zuora_connect_app_instances"
|
14
|
-
attr_accessor :options, :mode, :logins, :task_data, :last_refresh, :username, :password, :s3_client, :api_version, :drop_message, :new_session_message, :connect_user, :logitems
|
15
|
-
@@telegraf_host = nil
|
14
|
+
attr_accessor :options, :mode, :logins, :task_data, :last_refresh, :username, :password, :s3_client, :api_version, :drop_message, :new_session_message, :connect_user, :logitems, :user_timezone
|
16
15
|
REFRESH_TIMEOUT = 2.minute #Used to determine how long to wait on current refresh call before executing another
|
17
16
|
INSTANCE_REFRESH_WINDOW = 1.hours #Used to set how how long till app starts attempting to refresh cached task connect data
|
18
17
|
INSTANCE_REDIS_CACHE_PERIOD = 24.hours #Used to determine how long to cached task data will live for
|
@@ -21,6 +20,12 @@ module ZuoraConnect
|
|
21
20
|
HOLDING_PATTERN_SLEEP = 5.seconds
|
22
21
|
CONNECT_APPLICATION_ID = 0
|
23
22
|
CONNECT_COMMUNICATION_SLEEP = Rails.env.test? ? 0.seconds : 5.seconds
|
23
|
+
CATALOG_LOOKUP_PAGE_SIZE = 10_000
|
24
|
+
CATALOG_LOOKUP_CACHE_TIME_KEY = 'CatalogCachedAt'
|
25
|
+
CATALOG_LOOKUP_TTL = 60.seconds
|
26
|
+
CATALOG_LOOKUP_CACHE_RESULT_KEY = 'CatalogCache'
|
27
|
+
TIMEZONE_LOG_RATE_LIMIT_KEY = 'TimezoneLoggedAt'
|
28
|
+
TIMEZONE_LOG_PERIOD = 4.hours
|
24
29
|
IGNORED_LOCALS = ['fr', 'ja', 'es', 'zh', 'de']
|
25
30
|
INTERNAL_HOSTS = []
|
26
31
|
LOGIN_TENANT_DESTINATION = 'target_login'
|
@@ -29,7 +34,7 @@ module ZuoraConnect
|
|
29
34
|
Aws::Errors::MissingCredentialsError,
|
30
35
|
Aws::S3::Errors::AccessDenied,
|
31
36
|
Aws::SES::Errors::AccessDenied,
|
32
|
-
Aws::KMS::Errors::AccessDeniedException
|
37
|
+
Aws::KMS::Errors::AccessDeniedException
|
33
38
|
].freeze
|
34
39
|
AWS_AUTH_ERRORS_MSG = "AWS Auth Errors".freeze
|
35
40
|
|
@@ -163,6 +168,7 @@ module ZuoraConnect
|
|
163
168
|
end
|
164
169
|
|
165
170
|
self.build_task(task_data: mock_task_data, session: session)
|
171
|
+
self.set_backup_creds
|
166
172
|
self.last_refresh = Time.now.to_i
|
167
173
|
else
|
168
174
|
time_expire = (session["#{self.id}::last_refresh"] || Time.now).to_i - INSTANCE_REFRESH_WINDOW.ago.to_i
|
@@ -240,7 +246,9 @@ module ZuoraConnect
|
|
240
246
|
rescue I18n::InvalidLocale => ex
|
241
247
|
ZuoraConnect.logger.error(ex) if !IGNORED_LOCALS.include?(ex.locale.to_s.downcase)
|
242
248
|
end
|
243
|
-
|
249
|
+
|
250
|
+
self.set_timezone
|
251
|
+
|
244
252
|
if self.task_data.present?
|
245
253
|
tenants = self.task_data.fetch('tenant_ids', [])
|
246
254
|
organizations = self.task_data.fetch('organizations', [])
|
@@ -255,7 +263,7 @@ module ZuoraConnect
|
|
255
263
|
end
|
256
264
|
|
257
265
|
params = {
|
258
|
-
name: self.task_data.dig('name'),
|
266
|
+
name: self.task_data.dig('name'),
|
259
267
|
zuora_entity_ids: (self.task_data.dig(LOGIN_TENANT_DESTINATION,'entities') || []).map{|e| e['id']}.uniq,
|
260
268
|
zuora_tenant_ids: tenants.map(&:to_s).uniq,
|
261
269
|
organizations: organizations
|
@@ -264,7 +272,7 @@ module ZuoraConnect
|
|
264
272
|
client = self.send(LOGIN_TENANT_DESTINATION).client
|
265
273
|
if defined?(client.rest_domain)
|
266
274
|
ZuoraConnect::RequestIdMiddleware.zuora_rest_domain = client.rest_domain
|
267
|
-
params.merge!({zuora_domain: client.rest_domain, environment: client.environment })
|
275
|
+
params.merge!({zuora_domain: client.rest_domain, environment: client.environment })
|
268
276
|
end
|
269
277
|
end
|
270
278
|
params = params.reject{|k,v| !self.attributes.keys.member?(k.to_s) || self[k] == v}
|
@@ -272,12 +280,77 @@ module ZuoraConnect
|
|
272
280
|
end
|
273
281
|
end
|
274
282
|
|
275
|
-
def
|
283
|
+
def set_timezone(timezone: self.timezone, type: :default)
|
284
|
+
if timezone.blank?
|
285
|
+
timezone = self.timezone
|
286
|
+
end
|
287
|
+
|
288
|
+
if type == :default
|
289
|
+
Time.zone = timezone
|
290
|
+
elsif type == :user
|
291
|
+
begin
|
292
|
+
sql = <<-eos
|
293
|
+
SELECT zuora_users.zuora_identity_response FROM "#{self.id}".zuora_users ORDER BY zuora_users.updated_at DESC LIMIT 1;
|
294
|
+
eos
|
295
|
+
user = ActiveRecord::Base.connection.execute(sql).to_a.first
|
296
|
+
|
297
|
+
if user.present?
|
298
|
+
zuora_identity_response = JSON.parse(user.fetch('zuora_identity_response', '{}'))
|
299
|
+
self.user_timezone = zuora_identity_response.values.first&.dig('timeZone')
|
300
|
+
else
|
301
|
+
if (Redis.current.hget(TIMEZONE_LOG_RATE_LIMIT_KEY, self.id).to_i + TIMEZONE_LOG_PERIOD.to_i) <= Time.now.to_i
|
302
|
+
Rails.logger.error('Cannot find any user to set the timezone', app_instance_id: self.id)
|
303
|
+
Redis.current.hset(TIMEZONE_LOG_RATE_LIMIT_KEY, self.id, Time.now.to_i)
|
304
|
+
end
|
305
|
+
end
|
306
|
+
rescue => ex
|
307
|
+
Rails.logger.error('There is an error while getting timezone users', ex)
|
308
|
+
end
|
309
|
+
|
310
|
+
if self.user_timezone.present?
|
311
|
+
# connect instance which has a custom timezone
|
312
|
+
if !self.auto_deployed? && (
|
313
|
+
ActiveSupport::TimeZone[self.task_data.dig('user_settings', 'timezone') || '']&.utc_offset !=
|
314
|
+
ActiveSupport::TimeZone[self.user_timezone]&.utc_offset
|
315
|
+
)
|
316
|
+
if self.environment == 'Production' &&
|
317
|
+
(Redis.current.hget(TIMEZONE_LOG_RATE_LIMIT_KEY, self.id).to_i + TIMEZONE_LOG_PERIOD.to_i) <= Time.now.to_i
|
318
|
+
ZuoraConnect.logger.error(
|
319
|
+
"Instance and user timezones are different. User has '#{self.user_timezone}' and " \
|
320
|
+
"instance has '#{self.task_data.dig('user_settings', 'timezone')}'",
|
321
|
+
app_instance_id: self.id
|
322
|
+
)
|
323
|
+
Redis.current.hset(TIMEZONE_LOG_RATE_LIMIT_KEY, self.id, Time.now.to_i)
|
324
|
+
end
|
325
|
+
self.user_timezone = nil
|
326
|
+
Time.zone = timezone
|
327
|
+
else
|
328
|
+
begin
|
329
|
+
Time.zone = self.user_timezone
|
330
|
+
rescue ArgumentError
|
331
|
+
Rails.logger.error('Malformed user timezone', app_instance_id: self.id)
|
332
|
+
Time.zone = timezone
|
333
|
+
end
|
334
|
+
end
|
335
|
+
else
|
336
|
+
Time.zone = timezone
|
337
|
+
end
|
338
|
+
end
|
339
|
+
rescue => e
|
340
|
+
Rails.logger.error('Malformed timezone used', e, app_instance_id: self.id)
|
341
|
+
Time.zone = self.timezone
|
342
|
+
end
|
343
|
+
|
344
|
+
def auto_deployed?
|
345
|
+
self.id >= 25000000
|
346
|
+
end
|
347
|
+
|
348
|
+
def refresh(session: {})
|
276
349
|
refresh_count ||= 0
|
277
350
|
skip_connect ||= false
|
278
351
|
begin
|
279
352
|
#Check how app was deployed
|
280
|
-
if self.
|
353
|
+
if !self.auto_deployed? && !skip_connect
|
281
354
|
self.check_oauth_state
|
282
355
|
response = HTTParty.get(ZuoraConnect.configuration.url + "/api/#{self.api_version}/tools/tasks/#{self.id}.json",:body => {:access_token => self.access_token})
|
283
356
|
|
@@ -289,16 +362,8 @@ module ZuoraConnect
|
|
289
362
|
end
|
290
363
|
|
291
364
|
self.build_task(task_data: parsed_json, session: session)
|
292
|
-
|
293
|
-
|
294
|
-
self.zuora_logins = self.strip_cache_data(object: parsed_json.dup, keys: ['applications', 'tokens', 'user_settings'])
|
295
|
-
self.save(:validate => false)
|
296
|
-
rescue Aws::KMS::Errors::ValidationException, *AWS_AUTH_ERRORS => ex
|
297
|
-
Rails.logger.warn(AWS_AUTH_ERRORS_MSG, ex)
|
298
|
-
rescue => ex
|
299
|
-
Rails.logger.error(AWS_AUTH_ERRORS_MSG, ex)
|
300
|
-
end
|
301
|
-
end
|
365
|
+
self.set_backup_creds
|
366
|
+
self.save(validate: false) if self.changed?
|
302
367
|
else
|
303
368
|
raise ZuoraConnect::Exceptions::ConnectCommunicationError.new("Error Communicating with Connect", response.body, response.code)
|
304
369
|
end
|
@@ -338,9 +403,21 @@ module ZuoraConnect
|
|
338
403
|
raise
|
339
404
|
end
|
340
405
|
|
406
|
+
def aws_secrets
|
407
|
+
(Rails.application.secrets.aws || {}).transform_keys { |key| key.to_s }
|
408
|
+
end
|
409
|
+
|
341
410
|
#### START KMS ENCRYPTION Methods ####
|
411
|
+
def set_backup_creds
|
412
|
+
if self.kms_key.present? && self.kms_key.match(/^arn:aws:.*/) && self.task_data.present?
|
413
|
+
self.zuora_logins = self.strip_cache_data(object: self.task_data.dup, keys: ['applications', 'tokens', 'user_settings'])
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
342
417
|
def zuora_logins=(val)
|
343
418
|
write_attribute(:zuora_logins, kms_encrypt(val.to_json))
|
419
|
+
rescue Aws::KMS::Errors::ValidationException, Aws::KMS::Errors::NotFoundException, *AWS_AUTH_ERRORS => ex
|
420
|
+
Rails.logger.warn(AWS_AUTH_ERRORS_MSG, ex)
|
344
421
|
end
|
345
422
|
|
346
423
|
def zuora_logins
|
@@ -350,7 +427,7 @@ module ZuoraConnect
|
|
350
427
|
|
351
428
|
def kms_decrypt(value)
|
352
429
|
kms_tries ||= 0
|
353
|
-
kms_client = Aws::KMS::Client.new({region:
|
430
|
+
kms_client = Aws::KMS::Client.new({region: aws_secrets['AWS_REGION'], credentials: self.aws_auth_client}.delete_if { |k, v| v.blank? })
|
354
431
|
resp = kms_client.decrypt({ciphertext_blob: [value].pack("H*") })
|
355
432
|
return resp.plaintext
|
356
433
|
rescue *AWS_AUTH_ERRORS => ex
|
@@ -365,7 +442,7 @@ module ZuoraConnect
|
|
365
442
|
|
366
443
|
def kms_encrypt(value)
|
367
444
|
kms_tries ||= 0
|
368
|
-
kms_client = Aws::KMS::Client.new({region:
|
445
|
+
kms_client = Aws::KMS::Client.new({region: aws_secrets['AWS_REGION'], credentials: self.aws_auth_client}.delete_if {|k,v| v.blank? })
|
369
446
|
|
370
447
|
resp = kms_client.encrypt({key_id: kms_key, plaintext: value})
|
371
448
|
return resp.ciphertext_blob.unpack('H*').first
|
@@ -380,12 +457,12 @@ module ZuoraConnect
|
|
380
457
|
end
|
381
458
|
|
382
459
|
def kms_key
|
383
|
-
return ENV['AWS_KMS_ARN'] ||
|
460
|
+
return ENV['AWS_KMS_ARN'] || aws_secrets['AWS_KMS_ARN']
|
384
461
|
end
|
385
462
|
|
386
463
|
def aws_auth_client
|
387
464
|
if Rails.env.to_s == 'development'
|
388
|
-
return Aws::Credentials.new(
|
465
|
+
return Aws::Credentials.new(aws_secrets['AWS_ACCESS_KEY_ID'], aws_secrets['AWS_SECRET_ACCESS_KEY'])
|
389
466
|
else
|
390
467
|
return nil
|
391
468
|
end
|
@@ -400,82 +477,6 @@ module ZuoraConnect
|
|
400
477
|
end
|
401
478
|
Thread.current[:appinstance] = self
|
402
479
|
end
|
403
|
-
|
404
|
-
def self.write_to_telegraf(*args)
|
405
|
-
if ZuoraConnect.configuration.enable_metrics
|
406
|
-
@@telegraf_host = ZuoraConnect::Telegraf.new() if @@telegraf_host == nil
|
407
|
-
unicorn_stats = self.unicorn_listener_stats() if defined?(Unicorn) && Unicorn.respond_to?(:listener_names)
|
408
|
-
@@telegraf_host.write(direction: 'Raindrops', tags: {}, values: unicorn_stats) unless unicorn_stats.blank?
|
409
|
-
return @@telegraf_host.write(*args)
|
410
|
-
end
|
411
|
-
end
|
412
|
-
|
413
|
-
def self.unicorn_listener_stats ()
|
414
|
-
stats_hash = {}
|
415
|
-
stats_hash["total_active"] = 0
|
416
|
-
stats_hash["total_queued"] = 0
|
417
|
-
|
418
|
-
begin
|
419
|
-
tmp = Unicorn.listener_names
|
420
|
-
unix = tmp.grep(%r{\A/})
|
421
|
-
tcp = tmp.grep(/\A.+:\d+\z/)
|
422
|
-
tcp = nil if tcp.empty?
|
423
|
-
unix = nil if unix.empty?
|
424
|
-
|
425
|
-
|
426
|
-
Raindrops::Linux.tcp_listener_stats(tcp).each do |addr,stats|
|
427
|
-
stats_hash["active_#{addr}"] = stats.active
|
428
|
-
stats_hash["queued_#{addr}"] = stats.queued
|
429
|
-
stats_hash["total_active"] = stats.active + stats_hash["total_active"]
|
430
|
-
stats_hash["total_queued"] = stats.queued + stats_hash["total_queued"]
|
431
|
-
end if tcp
|
432
|
-
|
433
|
-
Raindrops::Linux.unix_listener_stats(unix).each do |addr,stats|
|
434
|
-
stats_hash["active_#{addr}"] = stats.active
|
435
|
-
stats_hash["queued_#{addr}"] = stats.queued
|
436
|
-
stats_hash["total_active"] = stats.active + stats_hash["total_active"]
|
437
|
-
stats_hash["total_queued"] = stats.queued + stats_hash["total_queued"]
|
438
|
-
end if unix
|
439
|
-
rescue IOError => ex
|
440
|
-
rescue => ex
|
441
|
-
ZuoraConnect.logger.error(ex)
|
442
|
-
end
|
443
|
-
return stats_hash
|
444
|
-
end
|
445
|
-
|
446
|
-
def self.get_metrics(type)
|
447
|
-
@data = {}
|
448
|
-
|
449
|
-
if type == "versions"
|
450
|
-
@data = {
|
451
|
-
app_name: ZuoraConnect::Telegraf.app_name,
|
452
|
-
url: "dummy",
|
453
|
-
Version_Gem: ZuoraConnect::VERSION,
|
454
|
-
Version_Zuora: ZuoraAPI::VERSION ,
|
455
|
-
Version_Ruby: RUBY_VERSION,
|
456
|
-
Version_Rails: Rails.version,
|
457
|
-
hold: 1
|
458
|
-
}
|
459
|
-
elsif type == "stats"
|
460
|
-
begin
|
461
|
-
Resque.redis.ping
|
462
|
-
@resque = Resque.info
|
463
|
-
@data = {
|
464
|
-
app_name: ZuoraConnect::Telegraf.app_name,
|
465
|
-
url: "dummy",
|
466
|
-
Resque:{
|
467
|
-
Jobs_Finished: @resque[:processed] ,
|
468
|
-
Jobs_Failed: @resque[:failed],
|
469
|
-
Jobs_Pending: @resque[:pending],
|
470
|
-
Workers_Active: @resque[:working],
|
471
|
-
Workers_Total: @resque[:workers]
|
472
|
-
}
|
473
|
-
}
|
474
|
-
rescue
|
475
|
-
end
|
476
|
-
end
|
477
|
-
return @data
|
478
|
-
end
|
479
480
|
#### END Task Methods ####
|
480
481
|
|
481
482
|
#### START Task Methods ####
|
@@ -518,7 +519,7 @@ module ZuoraConnect
|
|
518
519
|
end
|
519
520
|
rescue ZuoraConnect::Exceptions::MissMatch => ex
|
520
521
|
raise
|
521
|
-
rescue ZuoraConnect::Exceptions::InvalidCredentialSet => ex
|
522
|
+
rescue ZuoraConnect::Exceptions::InvalidCredentialSet => ex
|
522
523
|
raise
|
523
524
|
rescue => ex
|
524
525
|
ZuoraConnect.logger.error("Build Task Error", ex)
|
@@ -574,12 +575,12 @@ module ZuoraConnect
|
|
574
575
|
self.refresh if !defined?(self.target_login)
|
575
576
|
|
576
577
|
response = HTTParty.get("#{ZuoraConnect.configuration.url}/api/#{self.api_version}/tenants/search?hostname=#{self.target_login.client.hostname}&node_id=#{self.zuora_entity_ids.first}")
|
577
|
-
|
578
|
+
|
578
579
|
if response.success?
|
579
580
|
parsed_json = JSON.parse(response.body)
|
580
|
-
|
581
|
+
|
581
582
|
#Set Org
|
582
|
-
if self.
|
583
|
+
if self.auto_deployed? && parsed_json['organization'].present?
|
583
584
|
login_cache = self.zuora_logins
|
584
585
|
login_cache.delete('organization')
|
585
586
|
self.zuora_logins = login_cache.merge({'organizations' => [parsed_json['organization']]})
|
@@ -599,7 +600,7 @@ module ZuoraConnect
|
|
599
600
|
end
|
600
601
|
end
|
601
602
|
self.save(:validate => false)
|
602
|
-
|
603
|
+
|
603
604
|
return parsed_json
|
604
605
|
end
|
605
606
|
rescue *(ZuoraAPI::Login::CONNECTION_EXCEPTIONS + ZuoraAPI::Login::CONNECTION_READ_EXCEPTIONS) => ex
|
@@ -653,7 +654,7 @@ module ZuoraConnect
|
|
653
654
|
end
|
654
655
|
|
655
656
|
def refresh_oauth
|
656
|
-
refresh_oauth_count ||= 0
|
657
|
+
refresh_oauth_count ||= 0
|
657
658
|
response = HTTParty.post("#{ZuoraConnect.configuration.url}/oauth/token", body: {
|
658
659
|
:grant_type => "refresh_token",
|
659
660
|
:redirect_uri => ZuoraConnect.configuration.oauth_client_redirect_uri,
|
@@ -955,13 +956,81 @@ module ZuoraConnect
|
|
955
956
|
# object_id: The id or id's of the object/objects to be returned.
|
956
957
|
# child_objects: Whether to include child objects of the object in question.
|
957
958
|
# cache: Store individual "1" object lookup in redis for caching.
|
958
|
-
def catalog_lookup(entity_id: nil, object: :product, object_id: nil, child_objects: false, cache: false)
|
959
|
+
def catalog_lookup(entity_id: nil, object: :product, object_id: nil, child_objects: false, cache: false, source: 'DB')
|
959
960
|
entity_reference = entity_id.blank? ? 'Default' : entity_id
|
960
961
|
|
961
962
|
if object_id.present? && ![Array, String].include?(object_id.class)
|
962
963
|
raise "Object Id can only be a string or an array of strings"
|
963
964
|
end
|
964
965
|
|
966
|
+
if source == 'API'
|
967
|
+
catalog_container = {}
|
968
|
+
|
969
|
+
if (Redis.current.hget(CATALOG_LOOKUP_CACHE_TIME_KEY, self.id).to_i + CATALOG_LOOKUP_TTL.to_i) > Time.now.to_i
|
970
|
+
begin
|
971
|
+
catalog_container = JSON.parse(Redis.current.hget(CATALOG_LOOKUP_CACHE_RESULT_KEY, self.id))
|
972
|
+
rescue JSON::ParserError => ex
|
973
|
+
Rails.logger.warn('Failed to parse catalog cache', ex)
|
974
|
+
end
|
975
|
+
else
|
976
|
+
zuora_login = self.login_lookup(type: 'Zuora').first
|
977
|
+
login = zuora_login.client(entity_reference)
|
978
|
+
|
979
|
+
response = {
|
980
|
+
'nextPage' => login.rest_endpoint("catalog/products?pageSize=#{CATALOG_LOOKUP_PAGE_SIZE}")
|
981
|
+
}
|
982
|
+
|
983
|
+
while response['nextPage'].present?
|
984
|
+
url = login.rest_endpoint(response['nextPage'].split('/v1/').last)
|
985
|
+
output_json, response = login.rest_call(debug: false, url: url, timeout_retry: true)
|
986
|
+
|
987
|
+
case object
|
988
|
+
when :product
|
989
|
+
output_json.fetch('products', []).each do |product|
|
990
|
+
rate_plans = {}
|
991
|
+
product['productRatePlans'].each do |rate_plan|
|
992
|
+
charges = {}
|
993
|
+
rate_plan['productRatePlanCharges'].each do |charge|
|
994
|
+
charges[charge['id']] = charge.merge(
|
995
|
+
{
|
996
|
+
'productId' => product['id'],
|
997
|
+
'productName' => product['name'],
|
998
|
+
'productRatePlanId' => rate_plan['id'],
|
999
|
+
'productRatePlanName' => rate_plan['name'],
|
1000
|
+
}
|
1001
|
+
)
|
1002
|
+
end
|
1003
|
+
|
1004
|
+
rate_plan['productRatePlanCharges'] = charges
|
1005
|
+
rate_plans[rate_plan['id']] = rate_plan.merge(
|
1006
|
+
{
|
1007
|
+
'productId' => product['id'],
|
1008
|
+
'productName' => product['name']
|
1009
|
+
}
|
1010
|
+
)
|
1011
|
+
end
|
1012
|
+
|
1013
|
+
product['productRatePlans'] = rate_plans
|
1014
|
+
catalog_container[product['id']] = product
|
1015
|
+
end
|
1016
|
+
else
|
1017
|
+
raise "Available objects include [:product]"
|
1018
|
+
end
|
1019
|
+
end
|
1020
|
+
|
1021
|
+
Redis.current.hset(CATALOG_LOOKUP_CACHE_RESULT_KEY, self.id, catalog_container.to_json)
|
1022
|
+
Redis.current.hset(CATALOG_LOOKUP_CACHE_TIME_KEY, self.id, Time.now.to_i)
|
1023
|
+
end
|
1024
|
+
|
1025
|
+
if object_id.nil?
|
1026
|
+
catalog_container.transform_values! { |v| v.except('productRatePlans') }
|
1027
|
+
elsif object_id.is_a?(String)
|
1028
|
+
catalog_container = catalog_container[object_id]
|
1029
|
+
end
|
1030
|
+
|
1031
|
+
return catalog_container
|
1032
|
+
end
|
1033
|
+
|
965
1034
|
if defined?(Redis.current) && object_id.present? && object_id.class == String && object_id.present?
|
966
1035
|
stub_catalog = cache ? decrypt_data(data: Redis.current.get("Catalog:#{self.id}:#{object_id}:Children:#{child_objects}")) : nil
|
967
1036
|
object_hierarchy = decrypt_data(data: Redis.current.get("Catalog:#{self.id}:#{object_id}:Hierarchy"))
|
@@ -1221,7 +1290,7 @@ module ZuoraConnect
|
|
1221
1290
|
|
1222
1291
|
def self.without_sticking
|
1223
1292
|
if self.connection.respond_to?(:without_sticking)
|
1224
|
-
self.connection.without_sticking do
|
1293
|
+
self.connection.without_sticking do
|
1225
1294
|
yield
|
1226
1295
|
end
|
1227
1296
|
else
|