zuora_api 1.7.65 → 1.7.66b
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/lib/zuora_api/exceptions.rb +6 -4
- data/lib/zuora_api/login.rb +244 -178
- data/lib/zuora_api/logins/oauth.rb +20 -20
- data/lib/zuora_api/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e57efb2492106ced22eaf4a943801d0f639eab7c8e1e6c5a4a927fe556963007
|
4
|
+
data.tar.gz: e21363cc410dd6c49e5513db1fd3561ea9d13ec7390e57b7abf6b966a44314b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1869137cefa3e67accb4bd917e4466df8627cf198eff2409420c0176c8e4fe728f8a56d53297a7f7418d7f7b207a1843383c74379cfc5662ec38c19e3e05300a
|
7
|
+
data.tar.gz: 037fa29a6add8b326da59402cdd2207c65385d3046869866c3cb2a5cbc2e8935855aeba549fda5239579cf4e3aabd86ce992b3dc1c9284ee166bf8c333b95bbd
|
data/lib/zuora_api/exceptions.rb
CHANGED
@@ -177,14 +177,15 @@ module ZuoraAPI
|
|
177
177
|
end
|
178
178
|
|
179
179
|
class ZuoraAPITemporaryError < Error
|
180
|
-
attr_reader :code, :response
|
180
|
+
attr_reader :code, :response, :errors
|
181
181
|
attr_writer :default_message
|
182
182
|
|
183
|
-
def initialize(message = nil,response=nil, errors = [], successes = [], *args)
|
183
|
+
def initialize(message = nil, response = nil, errors = [], successes = [], *args)
|
184
184
|
@code = response.class.to_s == "HTTParty::Response" ? response.code : nil
|
185
185
|
@message = parse_message(message)
|
186
186
|
@response = response
|
187
187
|
@default_message = "There is a temporary error with zuora system."
|
188
|
+
@errors = errors
|
188
189
|
end
|
189
190
|
|
190
191
|
def to_s
|
@@ -225,13 +226,14 @@ module ZuoraAPI
|
|
225
226
|
end
|
226
227
|
|
227
228
|
class ZuoraAPIReadTimeout < Net::ReadTimeout
|
228
|
-
attr_reader :code, :response
|
229
|
+
attr_reader :code, :response, :request
|
229
230
|
attr_writer :default_message
|
230
231
|
|
231
|
-
def initialize(message = nil,response=nil, errors = [], successes = [], *args)
|
232
|
+
def initialize(message = nil, response = nil, request = nil, errors = [], successes = [], *args)
|
232
233
|
@code = response.class.to_s == "HTTParty::Response" ? response.code : nil
|
233
234
|
@message = message
|
234
235
|
@response = response
|
236
|
+
@request = request
|
235
237
|
@default_message = "Authentication type is not supported by this Login"
|
236
238
|
end
|
237
239
|
|
data/lib/zuora_api/login.rb
CHANGED
@@ -39,8 +39,8 @@ module ZuoraAPI
|
|
39
39
|
|
40
40
|
ZUORA_SERVER_ERRORS = [
|
41
41
|
ZuoraAPI::Exceptions::ZuoraAPIInternalServerError,
|
42
|
-
|
43
|
-
|
42
|
+
ZuoraAPI::Exceptions::ZuoraAPIConnectionTimeout,
|
43
|
+
ZuoraAPI::Exceptions::ZuoraAPIReadTimeout,
|
44
44
|
ZuoraAPI::Exceptions::ZuoraUnexpectedError
|
45
45
|
].freeze
|
46
46
|
|
@@ -474,12 +474,16 @@ module ZuoraAPI
|
|
474
474
|
headers = { 'Content-Type' => "text/xml; charset=utf-8", 'Accept' => 'text/xml'}
|
475
475
|
headers['Zuora-Track-Id'] = zuora_track_id if zuora_track_id.present?
|
476
476
|
|
477
|
-
|
477
|
+
request = HTTParty::Request.new(
|
478
|
+
Net::HTTP::Post,
|
478
479
|
self.url,
|
479
|
-
:
|
480
|
-
:
|
481
|
-
:
|
480
|
+
body: xml.doc.to_xml(:save_with => XML_SAVE_OPTIONS).strip,
|
481
|
+
headers: headers,
|
482
|
+
timeout: timeout,
|
482
483
|
)
|
484
|
+
|
485
|
+
response = request.perform
|
486
|
+
|
483
487
|
output_xml = Nokogiri::XML(response.body)
|
484
488
|
Rails.logger.debug("Response SOAP XML: #{output_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}") if debug
|
485
489
|
|
@@ -496,20 +500,18 @@ module ZuoraAPI
|
|
496
500
|
end
|
497
501
|
|
498
502
|
retry
|
499
|
-
else
|
500
|
-
if errors.include?(ex.class)
|
501
|
-
raise ex
|
502
|
-
else
|
503
|
-
return output_xml, input_xml, response
|
504
|
-
end
|
505
503
|
end
|
504
|
+
|
505
|
+
raise ex if errors.include?(ex.class)
|
506
|
+
|
507
|
+
return output_xml, input_xml, response
|
508
|
+
|
506
509
|
rescue *ZUORA_API_ERRORS => ex
|
507
|
-
if errors.include?(ex.class)
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
end
|
510
|
+
raise ex if errors.include?(ex.class)
|
511
|
+
|
512
|
+
response = ex.response unless response
|
513
|
+
return output_xml, input_xml, response
|
514
|
+
|
513
515
|
rescue *CONNECTION_EXCEPTIONS => ex
|
514
516
|
if tries.zero?
|
515
517
|
if output_exception_messages
|
@@ -526,34 +528,26 @@ module ZuoraAPI
|
|
526
528
|
sleep(timeout_sleep_interval)
|
527
529
|
retry
|
528
530
|
rescue *CONNECTION_READ_EXCEPTIONS => ex
|
529
|
-
if tries.zero?
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
531
|
+
if !tries.zero?
|
532
|
+
tries -= 1
|
533
|
+
|
534
|
+
if ex.is_a?(Errno::ECONNRESET) && ex.message.include?('SSL_connect')
|
535
|
+
retry
|
536
|
+
elsif timeout_retry
|
537
|
+
sleep(timeout_sleep_interval)
|
538
|
+
retry
|
536
539
|
end
|
537
|
-
raise ex
|
538
540
|
end
|
539
541
|
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
sleep(timeout_sleep_interval)
|
546
|
-
retry
|
547
|
-
else
|
548
|
-
if output_exception_messages
|
549
|
-
if Rails.logger.class.to_s == "Ougai::Logger"
|
550
|
-
Rails.logger.error("SOAP Call - Timed out will retry after #{timeout_sleep_interval} seconds", ex)
|
551
|
-
else
|
552
|
-
Rails.logger.error("SOAP Call - #{ex.class} Timed out will retry after #{timeout_sleep_interval} seconds")
|
553
|
-
end
|
542
|
+
if output_exception_messages
|
543
|
+
if Rails.logger.class.to_s == "Ougai::Logger"
|
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")
|
554
547
|
end
|
555
|
-
raise ex
|
556
548
|
end
|
549
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIReadTimeout.new("Received read timeout from #{url}", nil, request) if ex.instance_of?(Net::ReadTimeout)
|
550
|
+
raise ex
|
557
551
|
rescue => ex
|
558
552
|
raise ex
|
559
553
|
else
|
@@ -561,24 +555,33 @@ module ZuoraAPI
|
|
561
555
|
end
|
562
556
|
|
563
557
|
def raise_errors(type: :SOAP, body: nil, response: nil)
|
564
|
-
|
565
|
-
|
558
|
+
request_uri, request_path, match_string = "", "", ""
|
559
|
+
if response.class.to_s == "HTTP::Message"
|
560
|
+
request_uri = response.http_header.request_uri.to_s
|
561
|
+
request_path = response.http_header.request_uri.path
|
562
|
+
match_string = "#{response.http_header.request_method}::#{response.code}::#{request_uri}"
|
563
|
+
else
|
564
|
+
request = response.request
|
565
|
+
request_uri = response.request.uri
|
566
|
+
request_path = request.path.path
|
567
|
+
match_string = "#{request.http_method.to_s.split("Net::HTTP::").last.upcase}::#{response.code}::#{request_path}"
|
568
|
+
end
|
566
569
|
|
567
570
|
if [502,503].include?(response.code)
|
568
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIConnectionTimeout.new("Received #{response.code} from #{
|
571
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIConnectionTimeout.new("Received #{response.code} from #{request_uri}", response)
|
569
572
|
end
|
570
573
|
|
571
574
|
# Check failure response code
|
572
575
|
case response.code
|
573
576
|
when 504
|
574
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIReadTimeout.new("Received 504 from #{
|
577
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIReadTimeout.new("Received 504 from #{request_uri}", response)
|
575
578
|
when 429
|
576
579
|
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)
|
577
580
|
when 401
|
578
581
|
|
579
582
|
else
|
580
583
|
if body.class == Hash
|
581
|
-
case
|
584
|
+
case request_path
|
582
585
|
when /^\/v1\/connections$/
|
583
586
|
response_headers = response.headers.to_h
|
584
587
|
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new("Missing cookies for authentication call", response) if response_headers['set-cookie'].blank?
|
@@ -602,7 +605,7 @@ module ZuoraAPI
|
|
602
605
|
reason = body.xpath('//ns2:StatusReason', 'ns2' => 'http://object.api.zuora.com/').text
|
603
606
|
if reason.present?
|
604
607
|
message = body.xpath('//ns2:StatusReason', 'ns2' => 'http://object.api.zuora.com/').text
|
605
|
-
error = message.match(/^[\w\d]{16}\: (Unexpected error.|No HTTP Response)/).present? ? 'UNEXPECTED_ERROR' : 'FATAL_ERROR'
|
608
|
+
error = message.match(/^[\w\d]{16}\: (Unexpected error.|No HTTP Response|Socket Timeout|There is an internal error, please try again later)/).present? ? 'UNEXPECTED_ERROR' : 'FATAL_ERROR'
|
606
609
|
else
|
607
610
|
error = 'FATAL_ERROR'
|
608
611
|
message = 'Export failed due to unknown reason. Consult api logs.'
|
@@ -624,23 +627,10 @@ module ZuoraAPI
|
|
624
627
|
end
|
625
628
|
end
|
626
629
|
|
627
|
-
|
628
|
-
|
629
|
-
elsif response.code == 500
|
630
|
-
if response.headers.fetch('content-type', []).include?('application/json')
|
631
|
-
begin
|
632
|
-
output_json = JSON.parse(response.body)
|
633
|
-
self.raise_errors(type: :JSON, body: output_json, response: response)
|
634
|
-
rescue JSON::ParserError => ex
|
635
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new(response.body, response)
|
636
|
-
end
|
637
|
-
else
|
638
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new(response.body, response)
|
639
|
-
end
|
640
|
-
end
|
641
|
-
|
630
|
+
self.errors_via_content_type(response: response, type: :xml)
|
631
|
+
|
642
632
|
when :JSON
|
643
|
-
case
|
633
|
+
case request_path
|
644
634
|
when /^\/query\/jobs.*/ #DataQuery Paths
|
645
635
|
return if body.class != Hash
|
646
636
|
case match_string
|
@@ -660,12 +650,16 @@ module ZuoraAPI
|
|
660
650
|
if reporting_message&.include?("com.zuora.rest.RestUsageException: The user does not have permissions for this API.")
|
661
651
|
raise ZuoraAPI::Exceptions::ZuoraAPIError.new(reporting_message, response)
|
662
652
|
elsif reporting_message&.include?("500 Internal Server Error")
|
663
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new("Internal Server Error. The Reporting API is down. Contact Support.")
|
653
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new("Internal Server Error. The Reporting API is down. Contact Support.", response)
|
664
654
|
end
|
665
655
|
case match_string
|
666
656
|
when /^GET::400::\/api\/rest\/v1\/reports\/(reportlabels\/)?([a-zA-Z0-9\-_]+)\/report-details$/ # Get report, capture of the id is present if needed in future error responses.
|
667
657
|
raise ZuoraAPI::Exceptions::ZuoraAPIError.new(reporting_message, response) if reporting_message.present?
|
668
658
|
end
|
659
|
+
when /\/objects\/batch\//
|
660
|
+
if body['code'].present? && /61$/.match(body['code'].to_s).present? # if last 2 digits of code are 61
|
661
|
+
raise ZuoraAPI::Exceptions::ZuoraAPITemporaryError.new(body['message'], nil, body['details'])
|
662
|
+
end
|
669
663
|
end
|
670
664
|
|
671
665
|
body = body.dig("results").present? ? body["results"] : body if body.class == Hash
|
@@ -726,7 +720,6 @@ module ZuoraAPI
|
|
726
720
|
if codes_array.map{|code| code.to_s.slice(6,7).to_i}.include?(50)
|
727
721
|
raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("#{messages_array.join(', ')}", response)
|
728
722
|
end
|
729
|
-
|
730
723
|
#Internal Server Error
|
731
724
|
if codes_array.map{|code| code.to_s.slice(6,7).to_i}.include?(60)
|
732
725
|
if messages_array.uniq.size == 1
|
@@ -737,6 +730,11 @@ module ZuoraAPI
|
|
737
730
|
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new("#{messages_array.join(', ')}", response)
|
738
731
|
end
|
739
732
|
|
733
|
+
#Retryiable Service Error
|
734
|
+
if codes_array.map{|code| code.to_s.slice(6,7).to_i}.include?(61)
|
735
|
+
raise ZuoraAPI::Exceptions::ZuoraAPITemporaryError.new("#{messages_array.join(', ')}", response)
|
736
|
+
end
|
737
|
+
|
740
738
|
#Request exceeded limit
|
741
739
|
if codes_array.map{|code| code.to_s.slice(6,7).to_i}.include?(70)
|
742
740
|
raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new("#{messages_array.join(', ')}", response)
|
@@ -789,26 +787,56 @@ module ZuoraAPI
|
|
789
787
|
end
|
790
788
|
end
|
791
789
|
|
790
|
+
if body.class == Hash && body['message'].present?
|
791
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new(body['message'], response) if response.code == 500
|
792
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIError.new(body['message'], response) if ![200,201].include?(response.code)
|
793
|
+
end
|
794
|
+
|
795
|
+
self.errors_via_content_type(response: response, type: :json)
|
796
|
+
|
792
797
|
#All other errors
|
793
|
-
if response.code
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
798
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIError.new(response.body, response) if ![200,201].include?(response.code)
|
799
|
+
end
|
800
|
+
end
|
801
|
+
|
802
|
+
def errors_via_content_type(response: nil, type: :xml)
|
803
|
+
response_content_types = response.headers.transform_keys(&:downcase).fetch('content-type', []).first || ""
|
804
|
+
|
805
|
+
if response_content_types.include?('application/json') && type != :json
|
806
|
+
output_json = JSON.parse(response.body)
|
807
|
+
self.raise_errors(type: :JSON, body: output_json, response: response)
|
808
|
+
|
809
|
+
elsif (response_content_types.include?('application/xml') || response_content_types.include?('text/xml')) and type != :xml
|
810
|
+
output_xml = Nokogiri::XML(response.body)
|
811
|
+
self.raise_errors(type: :SOAP, body: output_xml, response: response)
|
812
|
+
|
813
|
+
elsif response_content_types.include?('text/html')
|
814
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new("Akamai Error", response) if response.headers.fetch('server', '') == 'AkamaiGHost'
|
815
|
+
|
816
|
+
parse_body = Nokogiri::HTML(response.body)
|
817
|
+
error_title = parse_body.xpath('//h2').text
|
818
|
+
error_title = parse_body.xpath('//h1').text if error_title.blank?
|
819
|
+
error_message = parse_body.xpath('//p').text
|
820
|
+
|
821
|
+
error_message = error_title if error_message.blank?
|
822
|
+
|
823
|
+
if error_title.present?
|
824
|
+
case error_title
|
825
|
+
when /Service Unavailable/
|
826
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIConnectionTimeout.new(error_message, response)
|
827
|
+
when /Client sent a bad request./, /Bad Request/, /403 Forbidden/
|
828
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new(error_message, response)
|
829
|
+
else
|
830
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new(error_message, response)
|
808
831
|
end
|
809
832
|
end
|
833
|
+
|
834
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new("Http response body is missing", response) if response.body.blank?
|
810
835
|
end
|
836
|
+
|
837
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new(response.body, response) if response.code == 500
|
811
838
|
end
|
839
|
+
|
812
840
|
|
813
841
|
def get_soap_error_and_message(body)
|
814
842
|
error = body.xpath('//fns:FaultCode', 'fns' =>'http://fault.api.zuora.com/').text
|
@@ -872,9 +900,9 @@ module ZuoraAPI
|
|
872
900
|
when /.*UNEXPECTED_ERROR/
|
873
901
|
raise ZuoraAPI::Exceptions::ZuoraUnexpectedError.new(message, response, errors, success)
|
874
902
|
when /.*soapenv:Server.*/
|
875
|
-
if /^Invalid value.*for type.*|^Id is invalid
|
903
|
+
if /^Invalid value.*for type.*|^Id is invalid|^date string can not be less than 19 charactors$/.match(message).present?
|
876
904
|
raise ZuoraAPI::Exceptions::ZuoraAPIError.new(message, response, errors, success)
|
877
|
-
elsif /^Invalid white space character \(.*\) in text to output$/.match(message).present?
|
905
|
+
elsif /^Invalid white space character \(.*\) in text to output$|^Invalid null character in text to output$/.match(message).present?
|
878
906
|
raise ZuoraAPI::Exceptions::ZuoraAPIUnkownError.new(message, response, errors, success)
|
879
907
|
end
|
880
908
|
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new(message, response, errors, success)
|
@@ -1025,7 +1053,7 @@ module ZuoraAPI
|
|
1025
1053
|
modified_headers = {'Content-Type' => "application/json; charset=utf-8"}.merge(authentication_headers).merge(headers)
|
1026
1054
|
|
1027
1055
|
begin
|
1028
|
-
|
1056
|
+
request = HTTParty::Request.new(
|
1029
1057
|
"Net::HTTP::#{method.to_s.capitalize}".constantize,
|
1030
1058
|
url,
|
1031
1059
|
body: body,
|
@@ -1033,7 +1061,9 @@ module ZuoraAPI
|
|
1033
1061
|
timeout: timeout,
|
1034
1062
|
multipart: multipart,
|
1035
1063
|
stream_body: stream_body
|
1036
|
-
)
|
1064
|
+
)
|
1065
|
+
|
1066
|
+
response = request.perform(&block)
|
1037
1067
|
|
1038
1068
|
Rails.logger.debug("Response Code: #{response.code}") if debug
|
1039
1069
|
begin
|
@@ -1052,10 +1082,10 @@ module ZuoraAPI
|
|
1052
1082
|
if self.class.to_s == 'ZuoraAPI::Oauth' && ex.message.include?("Authentication type is not supported by this Login")
|
1053
1083
|
session_type = :bearer
|
1054
1084
|
retry
|
1055
|
-
else
|
1056
|
-
Rails.logger.debug("Rest Call - Session Bad Auth type")
|
1057
|
-
raise ex
|
1058
1085
|
end
|
1086
|
+
Rails.logger.debug("Rest Call - Session Bad Auth type")
|
1087
|
+
raise ex
|
1088
|
+
|
1059
1089
|
rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
|
1060
1090
|
if !tries.zero? && z_session
|
1061
1091
|
tries -= 1
|
@@ -1068,20 +1098,17 @@ module ZuoraAPI
|
|
1068
1098
|
end
|
1069
1099
|
|
1070
1100
|
retry
|
1071
|
-
else
|
1072
|
-
if errors.include?(ex.class)
|
1073
|
-
raise ex
|
1074
|
-
else
|
1075
|
-
return [output_json, response]
|
1076
|
-
end
|
1077
1101
|
end
|
1102
|
+
|
1103
|
+
raise ex if errors.include?(ex.class)
|
1104
|
+
return [output_json, response]
|
1105
|
+
|
1078
1106
|
rescue *ZUORA_API_ERRORS => ex
|
1079
|
-
if errors.include?(ex.class)
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1084
|
-
end
|
1107
|
+
raise ex if errors.include?(ex.class)
|
1108
|
+
|
1109
|
+
response = ex.response unless response
|
1110
|
+
return [output_json, response]
|
1111
|
+
|
1085
1112
|
rescue ZuoraAPI::Exceptions::BadEntityError => ex
|
1086
1113
|
raise ex
|
1087
1114
|
rescue *CONNECTION_EXCEPTIONS => ex
|
@@ -1100,34 +1127,25 @@ module ZuoraAPI
|
|
1100
1127
|
sleep(timeout_sleep_interval)
|
1101
1128
|
retry
|
1102
1129
|
rescue *CONNECTION_READ_EXCEPTIONS => ex
|
1103
|
-
if tries.zero?
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1130
|
+
if !tries.zero?
|
1131
|
+
tries -= 1
|
1132
|
+
if ex.is_a?(Errno::ECONNRESET) && ex.message.include?('SSL_connect')
|
1133
|
+
retry
|
1134
|
+
elsif timeout_retry
|
1135
|
+
sleep(timeout_sleep_interval)
|
1136
|
+
retry
|
1110
1137
|
end
|
1111
|
-
raise ex
|
1112
1138
|
end
|
1113
|
-
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1118
|
-
|
1119
|
-
sleep(timeout_sleep_interval)
|
1120
|
-
retry
|
1121
|
-
else
|
1122
|
-
if output_exception_messages
|
1123
|
-
if Rails.logger.class.to_s == "Ougai::Logger"
|
1124
|
-
Rails.logger.error("Rest Call - Timed out will retry after #{timeout_sleep_interval} seconds", ex)
|
1125
|
-
else
|
1126
|
-
Rails.logger.error("Rest Call - #{ex.class} Timed out will retry after #{timeout_sleep_interval} seconds")
|
1127
|
-
end
|
1139
|
+
|
1140
|
+
if output_exception_messages
|
1141
|
+
if Rails.logger.class.to_s == "Ougai::Logger"
|
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")
|
1128
1145
|
end
|
1129
|
-
raise ex
|
1130
1146
|
end
|
1147
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIReadTimeout.new("Received read timeout from #{url}", nil, request) if ex.instance_of?(Net::ReadTimeout)
|
1148
|
+
raise ex
|
1131
1149
|
rescue => ex
|
1132
1150
|
raise ex
|
1133
1151
|
else
|
@@ -1183,6 +1201,8 @@ module ZuoraAPI
|
|
1183
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: 120, session_type: :basic, **execute_params)
|
1184
1202
|
raise "file_path must be of class Pathname" if file_path.class != Pathname
|
1185
1203
|
|
1204
|
+
retry_count ||= timeout_retries
|
1205
|
+
|
1186
1206
|
#Make sure directory exists
|
1187
1207
|
require 'fileutils'
|
1188
1208
|
FileUtils.mkdir_p(file_path) unless File.exists?(file_path)
|
@@ -1200,7 +1220,6 @@ module ZuoraAPI
|
|
1200
1220
|
headers['Zuora-Track-Id'] = zuora_track_id if zuora_track_id.present?
|
1201
1221
|
|
1202
1222
|
response_save = nil
|
1203
|
-
retry_count ||= timeout_retries
|
1204
1223
|
http.request_get(uri.request_uri, headers) do |response|
|
1205
1224
|
response_save = response
|
1206
1225
|
status_code = response.code if response
|
@@ -1308,75 +1327,122 @@ module ZuoraAPI
|
|
1308
1327
|
end
|
1309
1328
|
end
|
1310
1329
|
|
1311
|
-
def getDataSourceExport(query, extract: true, encrypted: false, zip: true)
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1330
|
+
def getDataSourceExport(query, extract: true, encrypted: false, zip: true, z_track_id: "")
|
1331
|
+
begin
|
1332
|
+
tries ||= 3
|
1333
|
+
request = Nokogiri::XML::Builder.new do |xml|
|
1334
|
+
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
|
1335
|
+
xml['SOAP-ENV'].Header do
|
1336
|
+
xml['ns1'].SessionHeader do
|
1337
|
+
xml['ns1'].session self.get_session(prefix: false, auth_type: :basic, zuora_track_id: z_track_id)
|
1338
|
+
end
|
1317
1339
|
end
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1321
|
-
|
1322
|
-
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1340
|
+
xml['SOAP-ENV'].Body do
|
1341
|
+
xml['ns1'].create do
|
1342
|
+
xml['ns1'].zObjects('xsi:type' => "ns2:Export") do
|
1343
|
+
xml['ns2'].Format 'csv'
|
1344
|
+
xml['ns2'].Zip zip
|
1345
|
+
xml['ns2'].Name 'googman'
|
1346
|
+
xml['ns2'].Query query
|
1347
|
+
xml['ns2'].Encrypted encrypted
|
1348
|
+
end
|
1327
1349
|
end
|
1328
1350
|
end
|
1329
1351
|
end
|
1330
1352
|
end
|
1331
|
-
end
|
1332
1353
|
|
1333
|
-
|
1354
|
+
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 => 120)
|
1334
1355
|
|
1335
|
-
|
1336
|
-
|
1337
|
-
id = output_xml.xpath('//ns1:Id', 'ns1' =>'http://api.zuora.com/').text
|
1356
|
+
output_xml = Nokogiri::XML(response_query.body)
|
1357
|
+
raise_errors(type: :SOAP, body: output_xml, response: response_query) if output_xml.xpath('//ns1:Success', 'ns1' =>'http://api.zuora.com/').text != "true"
|
1338
1358
|
|
1339
|
-
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
1359
|
+
# raise "Export Creation Unsuccessful : #{response_query.code}: #{response_query.parsed_response}" if output_xml.xpath('//ns1:Success', 'ns1' =>'http://api.zuora.com/').text != "true"
|
1360
|
+
|
1361
|
+
id = output_xml.xpath('//ns1:Id', 'ns1' =>'http://api.zuora.com/').text
|
1362
|
+
|
1363
|
+
confirmRequest = Nokogiri::XML::Builder.new do |xml|
|
1364
|
+
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
|
1365
|
+
xml['SOAP-ENV'].Header do
|
1366
|
+
xml['ns1'].SessionHeader do
|
1367
|
+
xml['ns1'].session self.get_session(prefix: false, auth_type: :basic, zuora_track_id: z_track_id)
|
1368
|
+
end
|
1344
1369
|
end
|
1345
|
-
|
1346
|
-
|
1347
|
-
|
1348
|
-
|
1370
|
+
xml['SOAP-ENV'].Body do
|
1371
|
+
xml['ns1'].query do
|
1372
|
+
xml['ns1'].queryString "SELECT Id, CreatedById, CreatedDate, Encrypted, FileId, Format, Name, Query, Size, Status, StatusReason, UpdatedById, UpdatedDate, Zip From Export where Id = '#{id}'"
|
1373
|
+
end
|
1349
1374
|
end
|
1350
1375
|
end
|
1351
1376
|
end
|
1352
|
-
|
1353
|
-
result = 'Waiting'
|
1377
|
+
result = 'Waiting'
|
1354
1378
|
|
1355
|
-
|
1356
|
-
|
1357
|
-
|
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)
|
1358
1382
|
|
1359
|
-
|
1360
|
-
|
1361
|
-
|
1362
|
-
raise "Export Creation Unsuccessful : #{output_xml.xpath('//ns1:Message', 'ns1' =>'http://api.zuora.com/').text}" if result.blank? || result == "Failed"
|
1363
|
-
end
|
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
|
1364
1386
|
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1387
|
+
raise_errors(type: :SOAP, body: output_xml, response: response_query) if result.blank? || result == "Failed"
|
1388
|
+
# raise "Export Creation Unsuccessful : #{response_query.code}: #{response_query.parsed_response}" if result.blank? || result == "Failed"
|
1389
|
+
end
|
1390
|
+
|
1391
|
+
file_id = output_xml.xpath('//ns2:FileId', 'ns2' =>'http://object.api.zuora.com/').text
|
1392
|
+
export_file = get_file(:url => self.fileURL(file_id))
|
1393
|
+
export_file_path = export_file.path
|
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
|
1415
|
+
|
1416
|
+
rescue ZuoraAPI::Exceptions::ZuoraUnexpectedError => ex
|
1417
|
+
if !(tries -= 1).zero?
|
1418
|
+
Rails.logger.info("Trace ID: #{z_track_id} UnexpectedError, will retry after 10 seconds")
|
1419
|
+
sleep 10
|
1420
|
+
retry
|
1421
|
+
else
|
1422
|
+
raise ex
|
1423
|
+
end
|
1424
|
+
|
1425
|
+
rescue *ZUORA_API_ERRORS => ex
|
1426
|
+
raise ex
|
1427
|
+
|
1428
|
+
rescue *(CONNECTION_EXCEPTIONS + CONNECTION_READ_EXCEPTIONS) => ex
|
1429
|
+
if !(tries -= 1).zero?
|
1430
|
+
Rails.logger.info("Trace ID: #{z_track_id} Timed out will retry after 5 seconds")
|
1431
|
+
sleep 5
|
1432
|
+
retry
|
1433
|
+
else
|
1434
|
+
raise ex
|
1435
|
+
end
|
1436
|
+
|
1437
|
+
rescue Errno::ECONNRESET => ex
|
1438
|
+
if !(tries -= 1).zero? && ex.message.include?('SSL_connect')
|
1439
|
+
retry
|
1440
|
+
else
|
1441
|
+
raise ex
|
1442
|
+
end
|
1443
|
+
|
1444
|
+
rescue ZuoraAPI::Exceptions::BadEntityError => ex
|
1445
|
+
raise ex
|
1380
1446
|
end
|
1381
1447
|
end
|
1382
1448
|
|
@@ -37,7 +37,13 @@ module ZuoraAPI
|
|
37
37
|
begin
|
38
38
|
self.current_session = response.headers.to_h['set-cookie'][0].split(';')[0].split('=',2)[1].gsub('%3D', '=')
|
39
39
|
rescue NoMethodError => ex
|
40
|
-
Rails.logger.fatal("Failure Parsing Cookie Headers",
|
40
|
+
Rails.logger.fatal("Failure Parsing Cookie Headers", {
|
41
|
+
response: {
|
42
|
+
status: response.code,
|
43
|
+
params: response.body.to_s,
|
44
|
+
headers: response.headers.to_s,
|
45
|
+
}
|
46
|
+
})
|
41
47
|
raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Failure Parsing Cookie Headers")
|
42
48
|
end
|
43
49
|
rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
|
@@ -46,34 +52,28 @@ module ZuoraAPI
|
|
46
52
|
Rails.logger.debug {"Session Invalid"}
|
47
53
|
self.new_session(auth_type: :bearer)
|
48
54
|
retry
|
49
|
-
else
|
50
|
-
if errors.include?(ex.class)
|
51
|
-
raise ex
|
52
|
-
else
|
53
|
-
return [output_json, response]
|
54
|
-
end
|
55
55
|
end
|
56
|
+
raise ex if errors.include?(ex.class)
|
57
|
+
return [output_json, response]
|
58
|
+
|
56
59
|
rescue ZuoraAPI::Exceptions::ZuoraAPIError, ZuoraAPI::Exceptions::ZuoraAPIRequestLimit, ZuoraAPI::Exceptions::ZuoraAPILockCompetition => ex
|
57
|
-
if errors.include?(ex.class)
|
58
|
-
|
59
|
-
|
60
|
-
return [output_json, response]
|
61
|
-
end
|
60
|
+
raise ex if errors.include?(ex.class)
|
61
|
+
return [output_json, response]
|
62
|
+
|
62
63
|
rescue *(CONNECTION_EXCEPTIONS + CONNECTION_READ_EXCEPTIONS) => ex
|
63
64
|
if !tries.zero?
|
64
65
|
tries -= 1
|
65
66
|
sleep(self.timeout_sleep)
|
66
67
|
retry
|
68
|
+
end
|
69
|
+
if Rails.logger.class.to_s == "Ougai::Logger"
|
70
|
+
Rails.logger.error("OAuthLogin - Timed out", ex)
|
67
71
|
else
|
68
|
-
|
69
|
-
Rails.logger.error("OAuthLogin - Timed out", ex)
|
70
|
-
else
|
71
|
-
Rails.logger.error("OAuthLogin - #{ex.class} Timed out")
|
72
|
-
end
|
73
|
-
self.current_error = "Request timed out. Try again"
|
74
|
-
self.status = 'Timeout'
|
75
|
-
return self.status
|
72
|
+
Rails.logger.error("OAuthLogin - #{ex.class} Timed out")
|
76
73
|
end
|
74
|
+
self.current_error = "Request timed out. Try again"
|
75
|
+
self.status = 'Timeout'
|
76
|
+
return self.status
|
77
77
|
end
|
78
78
|
|
79
79
|
def get_bearer_token(zuora_track_id: nil)
|
data/lib/zuora_api/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
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.66b
|
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-
|
11
|
+
date: 2020-06-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -182,9 +182,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
182
182
|
version: '0'
|
183
183
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
184
184
|
requirements:
|
185
|
-
- - "
|
185
|
+
- - ">"
|
186
186
|
- !ruby/object:Gem::Version
|
187
|
-
version:
|
187
|
+
version: 1.3.1
|
188
188
|
requirements: []
|
189
189
|
rubygems_version: 3.0.3
|
190
190
|
signing_key:
|