zuora_api 1.7.66c → 1.7.66i
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/.gitlab-ci.yml +2 -1
- data/Gemfile +1 -1
- data/lib/zuora_api/exceptions.rb +13 -0
- data/lib/zuora_api/login.rb +269 -189
- data/lib/zuora_api/logins/basic.rb +10 -101
- data/lib/zuora_api/logins/oauth.rb +17 -81
- data/lib/zuora_api/version.rb +1 -1
- data/zuora_api.gemspec +3 -2
- metadata +22 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d9abc05b9cc822f673afd3df5ab42267a5b0507c5af115d784cbe8b148ee7eda
|
|
4
|
+
data.tar.gz: fdf4bac3b2f9f6999406ebbe9e96ca80fb07297c5d915ff2fac280225adb486f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ac941b6f8d7c790ad3485690a15f756fba277adc39e594153e96cfb21ce3997e181c2dc4761621a7837f7be2072fc3da3ce0c613ef3b6ba4aaa47aaa3eb14fe4
|
|
7
|
+
data.tar.gz: 496c6f87369ef131c9a4b8e9f3fdb3e1896c3b73a9784174788234dbf2d55c9ed4a46908bac9ea924a7728ebdf64818c635bda93951b0c9781cfd5f81754b960
|
data/.gitlab-ci.yml
CHANGED
data/Gemfile
CHANGED
data/lib/zuora_api/exceptions.rb
CHANGED
|
@@ -40,6 +40,19 @@ module ZuoraAPI
|
|
|
40
40
|
def to_s
|
|
41
41
|
@message || @default_message
|
|
42
42
|
end
|
|
43
|
+
|
|
44
|
+
def parse_message(message)
|
|
45
|
+
case message
|
|
46
|
+
when /^Invalid Oauth Client Id$/, /^Unable to generate token.$/
|
|
47
|
+
@message = "Invalid login, please check client ID and Client Secret or URL endpoint"
|
|
48
|
+
when /^Forbidden$/
|
|
49
|
+
@message = "The user associated to OAuth credential set has been deactivated."
|
|
50
|
+
when /^Invalid login. User name and password do not match.$/
|
|
51
|
+
@message = "Invalid login, please check username and password or URL endpoint"
|
|
52
|
+
else
|
|
53
|
+
@message = message
|
|
54
|
+
end
|
|
55
|
+
end
|
|
43
56
|
end
|
|
44
57
|
|
|
45
58
|
class BadEntityError < Error
|
data/lib/zuora_api/login.rb
CHANGED
|
@@ -374,8 +374,8 @@ module ZuoraAPI
|
|
|
374
374
|
return domain ? endpoint.concat(prefix).concat(url) : prefix.concat(url)
|
|
375
375
|
end
|
|
376
376
|
|
|
377
|
-
def rest_domain
|
|
378
|
-
return URI(
|
|
377
|
+
def rest_domain(endpoint: self.rest_endpoint)
|
|
378
|
+
return URI(endpoint).host
|
|
379
379
|
end
|
|
380
380
|
|
|
381
381
|
def fileURL(url="")
|
|
@@ -387,10 +387,41 @@ module ZuoraAPI
|
|
|
387
387
|
end
|
|
388
388
|
|
|
389
389
|
def new_session(auth_type: :basic, debug: false, zuora_track_id: nil)
|
|
390
|
+
tries ||= 2
|
|
391
|
+
yield
|
|
392
|
+
|
|
393
|
+
rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
|
|
394
|
+
self.status = 'Inactive/Invalid'
|
|
395
|
+
self.current_error = ex.message
|
|
396
|
+
raise
|
|
397
|
+
rescue ZuoraAPI::Exceptions::ZuoraAPIError => ex
|
|
398
|
+
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(ex.message, ex.response)
|
|
399
|
+
|
|
400
|
+
rescue ZuoraAPI::Exceptions::ZuoraAPIInternalServerError => ex
|
|
401
|
+
raise ex if tries.zero?
|
|
402
|
+
|
|
403
|
+
tries -= 1
|
|
404
|
+
sleep(self.timeout_sleep)
|
|
405
|
+
retry
|
|
406
|
+
|
|
407
|
+
rescue *(CONNECTION_EXCEPTIONS + CONNECTION_READ_EXCEPTIONS) => ex
|
|
408
|
+
self.log(location: "BasicLogin", exception: ex, message: "Timed out", level: :error)
|
|
409
|
+
|
|
410
|
+
self.current_error = "Request timed out. Try again"
|
|
411
|
+
self.status = 'Timeout'
|
|
412
|
+
|
|
413
|
+
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error)
|
|
414
|
+
|
|
415
|
+
rescue EOFError
|
|
416
|
+
if self.url.match?(/.*services\d{1,}.zuora.com*/)
|
|
417
|
+
self.current_error = "Services tenant '#{self.url.scan(/.*\/\/(services\d{1,}).zuora.com*/).last.first}' is no longer available."
|
|
418
|
+
self.status = 'Not Available'
|
|
419
|
+
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error)
|
|
420
|
+
end
|
|
421
|
+
|
|
390
422
|
end
|
|
391
423
|
|
|
392
424
|
def get_session(prefix: false, auth_type: :basic, zuora_track_id: nil)
|
|
393
|
-
Rails.logger.debug("Get session for #{auth_type} - #{self.class.to_s}") if Rails.env.to_s == 'development'
|
|
394
425
|
case auth_type
|
|
395
426
|
when :basic
|
|
396
427
|
if self.current_session.blank?
|
|
@@ -399,14 +430,13 @@ module ZuoraAPI
|
|
|
399
430
|
if self.bearer_token.blank? || self.oauth_expired?
|
|
400
431
|
self.new_session(auth_type: :bearer, zuora_track_id: zuora_track_id)
|
|
401
432
|
end
|
|
402
|
-
self.get_z_session(zuora_track_id: zuora_track_id)
|
|
433
|
+
self.get_z_session(zuora_track_id: zuora_track_id)
|
|
403
434
|
when 'ZuoraAPI::Basic'
|
|
404
435
|
self.new_session(auth_type: :basic, zuora_track_id: zuora_track_id)
|
|
405
436
|
else
|
|
406
437
|
self.new_session(auth_type: :basic, zuora_track_id: zuora_track_id)
|
|
407
438
|
end
|
|
408
439
|
end
|
|
409
|
-
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error) if self.status != 'Active'
|
|
410
440
|
return prefix ? "ZSession #{self.current_session}" : self.current_session.to_s
|
|
411
441
|
when :bearer
|
|
412
442
|
case self.class.to_s
|
|
@@ -419,8 +449,6 @@ module ZuoraAPI
|
|
|
419
449
|
else
|
|
420
450
|
raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Unknown Login, does not support Authentication of Type: #{auth_type}")
|
|
421
451
|
end
|
|
422
|
-
|
|
423
|
-
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error) if self.status != 'Active'
|
|
424
452
|
return prefix ? "Bearer #{self.bearer_token}" : self.bearer_token.to_s
|
|
425
453
|
end
|
|
426
454
|
end
|
|
@@ -428,16 +456,18 @@ module ZuoraAPI
|
|
|
428
456
|
def soap_call(
|
|
429
457
|
ns1: 'ns1',
|
|
430
458
|
ns2: 'ns2',
|
|
431
|
-
batch_size: nil,
|
|
459
|
+
batch_size: nil,
|
|
460
|
+
headers: {},
|
|
432
461
|
single_transaction: false,
|
|
433
462
|
debug: false,
|
|
434
463
|
zuora_track_id: nil,
|
|
435
464
|
errors: [ZuoraAPI::Exceptions::ZuoraAPISessionError].concat(ZUORA_API_ERRORS),
|
|
436
465
|
z_session: true,
|
|
437
466
|
timeout_retry: false,
|
|
438
|
-
timeout:
|
|
467
|
+
timeout: 130,
|
|
439
468
|
timeout_sleep_interval: self.timeout_sleep,
|
|
440
469
|
output_exception_messages: true,
|
|
470
|
+
skip_session: false,
|
|
441
471
|
**keyword_args)
|
|
442
472
|
tries ||= 2
|
|
443
473
|
xml = Nokogiri::XML::Builder.new do |xml|
|
|
@@ -447,8 +477,10 @@ module ZuoraAPI
|
|
|
447
477
|
'xmlns:api' => "http://api.zuora.com/",
|
|
448
478
|
"xmlns:#{ns1}" => "http://api.zuora.com/") do
|
|
449
479
|
xml['SOAP-ENV'].Header do
|
|
450
|
-
|
|
451
|
-
xml["#{ns1}"].
|
|
480
|
+
if !skip_session
|
|
481
|
+
xml["#{ns1}"].SessionHeader do
|
|
482
|
+
xml["#{ns1}"].session self.get_session(prefix: false, auth_type: :basic, zuora_track_id: zuora_track_id)
|
|
483
|
+
end
|
|
452
484
|
end
|
|
453
485
|
if single_transaction
|
|
454
486
|
xml["#{ns1}"].CallOptions do
|
|
@@ -466,12 +498,11 @@ module ZuoraAPI
|
|
|
466
498
|
end
|
|
467
499
|
end
|
|
468
500
|
end
|
|
469
|
-
|
|
470
501
|
input_xml = Nokogiri::XML(xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip)
|
|
471
502
|
input_xml.xpath('//ns1:session', 'ns1' =>'http://api.zuora.com/').children.remove
|
|
472
503
|
Rails.logger.debug("Request SOAP XML: #{input_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}") if debug
|
|
473
504
|
|
|
474
|
-
headers
|
|
505
|
+
headers.merge!({ 'Content-Type' => "text/xml; charset=utf-8", 'Accept' => 'text/xml'})
|
|
475
506
|
headers['Zuora-Track-Id'] = zuora_track_id if zuora_track_id.present?
|
|
476
507
|
|
|
477
508
|
request = HTTParty::Request.new(
|
|
@@ -488,7 +519,11 @@ module ZuoraAPI
|
|
|
488
519
|
Rails.logger.debug("Response SOAP XML: #{output_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}") if debug
|
|
489
520
|
|
|
490
521
|
raise_errors(type: :SOAP, body: output_xml, response: response)
|
|
522
|
+
|
|
523
|
+
return output_xml, input_xml, response
|
|
524
|
+
|
|
491
525
|
rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
|
|
526
|
+
raise if skip_session
|
|
492
527
|
if !tries.zero? && z_session
|
|
493
528
|
tries -= 1
|
|
494
529
|
Rails.logger.debug("SOAP Call - Session Invalid")
|
|
@@ -513,24 +548,20 @@ module ZuoraAPI
|
|
|
513
548
|
return output_xml, input_xml, response
|
|
514
549
|
|
|
515
550
|
rescue *CONNECTION_EXCEPTIONS => ex
|
|
516
|
-
if tries.zero?
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
Rails.logger.error("SOAP Call - #{ex.class} Timed out will retry after #{timeout_sleep_interval} seconds")
|
|
522
|
-
end
|
|
523
|
-
end
|
|
524
|
-
raise ex
|
|
551
|
+
if !tries.zero?
|
|
552
|
+
tries -= 1
|
|
553
|
+
self.log(location: "SOAP Call", exception: ex, message: "Timed out will retry after #{timeout_sleep_interval} seconds", level: :debug)
|
|
554
|
+
sleep(timeout_sleep_interval)
|
|
555
|
+
retry
|
|
525
556
|
end
|
|
526
557
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
558
|
+
self.log(location: "SOAP Call", exception: ex, message: "Timed out", level: :error) if output_exception_messages
|
|
559
|
+
raise ex
|
|
560
|
+
|
|
530
561
|
rescue *CONNECTION_READ_EXCEPTIONS => ex
|
|
531
562
|
if !tries.zero?
|
|
532
563
|
tries -= 1
|
|
533
|
-
|
|
564
|
+
self.log(location: "SOAP Call", exception: ex, message: "Timed out will retry after #{timeout_sleep_interval} seconds", level: :debug)
|
|
534
565
|
if ex.is_a?(Errno::ECONNRESET) && ex.message.include?('SSL_connect')
|
|
535
566
|
retry
|
|
536
567
|
elsif timeout_retry
|
|
@@ -539,19 +570,79 @@ module ZuoraAPI
|
|
|
539
570
|
end
|
|
540
571
|
end
|
|
541
572
|
|
|
542
|
-
if output_exception_messages
|
|
543
|
-
|
|
544
|
-
Rails.logger.error("SOAP Call - Timed out will retry after #{timeout_sleep_interval} seconds", ex)
|
|
545
|
-
else
|
|
546
|
-
Rails.logger.error("SOAP Call - #{ex.class} Timed out will retry after #{timeout_sleep_interval} seconds")
|
|
547
|
-
end
|
|
548
|
-
end
|
|
549
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIReadTimeout.new("Received read timeout from #{url}", nil, request) if ex.instance_of?(Net::ReadTimeout)
|
|
573
|
+
self.log(location: "SOAP Call", exception: ex, message: "Timed out", level: :error) if output_exception_messages
|
|
574
|
+
ex = ZuoraAPI::Exceptions::ZuoraAPIReadTimeout.new("Received read timeout from 'https://#{rest_domain(endpoint: url)}'", nil, request) if ex.instance_of?(Net::ReadTimeout)
|
|
550
575
|
raise ex
|
|
576
|
+
|
|
551
577
|
rescue => ex
|
|
552
578
|
raise ex
|
|
553
|
-
|
|
554
|
-
|
|
579
|
+
ensure
|
|
580
|
+
self.error_logger(ex) if defined?(ex) && Rails.logger.class.to_s == "Ougai::Logger"
|
|
581
|
+
end
|
|
582
|
+
|
|
583
|
+
def error_logger(ex)
|
|
584
|
+
exception_args = Rails.logger.with_fields.merge(self.exception_args(ex))
|
|
585
|
+
case ex
|
|
586
|
+
when ZuoraAPI::Exceptions::ZuoraAPIUnkownError, ZuoraAPI::Exceptions::ZuoraDataIntegrity
|
|
587
|
+
Rails.logger.error('Zuora Unknown/Integrity Error', ex, exception_args)
|
|
588
|
+
when ZuoraAPI::Exceptions::ZuoraAPIRequestLimit
|
|
589
|
+
Rails.logger.info('Zuora APILimit Reached', exception_args)
|
|
590
|
+
when *(ZuoraAPI::Login::ZUORA_API_ERRORS-ZuoraAPI::Login::ZUORA_SERVER_ERRORS)
|
|
591
|
+
#Rails.logger.debug('Zuora API Error', ex, self.exception_args(ex))
|
|
592
|
+
when *ZuoraAPI::Login::ZUORA_SERVER_ERRORS
|
|
593
|
+
Rails.logger.error('Zuora Server Error', ex, exception_args)
|
|
594
|
+
end
|
|
595
|
+
end
|
|
596
|
+
|
|
597
|
+
def log(location: "Rest Call", exception: nil, message: "Timed out will retry after #{self.timeout_sleep} seconds", level: :info )
|
|
598
|
+
level = :debug if ![:debug, :info, :warn, :error, :fatal].include?(level)
|
|
599
|
+
if Rails.logger.class.to_s == "Ougai::Logger"
|
|
600
|
+
Rails.logger.send(level.to_sym, "#{location} - #{message}", exception)
|
|
601
|
+
else
|
|
602
|
+
Rails.logger.send(level.to_sym, "#{location} - #{exception.class} #{message}")
|
|
603
|
+
end
|
|
604
|
+
end
|
|
605
|
+
|
|
606
|
+
def exception_args(ex)
|
|
607
|
+
args = {}
|
|
608
|
+
if ex.class == ZuoraAPI::Exceptions::ZuoraAPIRequestLimit
|
|
609
|
+
args.merge!({
|
|
610
|
+
zuora_trace_id: ex.response.headers["zuora-request-id"],
|
|
611
|
+
zuora_track_id: ex.response.request.options[:headers]["Zuora-Track-Id"]
|
|
612
|
+
})
|
|
613
|
+
elsif defined?(ex.response) && ex.response.present?
|
|
614
|
+
args.merge!({
|
|
615
|
+
request: {
|
|
616
|
+
path: ex.response.request.path.to_s,
|
|
617
|
+
method: ex.response.request.http_method.to_s.split("Net::HTTP::").last.upcase,
|
|
618
|
+
params: ex.response.request.raw_body.to_s,
|
|
619
|
+
headers: ex.response.request.options[:headers].map{|k,v| [k.to_s, k.to_s.downcase.strip == "authorization" ? "VALUE FILTERED" : v]}.to_h.to_s,
|
|
620
|
+
},
|
|
621
|
+
response: {
|
|
622
|
+
status: ex.response.code,
|
|
623
|
+
params: ex.response.body.to_s,
|
|
624
|
+
headers: ex.response.headers.to_s,
|
|
625
|
+
},
|
|
626
|
+
zuora_trace_id: ex.response.headers["zuora-request-id"],
|
|
627
|
+
zuora_track_id: ex.response.request.options[:headers]["Zuora-Track-Id"],
|
|
628
|
+
})
|
|
629
|
+
elsif defined?(ex.request) && ex.request.present?
|
|
630
|
+
args.merge!({
|
|
631
|
+
request: {
|
|
632
|
+
path: ex.request.path.to_s,
|
|
633
|
+
method: ex.request.http_method.to_s.split("Net::HTTP::").last.upcase,
|
|
634
|
+
params: ex.request.options[:body],
|
|
635
|
+
headers: ex.request.options[:headers].map{|k,v| [k.to_s, k.to_s.downcase.strip == "authorization" ? "VALUE FILTERED" : v]}.to_h.to_s
|
|
636
|
+
}
|
|
637
|
+
})
|
|
638
|
+
args.merge!({
|
|
639
|
+
zuora_track_id: ex.request.options[:headers]["Zuora-Track-Id"]
|
|
640
|
+
}) if ex.request.options[:headers]["Zuora-Track-Id"].present?
|
|
641
|
+
end
|
|
642
|
+
rescue => ex
|
|
643
|
+
Rails.logger.error("Failed to create exception arguments", ex, args)
|
|
644
|
+
ensure
|
|
645
|
+
return args
|
|
555
646
|
end
|
|
556
647
|
|
|
557
648
|
def raise_errors(type: :SOAP, body: nil, response: nil)
|
|
@@ -568,13 +659,13 @@ module ZuoraAPI
|
|
|
568
659
|
end
|
|
569
660
|
|
|
570
661
|
if [502,503].include?(response.code)
|
|
571
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIConnectionTimeout.new("Received #{response.code} from
|
|
662
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIConnectionTimeout.new("Received #{response.code} from 'https://#{rest_domain(endpoint: request_uri)}'", response)
|
|
572
663
|
end
|
|
573
664
|
|
|
574
665
|
# Check failure response code
|
|
575
666
|
case response.code
|
|
576
667
|
when 504
|
|
577
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIReadTimeout.new("Received 504 from
|
|
668
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIReadTimeout.new("Received 504 from 'https://#{rest_domain(endpoint: request_uri)}'", response)
|
|
578
669
|
when 429
|
|
579
670
|
raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new("The total number of concurrent requests has exceeded the limit allowed by the system. Please resubmit your request later.", response)
|
|
580
671
|
when 401
|
|
@@ -595,6 +686,10 @@ module ZuoraAPI
|
|
|
595
686
|
when :SOAP
|
|
596
687
|
error, success, message = get_soap_error_and_message(body)
|
|
597
688
|
|
|
689
|
+
if body.xpath('//fns:LoginFault', 'fns' =>'http://fault.api.zuora.com/').present?
|
|
690
|
+
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(message, response)
|
|
691
|
+
end
|
|
692
|
+
|
|
598
693
|
if body.xpath('//ns1:queryResponse', 'ns1' => 'http://api.zuora.com/').present? &&
|
|
599
694
|
body.xpath(
|
|
600
695
|
'//ns1:records[@xsi:type="ns2:Export"]',
|
|
@@ -699,7 +794,11 @@ module ZuoraAPI
|
|
|
699
794
|
end
|
|
700
795
|
|
|
701
796
|
if body['error'] == 'Unauthorized' && body['status'] == 401
|
|
702
|
-
|
|
797
|
+
if body['message'].present?
|
|
798
|
+
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(body['message'], response)
|
|
799
|
+
else
|
|
800
|
+
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{messages_array.join(', ')}", response)
|
|
801
|
+
end
|
|
703
802
|
end
|
|
704
803
|
#Authentication failed
|
|
705
804
|
if (codes_array.map{|code| code.to_s.slice(6,7).to_i}.include?(11) || response.code == 401) && !codes_array.include?(422)
|
|
@@ -826,6 +925,8 @@ module ZuoraAPI
|
|
|
826
925
|
raise ZuoraAPI::Exceptions::ZuoraAPIConnectionTimeout.new(error_message, response)
|
|
827
926
|
when /Client sent a bad request./, /Bad Request/, /403 Forbidden/
|
|
828
927
|
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new(error_message, response)
|
|
928
|
+
when /414 Request-URI Too Large/
|
|
929
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Request URL is too long", response)
|
|
829
930
|
else
|
|
830
931
|
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new(error_message, response)
|
|
831
932
|
end
|
|
@@ -955,7 +1056,7 @@ module ZuoraAPI
|
|
|
955
1056
|
base = self.url.include?(".com") ? self.url.split(".com")[0].concat(".com") : self.url.split(".eu")[0].concat(".eu")
|
|
956
1057
|
url = object ? "#{base}/apps/api/describe/#{object}" : "#{base}/apps/api/describe/"
|
|
957
1058
|
headers = self.entity_id.present? ? {"Zuora-Entity-Ids" => self.entity_id, 'Content-Type' => "text/xml; charset=utf-8"} : {'Content-Type' => "text/xml; charset=utf-8"}
|
|
958
|
-
response = HTTParty.get(url, headers: {"Authorization" => self.get_session(prefix: true, auth_type: :basic)}.merge(headers), :timeout =>
|
|
1059
|
+
response = HTTParty.get(url, headers: {"Authorization" => self.get_session(prefix: true, auth_type: :basic)}.merge(headers), :timeout => 130)
|
|
959
1060
|
|
|
960
1061
|
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error.present? ? self.current_error : 'Describe call 401', response) if response.code == 401
|
|
961
1062
|
|
|
@@ -988,35 +1089,31 @@ module ZuoraAPI
|
|
|
988
1089
|
end
|
|
989
1090
|
des_hash[:related_objects] = output_xml.xpath(".//related-objects").xpath(".//object").map{ |x| [x.xpath(".//name").text.to_sym, [ [:url, x.attributes["href"].value], [:label, x.xpath(".//name").text ] ].to_h] }.to_h
|
|
990
1091
|
end
|
|
1092
|
+
|
|
1093
|
+
return des_hash
|
|
991
1094
|
rescue *(CONNECTION_EXCEPTIONS + CONNECTION_READ_EXCEPTIONS) => ex
|
|
992
|
-
if tries.zero?
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
Rails.logger.error("Describe - #{ex.class} Timed out will retry after #{self.timeout_sleep} seconds")
|
|
998
|
-
end
|
|
999
|
-
end
|
|
1000
|
-
raise ex
|
|
1095
|
+
if !tries.zero?
|
|
1096
|
+
tries -= 1
|
|
1097
|
+
self.log(location: "Describe", exception: ex, message: "Timed out will retry after #{self.timeout_sleep} seconds", level: :debug)
|
|
1098
|
+
sleep(self.timeout_sleep)
|
|
1099
|
+
retry
|
|
1001
1100
|
end
|
|
1002
1101
|
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1102
|
+
self.log(location: "Describe", exception: ex, message: "Timed out", level: :error) if log_errors
|
|
1103
|
+
raise ex
|
|
1104
|
+
|
|
1006
1105
|
rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
|
|
1007
1106
|
if !tries.zero? && self.status == 'Active'
|
|
1008
1107
|
tries -= 1
|
|
1009
1108
|
Rails.logger.debug("Describe session expired. Starting new session.")
|
|
1010
1109
|
self.new_session
|
|
1011
1110
|
retry
|
|
1012
|
-
else
|
|
1013
|
-
Rails.logger.error("Describe session expired. Starting new session.") if log_errors
|
|
1014
|
-
raise ex
|
|
1015
1111
|
end
|
|
1112
|
+
|
|
1113
|
+
Rails.logger.error("Describe session expired. Starting new session.") if log_errors
|
|
1114
|
+
raise ex
|
|
1016
1115
|
rescue => ex
|
|
1017
1116
|
raise ex
|
|
1018
|
-
else
|
|
1019
|
-
return des_hash
|
|
1020
1117
|
end
|
|
1021
1118
|
|
|
1022
1119
|
def rest_call(
|
|
@@ -1029,11 +1126,12 @@ module ZuoraAPI
|
|
|
1029
1126
|
z_session: true,
|
|
1030
1127
|
session_type: :basic,
|
|
1031
1128
|
timeout_retry: false,
|
|
1032
|
-
timeout:
|
|
1129
|
+
timeout: 130,
|
|
1033
1130
|
timeout_sleep_interval: self.timeout_sleep,
|
|
1034
1131
|
multipart: false,
|
|
1035
1132
|
stream_body: false,
|
|
1036
1133
|
output_exception_messages: true,
|
|
1134
|
+
zuora_track_id: nil,
|
|
1037
1135
|
**keyword_args,
|
|
1038
1136
|
&block
|
|
1039
1137
|
)
|
|
@@ -1043,12 +1141,13 @@ module ZuoraAPI
|
|
|
1043
1141
|
|
|
1044
1142
|
authentication_headers = {}
|
|
1045
1143
|
if z_session
|
|
1046
|
-
authentication_headers = {"Authorization" => self.get_session(prefix: true, auth_type: session_type) }
|
|
1144
|
+
authentication_headers = {"Authorization" => self.get_session(prefix: true, auth_type: session_type, zuora_track_id: zuora_track_id) }
|
|
1047
1145
|
if self.entity_id.present?
|
|
1048
1146
|
authentication_headers["Zuora-Entity-Ids"] = self.entity_id if headers.dig("Zuora-Entity-Ids").nil?
|
|
1049
1147
|
authentication_headers.delete_if { |key, value| ["entityId", "entityName"].include?(key.to_s) }
|
|
1050
1148
|
end
|
|
1051
1149
|
end
|
|
1150
|
+
headers['Zuora-Track-Id'] = zuora_track_id if zuora_track_id.present?
|
|
1052
1151
|
|
|
1053
1152
|
modified_headers = {'Content-Type' => "application/json; charset=utf-8"}.merge(authentication_headers).merge(headers)
|
|
1054
1153
|
|
|
@@ -1074,10 +1173,12 @@ module ZuoraAPI
|
|
|
1074
1173
|
Rails.logger.debug("Response JSON: #{output_json}") if debug && output_json.present?
|
|
1075
1174
|
|
|
1076
1175
|
raise_errors(type: :JSON, body: output_json, response: response)
|
|
1077
|
-
rescue
|
|
1176
|
+
rescue => ex
|
|
1078
1177
|
reset_files(body) if multipart
|
|
1079
1178
|
raise
|
|
1080
1179
|
end
|
|
1180
|
+
|
|
1181
|
+
return [output_json, response]
|
|
1081
1182
|
rescue ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError => ex
|
|
1082
1183
|
if self.class.to_s == 'ZuoraAPI::Oauth' && ex.message.include?("Authentication type is not supported by this Login")
|
|
1083
1184
|
session_type = :bearer
|
|
@@ -1112,23 +1213,21 @@ module ZuoraAPI
|
|
|
1112
1213
|
rescue ZuoraAPI::Exceptions::BadEntityError => ex
|
|
1113
1214
|
raise ex
|
|
1114
1215
|
rescue *CONNECTION_EXCEPTIONS => ex
|
|
1115
|
-
if tries.zero?
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
Rails.logger.error("Rest Call - #{ex.class} Timed out will retry after #{timeout_sleep_interval} seconds")
|
|
1121
|
-
end
|
|
1122
|
-
end
|
|
1123
|
-
raise ex
|
|
1216
|
+
if !tries.zero?
|
|
1217
|
+
tries -= 1
|
|
1218
|
+
self.log(location: "Rest Call", exception: ex, message: "Timed out will retry after #{timeout_sleep_interval} seconds", level: :debug)
|
|
1219
|
+
sleep(timeout_sleep_interval)
|
|
1220
|
+
retry
|
|
1124
1221
|
end
|
|
1125
1222
|
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1223
|
+
self.log(location: "Rest Call", exception: ex, message: "Timed out", level: :error) if output_exception_messages
|
|
1224
|
+
raise ex
|
|
1225
|
+
|
|
1129
1226
|
rescue *CONNECTION_READ_EXCEPTIONS => ex
|
|
1227
|
+
|
|
1130
1228
|
if !tries.zero?
|
|
1131
1229
|
tries -= 1
|
|
1230
|
+
self.log(location: "Rest Call", exception: ex, message: "Timed out will retry after #{timeout_sleep_interval} seconds", level: :debug)
|
|
1132
1231
|
if ex.is_a?(Errno::ECONNRESET) && ex.message.include?('SSL_connect')
|
|
1133
1232
|
retry
|
|
1134
1233
|
elsif timeout_retry
|
|
@@ -1136,20 +1235,15 @@ module ZuoraAPI
|
|
|
1136
1235
|
retry
|
|
1137
1236
|
end
|
|
1138
1237
|
end
|
|
1139
|
-
|
|
1140
|
-
if output_exception_messages
|
|
1141
|
-
|
|
1142
|
-
Rails.logger.error("Rest Call - Timed out will retry after #{timeout_sleep_interval} seconds", ex)
|
|
1143
|
-
else
|
|
1144
|
-
Rails.logger.error("Rest Call - #{ex.class} Timed out will retry after #{timeout_sleep_interval} seconds")
|
|
1145
|
-
end
|
|
1146
|
-
end
|
|
1147
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIReadTimeout.new("Received read timeout from #{url}", nil, request) if ex.instance_of?(Net::ReadTimeout)
|
|
1238
|
+
|
|
1239
|
+
self.log(location: "Rest Call", exception: ex, message: "Timed out", level: :error) if output_exception_messages
|
|
1240
|
+
ex = ZuoraAPI::Exceptions::ZuoraAPIReadTimeout.new("Received read timeout from 'https://#{rest_domain(endpoint: url)}'", nil, request) if ex.instance_of?(Net::ReadTimeout)
|
|
1148
1241
|
raise ex
|
|
1242
|
+
|
|
1149
1243
|
rescue => ex
|
|
1150
1244
|
raise ex
|
|
1151
|
-
|
|
1152
|
-
|
|
1245
|
+
ensure
|
|
1246
|
+
self.error_logger(ex) if defined?(ex) && Rails.logger.class.to_s == "Ougai::Logger"
|
|
1153
1247
|
end
|
|
1154
1248
|
|
|
1155
1249
|
def update_create_tenant
|
|
@@ -1171,8 +1265,9 @@ module ZuoraAPI
|
|
|
1171
1265
|
while !response["nextPage"].blank?
|
|
1172
1266
|
url = self.rest_endpoint(response["nextPage"].split('/v1/').last)
|
|
1173
1267
|
Rails.logger.debug("Fetch Catalog URL #{url}")
|
|
1174
|
-
output_json, response = self.rest_call(:
|
|
1175
|
-
|
|
1268
|
+
output_json, response = self.rest_call(debug: false, url: url, timeout_retry: true)
|
|
1269
|
+
|
|
1270
|
+
if !/(true|t|yes|y|1)$/.match(output_json['success'].to_s) || output_json['success'].class != TrueClass
|
|
1176
1271
|
raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Error Getting Catalog: #{output_json}", response)
|
|
1177
1272
|
end
|
|
1178
1273
|
output_json["products"].each do |product|
|
|
@@ -1198,7 +1293,7 @@ module ZuoraAPI
|
|
|
1198
1293
|
return products, catalog_map
|
|
1199
1294
|
end
|
|
1200
1295
|
|
|
1201
|
-
def get_file(url: nil, headers: {}, z_session: true, tempfile: true, output_file_name: nil, zuora_track_id: nil, add_timestamp: true, file_path: defined?(Rails.root.join('tmp')) ? Rails.root.join('tmp') : Pathname.new(Dir.pwd), timeout_retries: 3, timeout:
|
|
1296
|
+
def get_file(url: nil, headers: {}, z_session: true, tempfile: true, output_file_name: nil, zuora_track_id: nil, add_timestamp: true, file_path: defined?(Rails.root.join('tmp')) ? Rails.root.join('tmp') : Pathname.new(Dir.pwd), timeout_retries: 3, timeout: 130, session_type: :basic, **execute_params)
|
|
1202
1297
|
raise "file_path must be of class Pathname" if file_path.class != Pathname
|
|
1203
1298
|
|
|
1204
1299
|
retry_count ||= timeout_retries
|
|
@@ -1306,12 +1401,10 @@ module ZuoraAPI
|
|
|
1306
1401
|
if !(retry_count -= 1).zero?
|
|
1307
1402
|
self.new_session
|
|
1308
1403
|
raise response.class
|
|
1309
|
-
else
|
|
1310
|
-
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error)
|
|
1311
1404
|
end
|
|
1312
|
-
|
|
1313
|
-
raise
|
|
1405
|
+
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error)
|
|
1314
1406
|
end
|
|
1407
|
+
raise
|
|
1315
1408
|
else
|
|
1316
1409
|
raise ZuoraAPI::Exceptions::FileDownloadError.new("File Download Failed #{response.class}")
|
|
1317
1410
|
end
|
|
@@ -1321,133 +1414,120 @@ module ZuoraAPI
|
|
|
1321
1414
|
sleep(5)
|
|
1322
1415
|
if (retry_count -= 1) >= 0
|
|
1323
1416
|
retry
|
|
1324
|
-
else
|
|
1325
|
-
Rails.logger.error("File Download Failed")
|
|
1326
|
-
raise
|
|
1327
1417
|
end
|
|
1418
|
+
Rails.logger.error("File Download Failed")
|
|
1419
|
+
raise
|
|
1328
1420
|
end
|
|
1329
1421
|
|
|
1330
1422
|
def getDataSourceExport(query, extract: true, encrypted: false, zip: true, z_track_id: "")
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
xml['SOAP-ENV'].
|
|
1335
|
-
xml['
|
|
1336
|
-
xml['ns1'].
|
|
1337
|
-
xml['ns1'].session self.get_session(prefix: false, auth_type: :basic, zuora_track_id: z_track_id)
|
|
1338
|
-
end
|
|
1423
|
+
tries ||= 3
|
|
1424
|
+
request = Nokogiri::XML::Builder.new do |xml|
|
|
1425
|
+
xml['SOAP-ENV'].Envelope('xmlns:SOAP-ENV' => "http://schemas.xmlsoap.org/soap/envelope/", 'xmlns:ns2' => "http://object.api.zuora.com/", 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance", 'xmlns:ns1' => "http://api.zuora.com/") do
|
|
1426
|
+
xml['SOAP-ENV'].Header do
|
|
1427
|
+
xml['ns1'].SessionHeader do
|
|
1428
|
+
xml['ns1'].session self.get_session(prefix: false, auth_type: :basic, zuora_track_id: z_track_id)
|
|
1339
1429
|
end
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1430
|
+
end
|
|
1431
|
+
xml['SOAP-ENV'].Body do
|
|
1432
|
+
xml['ns1'].create do
|
|
1433
|
+
xml['ns1'].zObjects('xsi:type' => "ns2:Export") do
|
|
1434
|
+
xml['ns2'].Format 'csv'
|
|
1435
|
+
xml['ns2'].Zip zip
|
|
1436
|
+
xml['ns2'].Name 'googman'
|
|
1437
|
+
xml['ns2'].Query query
|
|
1438
|
+
xml['ns2'].Encrypted encrypted
|
|
1349
1439
|
end
|
|
1350
1440
|
end
|
|
1351
1441
|
end
|
|
1352
1442
|
end
|
|
1443
|
+
end
|
|
1353
1444
|
|
|
1354
|
-
|
|
1445
|
+
response_query = HTTParty.post(self.url, body: request.to_xml(:save_with => XML_SAVE_OPTIONS).strip, headers: {'Content-Type' => "application/json; charset=utf-8", "Z-Track-Id" => z_track_id}, :timeout => 130)
|
|
1355
1446
|
|
|
1356
|
-
|
|
1357
|
-
|
|
1447
|
+
output_xml = Nokogiri::XML(response_query.body)
|
|
1448
|
+
raise_errors(type: :SOAP, body: output_xml, response: response_query) if output_xml.xpath('//ns1:Success', 'ns1' =>'http://api.zuora.com/').text != "true"
|
|
1358
1449
|
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1450
|
+
# raise "Export Creation Unsuccessful : #{response_query.code}: #{response_query.parsed_response}" if output_xml.xpath('//ns1:Success', 'ns1' =>'http://api.zuora.com/').text != "true"
|
|
1451
|
+
|
|
1452
|
+
id = output_xml.xpath('//ns1:Id', 'ns1' =>'http://api.zuora.com/').text
|
|
1362
1453
|
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
end
|
|
1454
|
+
confirmRequest = Nokogiri::XML::Builder.new do |xml|
|
|
1455
|
+
xml['SOAP-ENV'].Envelope('xmlns:SOAP-ENV' => "http://schemas.xmlsoap.org/soap/envelope/", 'xmlns:ns2' => "http://object.api.zuora.com/", 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance", 'xmlns:ns1' => "http://api.zuora.com/") do
|
|
1456
|
+
xml['SOAP-ENV'].Header do
|
|
1457
|
+
xml['ns1'].SessionHeader do
|
|
1458
|
+
xml['ns1'].session self.get_session(prefix: false, auth_type: :basic, zuora_track_id: z_track_id)
|
|
1369
1459
|
end
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1460
|
+
end
|
|
1461
|
+
xml['SOAP-ENV'].Body do
|
|
1462
|
+
xml['ns1'].query do
|
|
1463
|
+
xml['ns1'].queryString "SELECT Id, CreatedById, CreatedDate, Encrypted, FileId, Format, Name, Query, Size, Status, StatusReason, UpdatedById, UpdatedDate, Zip From Export where Id = '#{id}'"
|
|
1374
1464
|
end
|
|
1375
1465
|
end
|
|
1376
1466
|
end
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
while result != "Completed"
|
|
1380
|
-
sleep 3
|
|
1381
|
-
response_query = HTTParty.post(self.url, body: confirmRequest.to_xml(:save_with => XML_SAVE_OPTIONS).strip, headers: {'Content-Type' => "application/json; charset=utf-8", "Z-Track-Id" => z_track_id}, :timeout => 120)
|
|
1382
|
-
|
|
1383
|
-
output_xml = Nokogiri::XML(response_query.body)
|
|
1384
|
-
result = output_xml.xpath('//ns2:Status', 'ns2' =>'http://object.api.zuora.com/').text
|
|
1385
|
-
status_code = response_query.code if response_query
|
|
1467
|
+
end
|
|
1468
|
+
result = 'Waiting'
|
|
1386
1469
|
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1470
|
+
while result != "Completed"
|
|
1471
|
+
sleep 3
|
|
1472
|
+
response_query = HTTParty.post(self.url, body: confirmRequest.to_xml(:save_with => XML_SAVE_OPTIONS).strip, headers: {'Content-Type' => "application/json; charset=utf-8", "Z-Track-Id" => z_track_id}, :timeout => 130)
|
|
1390
1473
|
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
Rails.logger.debug("=====> Export path #{export_file.path}")
|
|
1395
|
-
|
|
1396
|
-
if extract && zip
|
|
1397
|
-
require "zip"
|
|
1398
|
-
new_path = export_file_path.partition('.zip').first
|
|
1399
|
-
zipped = Zip::File.open(export_file_path)
|
|
1400
|
-
file_handle = zipped.entries.first
|
|
1401
|
-
file_handle.extract(new_path)
|
|
1402
|
-
File.delete(export_file_path)
|
|
1403
|
-
return new_path
|
|
1404
|
-
else
|
|
1405
|
-
return export_file_path
|
|
1406
|
-
end
|
|
1407
|
-
rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
|
|
1408
|
-
if !(tries -= 1).zero?
|
|
1409
|
-
Rails.logger.info("Export call failed - Trace ID: #{z_track_id}")
|
|
1410
|
-
self.new_session
|
|
1411
|
-
retry
|
|
1412
|
-
else
|
|
1413
|
-
raise ex
|
|
1414
|
-
end
|
|
1474
|
+
output_xml = Nokogiri::XML(response_query.body)
|
|
1475
|
+
result = output_xml.xpath('//ns2:Status', 'ns2' =>'http://object.api.zuora.com/').text
|
|
1476
|
+
status_code = response_query.code if response_query
|
|
1415
1477
|
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
sleep 10
|
|
1420
|
-
retry
|
|
1421
|
-
else
|
|
1422
|
-
raise ex
|
|
1423
|
-
end
|
|
1478
|
+
raise_errors(type: :SOAP, body: output_xml, response: response_query) if result.blank? || result == "Failed"
|
|
1479
|
+
# raise "Export Creation Unsuccessful : #{response_query.code}: #{response_query.parsed_response}" if result.blank? || result == "Failed"
|
|
1480
|
+
end
|
|
1424
1481
|
|
|
1425
|
-
|
|
1426
|
-
|
|
1482
|
+
file_id = output_xml.xpath('//ns2:FileId', 'ns2' =>'http://object.api.zuora.com/').text
|
|
1483
|
+
export_file = get_file(:url => self.fileURL(file_id))
|
|
1484
|
+
export_file_path = export_file.path
|
|
1485
|
+
Rails.logger.debug("=====> Export path #{export_file.path}")
|
|
1486
|
+
|
|
1487
|
+
if extract && zip
|
|
1488
|
+
require "zip"
|
|
1489
|
+
new_path = export_file_path.partition('.zip').first
|
|
1490
|
+
zipped = Zip::File.open(export_file_path)
|
|
1491
|
+
file_handle = zipped.entries.first
|
|
1492
|
+
file_handle.extract(new_path)
|
|
1493
|
+
File.delete(export_file_path)
|
|
1494
|
+
return new_path
|
|
1495
|
+
else
|
|
1496
|
+
return export_file_path
|
|
1497
|
+
end
|
|
1498
|
+
rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
|
|
1499
|
+
if !(tries -= 1).zero?
|
|
1500
|
+
Rails.logger.info("Export call failed - Trace ID: #{z_track_id}")
|
|
1501
|
+
self.new_session
|
|
1502
|
+
retry
|
|
1503
|
+
end
|
|
1504
|
+
raise ex
|
|
1427
1505
|
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
end
|
|
1506
|
+
rescue ZuoraAPI::Exceptions::ZuoraUnexpectedError => ex
|
|
1507
|
+
if !(tries -= 1).zero?
|
|
1508
|
+
Rails.logger.info("Trace ID: #{z_track_id} UnexpectedError, will retry after 10 seconds")
|
|
1509
|
+
sleep 10
|
|
1510
|
+
retry
|
|
1511
|
+
end
|
|
1512
|
+
raise ex
|
|
1436
1513
|
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
retry
|
|
1440
|
-
else
|
|
1441
|
-
raise ex
|
|
1442
|
-
end
|
|
1514
|
+
rescue *ZUORA_API_ERRORS => ex
|
|
1515
|
+
raise ex
|
|
1443
1516
|
|
|
1444
|
-
|
|
1445
|
-
|
|
1517
|
+
rescue *(CONNECTION_EXCEPTIONS + CONNECTION_READ_EXCEPTIONS) => ex
|
|
1518
|
+
if !(tries -= 1).zero?
|
|
1519
|
+
Rails.logger.info("Trace ID: #{z_track_id} Timed out will retry after 5 seconds")
|
|
1520
|
+
sleep 5
|
|
1521
|
+
retry
|
|
1446
1522
|
end
|
|
1523
|
+
raise ex
|
|
1524
|
+
|
|
1525
|
+
rescue ZuoraAPI::Exceptions::BadEntityError => ex
|
|
1526
|
+
raise ex
|
|
1447
1527
|
end
|
|
1448
1528
|
|
|
1449
1529
|
def query(query, parse = false)
|
|
1450
|
-
output_xml, input_xml = self.soap_call(
|
|
1530
|
+
output_xml, input_xml = self.soap_call(debug: false, timeout_retry: true) do |xml|
|
|
1451
1531
|
xml['ns1'].query do
|
|
1452
1532
|
xml['ns1'].queryString query
|
|
1453
1533
|
end
|
|
@@ -10,113 +10,22 @@ module ZuoraAPI
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def new_session(auth_type: :basic, debug: false, zuora_track_id: nil)
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
super do
|
|
14
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Basic Login, does not support Authentication of Type: #{auth_type}") if auth_type != :basic
|
|
15
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Request Basic Login but either 'Username' or 'Password' were not passed.") if (self.password.blank? && self.username.blank?)
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
xml['api'].login do
|
|
22
|
-
xml['api'].username self.username
|
|
23
|
-
xml['api'].password self.password
|
|
24
|
-
xml['api'].entityId self.entity_id if !self.entity_id.blank?
|
|
25
|
-
end
|
|
17
|
+
output_xml, input_xml, response = soap_call(timeout_retry: true, skip_session: true, zuora_track_id: zuora_track_id) do |xml|
|
|
18
|
+
xml['api'].login do
|
|
19
|
+
xml['api'].username self.username
|
|
20
|
+
xml['api'].password self.password
|
|
21
|
+
xml['api'].entityId self.entity_id if !self.entity_id.blank?
|
|
26
22
|
end
|
|
27
23
|
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
input_xml = Nokogiri::XML(request.to_xml(:save_with => XML_SAVE_OPTIONS).strip)
|
|
31
|
-
input_xml.xpath('//ns1:session', 'ns1' =>'http://api.zuora.com/').children.remove
|
|
32
|
-
Rails.logger.debug('Connect') {"SOAP XML: #{input_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}"} if debug
|
|
33
|
-
|
|
34
|
-
headers = { 'Content-Type' => "text/xml; charset=utf-8" }
|
|
35
|
-
headers['Zuora-Track-Id'] = zuora_track_id if zuora_track_id.present?
|
|
36
24
|
|
|
37
|
-
response_query = HTTParty.post(self.url,:body => request.to_xml(:save_with => XML_SAVE_OPTIONS).strip, :headers => headers, :timeout => 10)
|
|
38
|
-
output_xml = Nokogiri::XML(response_query.body)
|
|
39
|
-
Rails.logger.debug('Connect') {"Response Code: #{response_query.code} SOAP XML: #{output_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}"} if debug
|
|
40
|
-
|
|
41
|
-
if !response_query.success?
|
|
42
|
-
self.current_session = nil
|
|
43
|
-
if output_xml.namespaces.size > 0 && output_xml.xpath('//soapenv:Fault').size > 0
|
|
44
|
-
self.current_error = output_xml.xpath('//fns:FaultMessage', 'fns' =>'http://fault.api.zuora.com/').text
|
|
45
|
-
if self.current_error.include?('deactivated')
|
|
46
|
-
self.status = 'Deactivated'
|
|
47
|
-
self.current_error = 'Deactivated user login, please check with Zuora tenant administrator'
|
|
48
|
-
self.errors[:username] = self.current_error
|
|
49
|
-
elsif self.current_error.include?('inactive')
|
|
50
|
-
self.status = 'Inactive'
|
|
51
|
-
self.current_error = 'Inactive user login, please check with Zuora tenant administrator'
|
|
52
|
-
self.errors[:username] = self.current_error
|
|
53
|
-
elsif self.current_error.include?("invalid username or password") || self.current_error.include?("Invalid login. User name and password do not match.")
|
|
54
|
-
self.status = 'Invalid Login'
|
|
55
|
-
self.current_error = 'Invalid login, please check username and password or URL endpoint'
|
|
56
|
-
self.errors[:username] = self.current_error
|
|
57
|
-
self.errors[:password] = self.current_error
|
|
58
|
-
elsif self.current_error.include?('unsupported version')
|
|
59
|
-
self.status = 'Unsupported API Version'
|
|
60
|
-
self.current_error = 'Unsupported API version, please verify URL endpoint'
|
|
61
|
-
self.errors[:url] = self.current_error
|
|
62
|
-
elsif self.current_error.include?('invalid api version')
|
|
63
|
-
self.status = 'Invalid API Version'
|
|
64
|
-
self.current_error = 'Invalid API version, please verify URL endpoint'
|
|
65
|
-
self.errors[:url] = self.current_error
|
|
66
|
-
elsif self.current_error.include?('invalid session')
|
|
67
|
-
self.status = 'Invalid Session'
|
|
68
|
-
self.current_error = 'Session invalid, please update session and verify URL endpoint'
|
|
69
|
-
self.errors[:session] = self.current_error
|
|
70
|
-
elsif self.current_error.include?('Your IP address')
|
|
71
|
-
self.status = 'Restricted IP'
|
|
72
|
-
self.current_error = 'IP restricted, contact Zuora tenant administrator and remove IP restriction'
|
|
73
|
-
self.errors[:base] = self.current_error
|
|
74
|
-
elsif self.current_error.include?('This account has been locked')
|
|
75
|
-
self.status = 'Locked'
|
|
76
|
-
self.current_error = 'Locked user login, please wait or navigate to Zuora to unlock user'
|
|
77
|
-
self.errors[:username] = self.current_error
|
|
78
|
-
elsif self.current_error.include?('Entity not exist:')
|
|
79
|
-
self.status = 'Entity Missing'
|
|
80
|
-
self.errors[:base] = self.current_error
|
|
81
|
-
else
|
|
82
|
-
self.status = 'Unknown'
|
|
83
|
-
self.current_error = output_xml.xpath('//faultstring').text if self.current_error.blank?
|
|
84
|
-
self.errors[:base] = self.current_error
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
else
|
|
88
|
-
self.status = 'Unknown'
|
|
89
|
-
self.current_error = output_xml.xpath('//faultstring').text if self.current_error.blank?
|
|
90
|
-
self.errors[:base] = self.current_error
|
|
91
|
-
end
|
|
92
|
-
else
|
|
93
|
-
#Username & password combo
|
|
94
25
|
retrieved_session = output_xml.xpath('//ns1:Session', 'ns1' =>'http://api.zuora.com/').text
|
|
95
|
-
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("No session found for api call.",
|
|
96
|
-
self.status = 'Active'
|
|
26
|
+
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("No session found for api call.", response) if retrieved_session.blank?
|
|
97
27
|
self.current_session = retrieved_session
|
|
98
|
-
|
|
99
|
-
return self.status
|
|
100
|
-
rescue *(CONNECTION_EXCEPTIONS + CONNECTION_READ_EXCEPTIONS) => ex
|
|
101
|
-
if !tries.zero?
|
|
102
|
-
tries -= 1
|
|
103
|
-
sleep(self.timeout_sleep)
|
|
104
|
-
retry
|
|
105
|
-
else
|
|
106
|
-
if Rails.logger.class.to_s == "Ougai::Logger"
|
|
107
|
-
Rails.logger.error("BasicLogin - Timed out", ex)
|
|
108
|
-
else
|
|
109
|
-
Rails.logger.error("BasicLogin - #{ex.class} Timed out")
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
self.current_error = "Request timed out. Try again"
|
|
113
|
-
self.status = 'Timeout'
|
|
114
|
-
return self.status
|
|
115
|
-
end
|
|
116
|
-
rescue EOFError
|
|
117
|
-
if self.url.match?(/.*services\d{1,}.zuora.com*/)
|
|
118
|
-
self.current_error = "Services tenant '#{self.url.scan(/.*\/\/(services\d{1,}).zuora.com*/).last.first}' is no longer available."
|
|
119
|
-
self.status = 'Not Available'
|
|
28
|
+
self.status = 'Active'
|
|
120
29
|
return self.status
|
|
121
30
|
end
|
|
122
31
|
end
|
|
@@ -12,16 +12,18 @@ module ZuoraAPI
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def new_session(auth_type: nil, zuora_track_id: nil)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
15
|
+
super do
|
|
16
|
+
if auth_type == :bearer
|
|
17
|
+
get_bearer_token(zuora_track_id: zuora_track_id)
|
|
18
|
+
elsif auth_type == :basic
|
|
19
|
+
get_bearer_token(zuora_track_id: zuora_track_id) if self.oauth_expired?
|
|
20
|
+
get_z_session(zuora_track_id: zuora_track_id)
|
|
21
|
+
else
|
|
22
|
+
get_bearer_token(zuora_track_id: zuora_track_id) if self.oauth_expired?
|
|
23
|
+
get_z_session(zuora_track_id: zuora_track_id)
|
|
24
|
+
end
|
|
25
|
+
return self.status
|
|
23
26
|
end
|
|
24
|
-
return self.status
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
def get_active_bearer_token
|
|
@@ -30,7 +32,6 @@ module ZuoraAPI
|
|
|
30
32
|
end
|
|
31
33
|
|
|
32
34
|
def get_z_session(debug: false, zuora_track_id: nil)
|
|
33
|
-
tries ||= 2
|
|
34
35
|
headers = self.entity_id.present? ? {"Zuora-Entity-Ids" => self.entity_id } : {}
|
|
35
36
|
headers['Zuora-Track-Id'] = zuora_track_id if zuora_track_id.present?
|
|
36
37
|
output_json, response = self.rest_call(:url => self.rest_endpoint("connections"), :session_type => :bearer, :headers => headers)
|
|
@@ -44,49 +45,22 @@ module ZuoraAPI
|
|
|
44
45
|
headers: response.headers.to_s,
|
|
45
46
|
}
|
|
46
47
|
})
|
|
47
|
-
raise ZuoraAPI::Exceptions::
|
|
48
|
+
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("Failure Parsing Cookie Headers", response)
|
|
48
49
|
end
|
|
49
|
-
rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
|
|
50
|
-
if !tries.zero?
|
|
51
|
-
tries -= 1
|
|
52
|
-
Rails.logger.debug {"Session Invalid"}
|
|
53
|
-
self.new_session(auth_type: :bearer)
|
|
54
|
-
retry
|
|
55
|
-
end
|
|
56
|
-
raise ex
|
|
57
|
-
|
|
58
|
-
rescue ZuoraAPI::Exceptions::ZuoraAPIError, ZuoraAPI::Exceptions::ZuoraAPIRequestLimit, ZuoraAPI::Exceptions::ZuoraAPILockCompetition => ex
|
|
59
|
-
raise ex
|
|
60
|
-
|
|
61
|
-
rescue *(CONNECTION_EXCEPTIONS + CONNECTION_READ_EXCEPTIONS) => ex
|
|
62
|
-
if !tries.zero?
|
|
63
|
-
tries -= 1
|
|
64
|
-
sleep(self.timeout_sleep)
|
|
65
|
-
retry
|
|
66
|
-
end
|
|
67
|
-
if Rails.logger.class.to_s == "Ougai::Logger"
|
|
68
|
-
Rails.logger.error("OAuthLogin - Timed out", ex)
|
|
69
|
-
else
|
|
70
|
-
Rails.logger.error("OAuthLogin - #{ex.class} Timed out")
|
|
71
|
-
end
|
|
72
|
-
self.current_error = "Request timed out. Try again"
|
|
73
|
-
self.status = 'Timeout'
|
|
74
|
-
return self.status
|
|
75
50
|
end
|
|
76
51
|
|
|
77
52
|
def get_bearer_token(zuora_track_id: nil)
|
|
78
|
-
tries ||= 2
|
|
79
53
|
raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Request Oauth Login but either 'Oauth Client Id' or 'Oauth Secret' were not passed") if self.oauth_client_id.blank? || self.oauth_secret.blank?
|
|
80
54
|
|
|
81
55
|
headers = { "content-type" => "application/x-www-form-urlencoded" }
|
|
82
56
|
headers['Zuora-Track-Id'] = zuora_track_id if zuora_track_id.present?
|
|
83
57
|
|
|
84
58
|
output_json, response = self.rest_call(:method => :post,
|
|
85
|
-
:
|
|
86
|
-
:
|
|
87
|
-
:
|
|
88
|
-
:
|
|
89
|
-
:
|
|
59
|
+
url: self.rest_endpoint.chomp('v1/').concat("oauth/token"),
|
|
60
|
+
z_session: false,
|
|
61
|
+
timeout_retry: true,
|
|
62
|
+
headers: headers,
|
|
63
|
+
body: {"client_id"=> self.oauth_client_id, "client_secret"=>self.oauth_secret, "grant_type" =>"client_credentials"}
|
|
90
64
|
)
|
|
91
65
|
|
|
92
66
|
self.bearer_token = output_json["access_token"]
|
|
@@ -96,44 +70,6 @@ module ZuoraAPI
|
|
|
96
70
|
self.status = 'Active'
|
|
97
71
|
|
|
98
72
|
return self.status
|
|
99
|
-
|
|
100
|
-
rescue ZuoraAPI::Exceptions::ZuoraAPIInternalServerError => ex
|
|
101
|
-
raise ex if tries.zero?
|
|
102
|
-
|
|
103
|
-
tries -= 1
|
|
104
|
-
sleep(self.timeout_sleep)
|
|
105
|
-
retry
|
|
106
|
-
rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
|
|
107
|
-
self.bearer_token = nil
|
|
108
|
-
self.oauth_session_expires_at = nil
|
|
109
|
-
self.current_error = ex.message
|
|
110
|
-
case ex.message
|
|
111
|
-
when "Forbidden"
|
|
112
|
-
self.current_error = "The user associated to OAuth credential set has been deactivated."
|
|
113
|
-
self.status = 'Deactivated'
|
|
114
|
-
else
|
|
115
|
-
self.current_error = "Invalid login, please check client ID and Client Secret or URL endpoint"
|
|
116
|
-
self.status = 'Invalid Login'
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
return self.status
|
|
120
|
-
rescue ZuoraAPI::Exceptions::ZuoraAPIError, ZuoraAPI::Exceptions::ZuoraAPIRequestLimit, ZuoraAPI::Exceptions::ZuoraAPILockCompetition => ex
|
|
121
|
-
raise ex
|
|
122
|
-
rescue *(CONNECTION_EXCEPTIONS + CONNECTION_READ_EXCEPTIONS) => ex
|
|
123
|
-
if !tries.zero?
|
|
124
|
-
tries -= 1
|
|
125
|
-
sleep(self.timeout_sleep)
|
|
126
|
-
retry
|
|
127
|
-
else
|
|
128
|
-
if Rails.logger.class.to_s == "Ougai::Logger"
|
|
129
|
-
Rails.logger.error("OAuthLogin - Timed out will retry after #{self.timeout_sleep} seconds", ex)
|
|
130
|
-
else
|
|
131
|
-
Rails.logger.error("OAuthLogin - #{ex.class} Timed out will retry after #{self.timeout_sleep} seconds")
|
|
132
|
-
end
|
|
133
|
-
self.current_error = "Invalid login, please check client ID and Client Secret or URL endpoint"
|
|
134
|
-
self.status = 'Timeout'
|
|
135
|
-
return self.status
|
|
136
|
-
end
|
|
137
73
|
end
|
|
138
74
|
|
|
139
75
|
def oauth_expired?
|
data/lib/zuora_api/version.rb
CHANGED
data/zuora_api.gemspec
CHANGED
|
@@ -18,11 +18,12 @@ Gem::Specification.new do |spec|
|
|
|
18
18
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
19
19
|
spec.require_paths = ["lib"]
|
|
20
20
|
|
|
21
|
-
spec.add_development_dependency "bundler"
|
|
21
|
+
spec.add_development_dependency "bundler"
|
|
22
22
|
spec.add_development_dependency "rake", "~> 10.0"
|
|
23
23
|
spec.add_development_dependency "rspec", "~> 3.0"
|
|
24
24
|
spec.add_development_dependency("webmock")
|
|
25
|
-
spec.add_development_dependency("simplecov")
|
|
25
|
+
spec.add_development_dependency("simplecov", "~> 0.18.5")
|
|
26
|
+
spec.add_dependency("ougai")
|
|
26
27
|
spec.add_dependency("nokogiri")
|
|
27
28
|
spec.add_dependency("httparty")
|
|
28
29
|
spec.add_dependency("rubyzip")
|
metadata
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: zuora_api
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.7.
|
|
4
|
+
version: 1.7.66i
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Zuora Strategic Solutions Group
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-06-
|
|
11
|
+
date: 2020-06-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- - "
|
|
17
|
+
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
19
|
+
version: '0'
|
|
20
20
|
type: :development
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
|
-
- - "
|
|
24
|
+
- - ">="
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
26
|
+
version: '0'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: rake
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -68,12 +68,26 @@ dependencies:
|
|
|
68
68
|
version: '0'
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
70
|
name: simplecov
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: 0.18.5
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: 0.18.5
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: ougai
|
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
|
72
86
|
requirements:
|
|
73
87
|
- - ">="
|
|
74
88
|
- !ruby/object:Gem::Version
|
|
75
89
|
version: '0'
|
|
76
|
-
type: :
|
|
90
|
+
type: :runtime
|
|
77
91
|
prerelease: false
|
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
93
|
requirements:
|
|
@@ -186,7 +200,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
186
200
|
- !ruby/object:Gem::Version
|
|
187
201
|
version: 1.3.1
|
|
188
202
|
requirements: []
|
|
189
|
-
rubygems_version: 3.
|
|
203
|
+
rubygems_version: 3.1.2
|
|
190
204
|
signing_key:
|
|
191
205
|
specification_version: 4
|
|
192
206
|
summary: Gem that provides easy integration to Zuora
|