zuora_connect 2.1.1 → 3.0.0.pre.a
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 +168 -97
- 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 +20 -6
- 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 +52 -38
- 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 +212 -76
- data/lib/zuora_connect/engine.rb +2 -1
- data/lib/zuora_connect/railtie.rb +9 -53
- 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: e63c10c8405375ad7cb2c28073c6181ed055266fb8d61e3ac5725e8f5b8ca8d5
|
|
4
|
+
data.tar.gz: c5124fe3590fd14c0acdad0cfe6e567997195eaa728245f620bfff5bbda285fe
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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 => [:
|
|
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
|
|
|
@@ -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
|
-
|
|
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
|
|
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:
|
|
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:
|
|
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'] ||
|
|
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(
|
|
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
|