zuora_connect 2.1.1 → 3.0.0.pre.e
Sign up to get free protection for your applications and to get access to all the features.
- 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
|