zuora_connect 2.1.1 → 3.0.0.pre.a

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: 0342c5ac7396b4e8ba75aff8dbab5d579fa6d0ad04a421b7d1d809ab3abbd90a
4
- data.tar.gz: 70f7277a93fec8e481f63e56f85e466b5e0b4d1307e2413e4f8da9497e980be2
3
+ metadata.gz: e63c10c8405375ad7cb2c28073c6181ed055266fb8d61e3ac5725e8f5b8ca8d5
4
+ data.tar.gz: c5124fe3590fd14c0acdad0cfe6e567997195eaa728245f620bfff5bbda285fe
5
5
  SHA512:
6
- metadata.gz: eb6497a343dde2b4a3edfe470c8e5a44eb37ff99b75ed434138c280e8ac25bf36806d58fbb477772182596917f1c37c0e237bd55e88f646e149743477fba2f15
7
- data.tar.gz: f0b1f8b6f647f204ce8c4bfed7a8e77b49f3aada0faf6a0c31fc47675f5bfca67feb464692006bcb490977a577d1d5a3feab53886815f4c6472023e9ade6823b
6
+ metadata.gz: 1beb3e3c0531b3035051711670de269814122c20269086ffd31257b02dc4e6ff8c515ac812abc436360ebc9f1506e3ae8e15e859d6098913e08f2dfed67e1284
7
+ data.tar.gz: bff9fca90e302be4fe97b3cac4ac54bb8dc6c841ad6762939f9b0b2c6c7e66417bb108105d6d8372965ae9090d813c97cff8a4a4a6b513665beed63c9229f0e4
@@ -1,23 +1,20 @@
1
1
  module ZuoraConnect
2
2
  class StaticController < ApplicationController
3
- before_action :authenticate_connect_app_request, :except => [:metrics, :health, :initialize_app]
4
- before_action :clear_connect_app_session, :only => [:metrics, :health, :initialize_app]
5
- after_action :persist_connect_app_session, :except => [:metrics, :health, :initialize_app]
6
-
7
- skip_before_action :verify_authenticity_token, :only => [:initialize_app]
8
-
9
- def metrics
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
- @appinstance.new_session(:session => @appinstance.data_lookup(:session => session))
38
- render json: {
39
- message: "Success",
40
- status: 200
41
- }, status: 200
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
 
@@ -240,7 +245,9 @@ module ZuoraConnect
240
245
  rescue I18n::InvalidLocale => ex
241
246
  ZuoraConnect.logger.error(ex) if !IGNORED_LOCALS.include?(ex.locale.to_s.downcase)
242
247
  end
243
- Time.zone = self.timezone
248
+
249
+ self.set_timezone
250
+
244
251
  if self.task_data.present?
245
252
  tenants = self.task_data.fetch('tenant_ids', [])
246
253
  organizations = self.task_data.fetch('organizations', [])
@@ -255,7 +262,7 @@ module ZuoraConnect
255
262
  end
256
263
 
257
264
  params = {
258
- name: self.task_data.dig('name'),
265
+ name: self.task_data.dig('name'),
259
266
  zuora_entity_ids: (self.task_data.dig(LOGIN_TENANT_DESTINATION,'entities') || []).map{|e| e['id']}.uniq,
260
267
  zuora_tenant_ids: tenants.map(&:to_s).uniq,
261
268
  organizations: organizations
@@ -264,7 +271,7 @@ module ZuoraConnect
264
271
  client = self.send(LOGIN_TENANT_DESTINATION).client
265
272
  if defined?(client.rest_domain)
266
273
  ZuoraConnect::RequestIdMiddleware.zuora_rest_domain = client.rest_domain
267
- params.merge!({zuora_domain: client.rest_domain, environment: client.environment })
274
+ params.merge!({zuora_domain: client.rest_domain, environment: client.environment })
268
275
  end
269
276
  end
270
277
  params = params.reject{|k,v| !self.attributes.keys.member?(k.to_s) || self[k] == v}
@@ -272,12 +279,80 @@ module ZuoraConnect
272
279
  end
273
280
  end
274
281
 
275
- def refresh(session: {})
282
+ def set_timezone(timezone: self.timezone, type: :default)
283
+ if timezone.blank?
284
+ timezone = self.timezone
285
+ end
286
+
287
+ if type == :default
288
+ Time.zone = timezone
289
+ elsif type == :user
290
+ begin
291
+ sql = <<-eos
292
+ SELECT zuora_users.zuora_identity_response
293
+ FROM "#{self.id}".zuora_users
294
+ ORDER BY zuora_users.updated_at DESC
295
+ LIMIT 1;
296
+ eos
297
+ user = ActiveRecord::Base.connection.execute(sql).to_a.first
298
+
299
+ if user.present?
300
+ zuora_identity_response = JSON.parse(user.fetch('zuora_identity_response', '{}'))
301
+ self.user_timezone = zuora_identity_response.values.first&.dig('timeZone')
302
+ else
303
+ if (Redis.current.hget(TIMEZONE_LOG_RATE_LIMIT_KEY, self.id).to_i + TIMEZONE_LOG_PERIOD.to_i) <= Time.now.to_i
304
+ Rails.logger.error('Cannot find any user to set the timezone', app_instance_id: self.id)
305
+ Redis.current.hset(TIMEZONE_LOG_RATE_LIMIT_KEY, self.id, Time.now.to_i)
306
+ end
307
+ end
308
+ rescue => ex
309
+ Rails.logger.error('There is an error while getting timezone users', ex)
310
+ end
311
+
312
+ if self.user_timezone.present?
313
+ # connect instance which has a custom timezone
314
+ if !self.auto_deployed? && (
315
+ ActiveSupport::TimeZone[self.task_data.dig('user_settings', 'timezone') || '']&.utc_offset !=
316
+ ActiveSupport::TimeZone[self.user_timezone]&.utc_offset
317
+ )
318
+ if self.environment == 'Production' &&
319
+ (Redis.current.hget(TIMEZONE_LOG_RATE_LIMIT_KEY, self.id).to_i + TIMEZONE_LOG_PERIOD.to_i) <= Time.now.to_i
320
+ ZuoraConnect.logger.error(
321
+ "Instance and user timezones are different. User has '#{self.user_timezone}' and " \
322
+ "instance has '#{self.task_data.dig('user_settings', 'timezone')}'",
323
+ app_instance_id: self.id
324
+ )
325
+ Redis.current.hset(TIMEZONE_LOG_RATE_LIMIT_KEY, self.id, Time.now.to_i)
326
+ end
327
+ self.user_timezone = nil
328
+ Time.zone = timezone
329
+ else
330
+ begin
331
+ Time.zone = self.user_timezone
332
+ rescue ArgumentError
333
+ Rails.logger.error('Malformed user timezone', app_instance_id: self.id)
334
+ Time.zone = timezone
335
+ end
336
+ end
337
+ else
338
+ Time.zone = timezone
339
+ end
340
+ end
341
+ rescue => e
342
+ Rails.logger.error('Malformed timezone used', e, app_instance_id: self.id)
343
+ Time.zone = self.timezone
344
+ end
345
+
346
+ def auto_deployed?
347
+ self.id >= 25000000
348
+ end
349
+
350
+ def refresh(session: {})
276
351
  refresh_count ||= 0
277
352
  skip_connect ||= false
278
353
  begin
279
354
  #Check how app was deployed
280
- if self.id < 25000000 && !skip_connect
355
+ if self.id < 25000000 && !skip_connect
281
356
  self.check_oauth_state
282
357
  response = HTTParty.get(ZuoraConnect.configuration.url + "/api/#{self.api_version}/tools/tasks/#{self.id}.json",:body => {:access_token => self.access_token})
283
358
 
@@ -288,7 +363,7 @@ module ZuoraConnect
288
363
  raise ZuoraConnect::Exceptions::ConnectCommunicationError.new("JSON parse error", response.body, response.code)
289
364
  end
290
365
 
291
- self.build_task(task_data: parsed_json, session: session)
366
+ self.build_task(task_data: parsed_json, session: session)
292
367
  if self.kms_key.present? && self.kms_key.match(/^arn:aws:.*/)
293
368
  begin
294
369
  self.zuora_logins = self.strip_cache_data(object: parsed_json.dup, keys: ['applications', 'tokens', 'user_settings'])
@@ -298,7 +373,7 @@ module ZuoraConnect
298
373
  rescue => ex
299
374
  Rails.logger.error(AWS_AUTH_ERRORS_MSG, ex)
300
375
  end
301
- end
376
+ end
302
377
  else
303
378
  raise ZuoraConnect::Exceptions::ConnectCommunicationError.new("Error Communicating with Connect", response.body, response.code)
304
379
  end
@@ -338,6 +413,10 @@ module ZuoraConnect
338
413
  raise
339
414
  end
340
415
 
416
+ def aws_secrets
417
+ (Rails.application.secrets.aws || {}).transform_keys { |key| key.to_s }
418
+ end
419
+
341
420
  #### START KMS ENCRYPTION Methods ####
342
421
  def zuora_logins=(val)
343
422
  write_attribute(:zuora_logins, kms_encrypt(val.to_json))
@@ -350,7 +429,7 @@ module ZuoraConnect
350
429
 
351
430
  def kms_decrypt(value)
352
431
  kms_tries ||= 0
353
- kms_client = Aws::KMS::Client.new({region: Rails.application.secrets.aws['AWS_REGION'], credentials: self.aws_auth_client}.delete_if { |k, v| v.blank? })
432
+ kms_client = Aws::KMS::Client.new({region: aws_secrets['AWS_REGION'], credentials: self.aws_auth_client}.delete_if { |k, v| v.blank? })
354
433
  resp = kms_client.decrypt({ciphertext_blob: [value].pack("H*") })
355
434
  return resp.plaintext
356
435
  rescue *AWS_AUTH_ERRORS => ex
@@ -365,7 +444,7 @@ module ZuoraConnect
365
444
 
366
445
  def kms_encrypt(value)
367
446
  kms_tries ||= 0
368
- kms_client = Aws::KMS::Client.new({region: Rails.application.secrets.aws['AWS_REGION'], credentials: self.aws_auth_client}.delete_if {|k,v| v.blank? })
447
+ kms_client = Aws::KMS::Client.new({region: aws_secrets['AWS_REGION'], credentials: self.aws_auth_client}.delete_if {|k,v| v.blank? })
369
448
 
370
449
  resp = kms_client.encrypt({key_id: kms_key, plaintext: value})
371
450
  return resp.ciphertext_blob.unpack('H*').first
@@ -380,12 +459,12 @@ module ZuoraConnect
380
459
  end
381
460
 
382
461
  def kms_key
383
- return ENV['AWS_KMS_ARN'] || Rails.application.secrets.dig(:aws,'AWS_KMS_ARN')
462
+ return ENV['AWS_KMS_ARN'] || aws_secrets['AWS_KMS_ARN']
384
463
  end
385
464
 
386
465
  def aws_auth_client
387
466
  if Rails.env.to_s == 'development'
388
- return Aws::Credentials.new(Rails.application.secrets.aws['AWS_ACCESS_KEY_ID'], Rails.application.secrets.aws['AWS_SECRET_ACCESS_KEY'])
467
+ return Aws::Credentials.new(aws_secrets['AWS_ACCESS_KEY_ID'], aws_secrets['AWS_SECRET_ACCESS_KEY'])
389
468
  else
390
469
  return nil
391
470
  end
@@ -400,82 +479,6 @@ module ZuoraConnect
400
479
  end
401
480
  Thread.current[:appinstance] = self
402
481
  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
482
  #### END Task Methods ####
480
483
 
481
484
  #### START Task Methods ####
@@ -518,7 +521,7 @@ module ZuoraConnect
518
521
  end
519
522
  rescue ZuoraConnect::Exceptions::MissMatch => ex
520
523
  raise
521
- rescue ZuoraConnect::Exceptions::InvalidCredentialSet => ex
524
+ rescue ZuoraConnect::Exceptions::InvalidCredentialSet => ex
522
525
  raise
523
526
  rescue => ex
524
527
  ZuoraConnect.logger.error("Build Task Error", ex)
@@ -574,10 +577,10 @@ module ZuoraConnect
574
577
  self.refresh if !defined?(self.target_login)
575
578
 
576
579
  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
-
580
+
578
581
  if response.success?
579
582
  parsed_json = JSON.parse(response.body)
580
-
583
+
581
584
  #Set Org
582
585
  if self.id >= 25000000 && parsed_json['organization'].present?
583
586
  login_cache = self.zuora_logins
@@ -599,7 +602,7 @@ module ZuoraConnect
599
602
  end
600
603
  end
601
604
  self.save(:validate => false)
602
-
605
+
603
606
  return parsed_json
604
607
  end
605
608
  rescue *(ZuoraAPI::Login::CONNECTION_EXCEPTIONS + ZuoraAPI::Login::CONNECTION_READ_EXCEPTIONS) => ex
@@ -653,7 +656,7 @@ module ZuoraConnect
653
656
  end
654
657
 
655
658
  def refresh_oauth
656
- refresh_oauth_count ||= 0
659
+ refresh_oauth_count ||= 0
657
660
  response = HTTParty.post("#{ZuoraConnect.configuration.url}/oauth/token", body: {
658
661
  :grant_type => "refresh_token",
659
662
  :redirect_uri => ZuoraConnect.configuration.oauth_client_redirect_uri,
@@ -955,13 +958,81 @@ module ZuoraConnect
955
958
  # object_id: The id or id's of the object/objects to be returned.
956
959
  # child_objects: Whether to include child objects of the object in question.
957
960
  # 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)
961
+ def catalog_lookup(entity_id: nil, object: :product, object_id: nil, child_objects: false, cache: false, source: 'DB')
959
962
  entity_reference = entity_id.blank? ? 'Default' : entity_id
960
963
 
961
964
  if object_id.present? && ![Array, String].include?(object_id.class)
962
965
  raise "Object Id can only be a string or an array of strings"
963
966
  end
964
967
 
968
+ if source == 'API'
969
+ catalog_container = {}
970
+
971
+ if (Redis.current.hget(CATALOG_LOOKUP_CACHE_TIME_KEY, self.id).to_i + CATALOG_LOOKUP_TTL.to_i) > Time.now.to_i
972
+ begin
973
+ catalog_container = JSON.parse(Redis.current.hget(CATALOG_LOOKUP_CACHE_RESULT_KEY, self.id))
974
+ rescue JSON::ParserError => ex
975
+ Rails.logger.warn('Failed to parse catalog cache', ex)
976
+ end
977
+ else
978
+ zuora_login = self.login_lookup(type: 'Zuora').first
979
+ login = zuora_login.client(entity_reference)
980
+
981
+ response = {
982
+ 'nextPage' => login.rest_endpoint("catalog/products?pageSize=#{CATALOG_LOOKUP_PAGE_SIZE}")
983
+ }
984
+
985
+ while response['nextPage'].present?
986
+ url = login.rest_endpoint(response['nextPage'].split('/v1/').last)
987
+ output_json, response = login.rest_call(debug: false, url: url, timeout_retry: true)
988
+
989
+ case object
990
+ when :product
991
+ output_json.fetch('products', []).each do |product|
992
+ rate_plans = {}
993
+ product['productRatePlans'].each do |rate_plan|
994
+ charges = {}
995
+ rate_plan['productRatePlanCharges'].each do |charge|
996
+ charges[charge['id']] = charge.merge(
997
+ {
998
+ 'productId' => product['id'],
999
+ 'productName' => product['name'],
1000
+ 'productRatePlanId' => rate_plan['id'],
1001
+ 'productRatePlanName' => rate_plan['name'],
1002
+ }
1003
+ )
1004
+ end
1005
+
1006
+ rate_plan['productRatePlanCharges'] = charges
1007
+ rate_plans[rate_plan['id']] = rate_plan.merge(
1008
+ {
1009
+ 'productId' => product['id'],
1010
+ 'productName' => product['name']
1011
+ }
1012
+ )
1013
+ end
1014
+
1015
+ product['productRatePlans'] = rate_plans
1016
+ catalog_container[product['id']] = product
1017
+ end
1018
+ else
1019
+ raise "Available objects include [:product]"
1020
+ end
1021
+ end
1022
+
1023
+ Redis.current.hset(CATALOG_LOOKUP_CACHE_RESULT_KEY, self.id, catalog_container.to_json)
1024
+ Redis.current.hset(CATALOG_LOOKUP_CACHE_TIME_KEY, self.id, Time.now.to_i)
1025
+ end
1026
+
1027
+ if object_id.nil?
1028
+ catalog_container.transform_values! { |v| v.except('productRatePlans') }
1029
+ elsif object_id.is_a?(String)
1030
+ catalog_container = catalog_container[object_id]
1031
+ end
1032
+
1033
+ return catalog_container
1034
+ end
1035
+
965
1036
  if defined?(Redis.current) && object_id.present? && object_id.class == String && object_id.present?
966
1037
  stub_catalog = cache ? decrypt_data(data: Redis.current.get("Catalog:#{self.id}:#{object_id}:Children:#{child_objects}")) : nil
967
1038
  object_hierarchy = decrypt_data(data: Redis.current.get("Catalog:#{self.id}:#{object_id}:Hierarchy"))
@@ -1221,7 +1292,7 @@ module ZuoraConnect
1221
1292
 
1222
1293
  def self.without_sticking
1223
1294
  if self.connection.respond_to?(:without_sticking)
1224
- self.connection.without_sticking do
1295
+ self.connection.without_sticking do
1225
1296
  yield
1226
1297
  end
1227
1298
  else