zuora_api 1.6.54 → 1.6.251

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: db9d04850886747fda373d56232f5a050b274cb1313d3e07c4acf34a803e6071
4
- data.tar.gz: 0c9dfafc751ff2b2722ddace209f1092b06f98c3c4dee059b0a75165c915f435
2
+ SHA1:
3
+ metadata.gz: 1bfd029f416736077243b7e0d6c8b3fd5e218167
4
+ data.tar.gz: 5344e6087fc2d37c50972ab97cd6705d4696bb23
5
5
  SHA512:
6
- metadata.gz: af8e4adb50fcc272107b17e5a2d45c3b0b017c0978d02b68746b046399721b48e6b6d871d4519793b6fccfc2b11b140c7cde82d179ac1714953b0c30d132ec2e
7
- data.tar.gz: 5df0bc633015dc4848a13eff13033e6fe5d512ec7c072df9397577d78359bde086d7bc1fb4766771fd22d4a9736fbb92290a2d75827ea742f0b6de192943d538
6
+ metadata.gz: a4fd0150091455e2999b35081be1a078ca2a529e2ff264227048f3c1f7788b7a193510acb030270f051058f635edf2b51f557f1f2ecac2280ec1a9d33a58e772
7
+ data.tar.gz: 6700d2cceaf338fbb1f151841e65cf7980cc2e0a13370416cbd2530e8893716d7ec9aa286f6f203800c0e27845210ed4a20e567ea97335e8ef0d88a6294882b5
@@ -1,4 +1,5 @@
1
- image: ruby:2.6
1
+
2
+ image: ruby:2.3.1
2
3
  stages:
3
4
  - setup
4
5
  - test
@@ -40,24 +41,10 @@ rubygems-deploy:
40
41
  stage: deploy
41
42
  allow_failure: false
42
43
  script:
43
- - echo "deb http://ftp.us.debian.org/debian testing main contrib non-free" >> /etc/apt/sources.list
44
- - apt-get update
45
- - apt-get install -y git
46
- - apt-get clean all
47
- - gem install dpl
48
- - if [[ "staging" == $CI_BUILD_REF_SLUG ]];then export VERSION=`git describe --match "[0-9]*\.[0-9]*\.[0-9]*[a-z]" --abbrev=0 --tags HEAD`; fi
49
- - if [[ "master" == $CI_BUILD_REF_SLUG ]];then export VERSION=`git describe --exclude "[0-9]*\.[0-9]*\.[0-9]*[a-z]" --abbrev=0 --tags HEAD`; fi
50
- - echo $VERSION
51
- - sed -i "s/0.0.1/$VERSION/" /Connect/zuora-gem/lib/zuora_api/version.rb
52
- - git add /Connect/zuora-gem/lib/zuora_api/version.rb
53
- - git config --global user.email "connect@zuora.com"
54
- - git config --global user.name "Connect Automation"
55
- - git commit -m "Automated Version Update $VERSION"
56
44
  - bundle install
57
45
  - gem install rake
58
46
  - version=$(rake install | grep -o 'pkg/zuora_api-.*gem')
59
47
  - curl -u $USERNAME:$PASSWORD https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials; chmod 0600 ~/.gem/credentials
60
48
  - gem push $version
61
49
  only:
62
- - master
63
- - staging
50
+ - master
@@ -1,23 +1,18 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
- ## [1.6.32] - 2018-5-14
5
- ### Changed
6
- - Don't log fatal errors, allow application to decide for file download
7
- - Don't change api url if the user set a high api url
8
-
9
- ###Removed
10
- - Force encoding
11
-
12
- ## [1.6.28] - 2018-3-12
4
+ ## [1.6.16] - 2018-12-09
13
5
  ### Added
14
- - Way to avoid force encoding for filedownload
6
+ - Example
15
7
 
16
- ## [1.6.28] - 2018-3-12
17
- ### Added
18
- - Way to avoid force encoding for filedownload
8
+ ### Changed
9
+ - Example
10
+
11
+ ### Removed
12
+ - Example
19
13
 
20
14
  ## [1.6.22] - 2019-01-03
15
+
21
16
  ### Changed
22
17
  - get_identity method - supports ZSession auth now
23
18
  - updated rspecs accordingly
@@ -6,8 +6,8 @@ module ZuoraAPI
6
6
  attr_reader :code, :response
7
7
  attr_writer :default_message
8
8
 
9
- def initialize(message = nil,response=nil)
10
- @code = response.present? && response.class.to_s == "HTTParty::Response" ? response.code : nil
9
+ def initialize(message = nil,response=nil, code =nil)
10
+ @code = code
11
11
  @message = message
12
12
  @response = response
13
13
  @default_message = "Error with Zuora Session."
@@ -22,8 +22,8 @@ module ZuoraAPI
22
22
  attr_reader :code, :response, :errors, :successes
23
23
  attr_writer :default_message
24
24
 
25
- def initialize(message = nil,response=nil, errors = [], successes = [], *args)
26
- @code = response.present? && response.class.to_s == "HTTParty::Response" ? response.code : nil
25
+ def initialize(message = nil,response=nil, code =nil, errors = [], successes = [])
26
+ @code = code
27
27
  @message = message
28
28
  @response = response
29
29
  @default_message = "Error with Zuora Entity"
@@ -40,8 +40,8 @@ module ZuoraAPI
40
40
  attr_reader :code, :response, :errors, :successes
41
41
  attr_writer :default_message
42
42
 
43
- def initialize(message = nil,response=nil, errors = [], successes = [], *args)
44
- @code = response.present? && response.class.to_s == "HTTParty::Response" ? response.code : nil
43
+ def initialize(message = nil,response=nil, code =nil, errors = [], successes = [])
44
+ @code = code
45
45
  @message = message
46
46
  @response = response
47
47
  @default_message = "Error communicating with Zuora."
@@ -58,8 +58,8 @@ module ZuoraAPI
58
58
  attr_reader :code, :response
59
59
  attr_writer :default_message
60
60
 
61
- def initialize(message = nil,response=nil, *args)
62
- @code = response.present? && response.class.to_s == "HTTParty::Response" ? response.code : nil
61
+ def initialize(message = nil,response=nil, code =nil)
62
+ @code = code
63
63
  @message = message
64
64
  @response = response
65
65
  @default_message = "Your request limit has been exceeded for zuora."
@@ -74,24 +74,8 @@ module ZuoraAPI
74
74
  attr_reader :code, :response
75
75
  attr_writer :default_message
76
76
 
77
- def initialize(message = nil,response=nil, *args)
78
- @code = response.present? && response.class.to_s == "HTTParty::Response" ? response.code : nil
79
- @message = message
80
- @response = response
81
- @default_message = "Operation failed due to lock competition. Please retry"
82
- end
83
-
84
- def to_s
85
- @message || @default_message
86
- end
87
- end
88
-
89
- class ZuoraDataIntegrity < Error
90
- attr_reader :code, :response
91
- attr_writer :default_message
92
-
93
- def initialize(message = nil,response=nil, *args)
94
- @code = response.present? && response.class.to_s == "HTTParty::Response" ? response.code : nil
77
+ def initialize(message = nil,response=nil, code =nil)
78
+ @code = code
95
79
  @message = message
96
80
  @response = response
97
81
  @default_message = "Operation failed due to lock competition. Please retry"
@@ -106,8 +90,8 @@ module ZuoraAPI
106
90
  attr_reader :code, :response
107
91
  attr_writer :default_message
108
92
 
109
- def initialize(message = nil,response=nil, *args)
110
- @code = response.present? && response.class.to_s == "HTTParty::Response" ? response.code : nil
93
+ def initialize(message = nil,response=nil, code =nil)
94
+ @code = code
111
95
  @message = message
112
96
  @response = response
113
97
  @default_message = "There is a temporary error with zuora system."
@@ -122,8 +106,8 @@ module ZuoraAPI
122
106
  attr_reader :code, :response
123
107
  attr_writer :default_message
124
108
 
125
- def initialize(message = nil,response=nil, *args)
126
- @code = response.present? && response.class.to_s == "HTTParty::Response" ? response.code : nil
109
+ def initialize(message = nil,response=nil, code =nil)
110
+ @code = code
127
111
  @message = message
128
112
  @response = response
129
113
  @default_message = "Authentication type is not supported by this Login"
@@ -1,38 +1,28 @@
1
1
  require "httparty"
2
2
  require "nokogiri"
3
3
  require "uri"
4
- require 'zuora_api/exceptions'
5
4
 
6
5
  module ZuoraAPI
7
6
  class Login
8
7
  ENVIRONMENTS = [SANDBOX = 'Sandbox', PRODUCTION = 'Production', PREFORMANCE = 'Preformance', SERVICES = 'Services', UNKNOWN = 'Unknown', STAGING = 'Staging' ]
9
8
  REGIONS = [EU = 'EU', US = 'US', NA = 'NA' ]
10
- MIN_Endpoint = '96.0'
9
+ MIN_Endpoint = '91.0'
11
10
  XML_SAVE_OPTIONS = Nokogiri::XML::Node::SaveOptions::AS_XML | Nokogiri::XML::Node::SaveOptions::NO_DECLARATION
12
- CONNECTION_EXCEPTIONS = [Net::OpenTimeout, OpenSSL::SSL::SSLError, Errno::ECONNREFUSED, SocketError, Errno::EHOSTUNREACH, Errno::EADDRNOTAVAIL]
11
+ CONNECTION_EXCEPTIONS = [Net::OpenTimeout, OpenSSL::SSL::SSLError, Errno::ECONNREFUSED, SocketError]
13
12
  CONNECTION_READ_EXCEPTIONS = [Net::ReadTimeout, Errno::ECONNRESET, Errno::EPIPE]
14
- ZUORA_API_ERRORS = [ZuoraAPI::Exceptions::ZuoraAPIError, ZuoraAPI::Exceptions::ZuoraAPIRequestLimit, ZuoraAPI::Exceptions::ZuoraAPILockCompetition, ZuoraAPI::Exceptions::ZuoraAPITemporaryError, ZuoraAPI::Exceptions::ZuoraDataIntegrity]
15
-
16
- attr_accessor :region, :url, :wsdl_number, :current_session, :bearer_token, :oauth_session_expires_at, :environment, :status, :errors, :current_error, :user_info, :tenant_id, :tenant_name, :entity_id, :timeout_sleep, :hostname, :zconnect_provider
17
13
 
18
- def initialize(url: nil, entity_id: nil, session: nil, status: nil, bearer_token: nil, oauth_session_expires_at: nil, **keyword_args)
19
- raise "URL is nil or empty, but URL is required" if url.nil? || url.empty?
14
+ attr_accessor :region, :url, :wsdl_number, :current_session, :environment, :status, :errors, :current_error, :user_info, :tenant_id, :tenant_name, :entity_id, :timeout_sleep, :hostname, :zconnect_provider
15
+
16
+ def initialize(url: nil, entity_id: nil, session: nil, status: nil, **keyword_args)
17
+ raise "URL is nil or empty, but URL is required" if url.nil? | url.empty?
20
18
  # raise "URL is improper. URL must contain zuora.com, zuora.eu, or zuora.na" if /zuora.com|zuora.eu|zuora.na/ === url
21
- self.hostname = /(?<=https:\/\/|http:\/\/)(.*?)(?=\/|$)/.match(url)[0] if !/(?<=https:\/\/|http:\/\/)(.*?)(?=\/|$)/.match(url).nil?
22
- if !/apps\/services\/a\/\d{2}\.\d$/.match(url.strip)
23
- self.url = "https://#{hostname}/apps/services/a/#{MIN_Endpoint}"
24
- elsif MIN_Endpoint.to_f > url.scan(/(\d{2}\.\d)$/).dig(0,0).to_f
25
- self.url = url.gsub(/(\d{2}\.\d)$/, MIN_Endpoint)
26
- else
27
- self.url = url
28
- end
29
- self.entity_id = get_entity_id(entity_id: entity_id)
30
- self.errors = Hash.new
31
- self.current_session = session
32
- self.bearer_token = bearer_token
33
- self.oauth_session_expires_at = oauth_session_expires_at
34
- self.status = status.blank? ? "Active" : status
35
- self.user_info = Hash.new
19
+ @url = url.gsub(/(\d{2}\.\d)$/, MIN_Endpoint)
20
+ @hostname = /(?<=https:\/\/|http:\/\/)(.*?)(?=\/|$)/.match(url)[0] if !/(?<=https:\/\/|http:\/\/)(.*?)(?=\/|$)/.match(url).nil?
21
+ @entity_id = get_entity_id(entity_id: entity_id)
22
+ @errors = Hash.new
23
+ @current_session = session
24
+ @status = status.blank? ? "Active" : status
25
+ @user_info = Hash.new
36
26
  self.update_region
37
27
  self.update_environment
38
28
  self.update_zconnect_provider
@@ -46,21 +36,21 @@ module ZuoraAPI
46
36
  if !zsession.blank?
47
37
  response = HTTParty.get("https://#{self.hostname}/apps/v1/identity", :headers => {'Cookie' => "ZSession=#{zsession}", 'Content-Type' => 'application/json'})
48
38
  output_json = JSON.parse(response.body)
49
- elsif zconnect_accesstoken.present?
39
+ elsif !zconnect_accesstoken.blank?
40
+ code = zconnect_accesstoken.split("#!").last
41
+ encrypted_token, tenant_id = Base64.decode64(code).split(":")
50
42
  begin
51
- code = zconnect_accesstoken.split("#!").last
52
- encrypted_token, tenant_id = Base64.decode64(code).split(":")
53
43
  body = {'token' => encrypted_token}.to_json
54
44
  rescue => ex
55
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Invalid ZConnect Cookie")
45
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Invalid ZConnect Cookie", {}, 400)
56
46
  end
57
47
  response = HTTParty.post("https://#{self.hostname}/apps/zconnectsession/identity", :body => body, :headers => { 'Content-Type' => 'application/json' })
58
48
  output_json = JSON.parse(response.body)
59
49
  else
60
50
  if zconnect_accesstoken.blank? && cookies.keys.any? { |x| x.include? "ZConnect"}
61
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZConnect cookie present matching #{self.hostname}")
51
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZConnect cookie present matching #{self.hostname}", {}, 400)
62
52
  else
63
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present")
53
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present", {}, 400)
64
54
  end
65
55
  end
66
56
  rescue JSON::ParserError => ex
@@ -74,17 +64,17 @@ module ZuoraAPI
74
64
  zsession = cookies["ZSession"]
75
65
  zconnect_accesstoken = get_zconnect_accesstoken(cookies)
76
66
  begin
77
- if zsession.present?
67
+ if !zsession.blank?
78
68
  response = HTTParty.get("https://#{self.hostname}/apps/v1/navigation", :headers => {'Cookie' => "ZSession=#{zsession}", 'Content-Type' => 'application/json'})
79
69
  output_json = JSON.parse(response.body)
80
- elsif zconnect_accesstoken.present?
70
+ elsif !zconnect_accesstoken.blank?
81
71
  response = HTTParty.get("https://#{self.hostname}/apps/zconnectsession/navigation", :headers => {'Cookie' => "#{self.zconnect_provider}=#{zconnect_accesstoken}",'Content-Type' => 'application/json'})
82
72
  output_json = JSON.parse(response.body)
83
73
  else
84
74
  if zconnect_accesstoken.blank? && cookies.keys.any? { |x| x.include? "ZConnect"}
85
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZConnect cookie present matching #{self.hostname}")
75
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZConnect cookie present matching #{self.hostname}", {}, 400)
86
76
  else
87
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present")
77
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present", {}, 400)
88
78
  end
89
79
  end
90
80
  rescue JSON::ParserError => ex
@@ -106,9 +96,9 @@ module ZuoraAPI
106
96
  output_json = JSON.parse(response.body)
107
97
  else
108
98
  if zconnect_accesstoken.blank? && cookies.keys.any? { |x| x.include? "ZConnect"}
109
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZConnect cookie present matching #{self.hostname}")
99
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZConnect cookie present matching #{self.hostname}", {}, 400)
110
100
  else
111
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present")
101
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present", {}, 400)
112
102
  end
113
103
  end
114
104
  rescue JSON::ParserError => ex
@@ -130,9 +120,9 @@ module ZuoraAPI
130
120
  output_json = JSON.parse(response.body)
131
121
  else
132
122
  if zconnect_accesstoken.blank? && cookies.keys.any? { |x| x.include? "ZConnect"}
133
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZConnect cookie present matching #{self.hostname}")
123
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZConnect cookie present matching #{self.hostname}", {}, 400)
134
124
  else
135
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present")
125
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present", {}, 400)
136
126
  end
137
127
  end
138
128
  rescue JSON::ParserError => ex
@@ -180,12 +170,12 @@ module ZuoraAPI
180
170
  if entity_ids.blank? && cookies["ZuoraCurrentEntity"].present?
181
171
  entity_ids = Array(cookies["ZuoraCurrentEntity"].unpack("a8a4a4a4a12").join('-'))
182
172
  else
183
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Zuora Entity ID not provided")
173
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Zuora Entity ID not provided", {}, 400)
184
174
  end
185
175
  if user_id.blank? && cookies["Zuora-User-Id"].present?
186
176
  user_id = cookies["Zuora-User-Id"]
187
177
  else
188
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Zuora User ID not provided")
178
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Zuora User ID not provided", {}, 400)
189
179
  end
190
180
  elsif !client_id.nil? && !client_secret.nil?
191
181
  bearer_response = HTTParty.post("https://#{self.hostname}/oauth/token", :headers => {'Content-Type' => 'application/x-www-form-urlencoded', 'Accept' => 'application/json'}, :body => {'client_id' => client_id, 'client_secret' => URI::encode(client_secret), 'grant_type' => 'client_credentials'})
@@ -202,12 +192,12 @@ module ZuoraAPI
202
192
  output_json["clientSecret"] = new_client_secret
203
193
  return output_json
204
194
  elsif oauth_response.code == 401 && !oauth_response.message.blank?
205
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new(output_json["message"], oauth_response)
195
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new(output_json["message"], {}, oauth_response.code)
206
196
  else
207
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new(output_json["error"], oauth_response)
197
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new(output_json["error"], {}, oauth_response.code)
208
198
  end
209
199
  else
210
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Insufficient credentials provided")
200
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Insufficient credentials provided", {}, 400)
211
201
  end
212
202
  end
213
203
 
@@ -267,7 +257,7 @@ module ZuoraAPI
267
257
  if !self.url.blank?
268
258
  if /(?<=\.|\/|-|^)(apisandbox|sandbox)(?=\.|\/|-|$)/ === self.hostname
269
259
  self.environment = 'Sandbox'
270
- elsif /(?<=\.|\/|^)(service[\d]*|services[\d]*|ep-edge)(?=\.|\/|$)/ === self.hostname
260
+ elsif /(?<=\.|\/|^)(service|services[\d]*|ep-edge)(?=\.|\/|$)/ === self.hostname
271
261
  self.environment = 'Services'
272
262
  elsif /(?<=\.|\/|-|^)(pt[\d]*)(?=\.|\/|-|$)/ === self.hostname
273
263
  self.environment = 'Performance'
@@ -342,22 +332,17 @@ module ZuoraAPI
342
332
  when 'Services'
343
333
  https = /https:\/\/|http:\/\//.match(self.url)[0]
344
334
  host = self.hostname
345
- endpoint = "#{https}rest#{host}/v1/#{url}"
335
+ endpoint = "#{https}#{host}/apps/v1/#{url}"
346
336
  when 'Staging'
347
- endpoint = "https://rest-staging2.zuora.com/v1/".concat(url)
337
+ endpoint = "https://rest-staging2.zuora.com/".concat(url)
348
338
  when 'Unknown'
349
339
  raise "Environment unknown, returning passed in parameter unaltered"
350
340
  end
351
341
  return endpoint
352
342
  end
353
343
 
354
- def rest_domain
355
- require 'addressable/uri'
356
- return ::Addressable::URI.parse(self.rest_endpoint).host
357
- end
358
-
359
344
  def fileURL(url="")
360
- return self.rest_endpoint("file/").concat(url)
345
+ return self.url.split(".com").first.concat(".com/apps/api/file/").concat(url)
361
346
  end
362
347
 
363
348
  def dateFormat
@@ -368,16 +353,17 @@ module ZuoraAPI
368
353
  end
369
354
 
370
355
  def get_session(prefix: false, auth_type: :basic)
371
- Rails.logger.debug("Get session for #{auth_type} - #{self.class.to_s}") if Rails.env.to_s == 'development'
356
+ Rails.logger.debug("Get session for #{auth_type} - #{self.class.to_s}")
372
357
  case auth_type
373
358
  when :basic
374
359
  if self.current_session.blank?
360
+ Rails.logger.debug("Create new session")
375
361
  case self.class.to_s
376
362
  when 'ZuoraAPI::Oauth'
377
363
  if self.bearer_token.blank? || self.oauth_expired?
378
364
  self.new_session(auth_type: :bearer)
379
365
  end
380
- self.get_z_session if self.status == 'Active'
366
+ self.get_z_session
381
367
  when 'ZuoraAPI::Basic'
382
368
  self.new_session(auth_type: :basic)
383
369
  else
@@ -400,7 +386,7 @@ module ZuoraAPI
400
386
  end
401
387
  end
402
388
 
403
- def soap_call(ns1: 'ns1', ns2: 'ns2', batch_size: nil, single_transaction: false, debug: false, errors: [ZuoraAPI::Exceptions::ZuoraAPISessionError].concat(ZUORA_API_ERRORS), z_session: true, timeout_retry: false, timeout: 120,**keyword_args)
389
+ def soap_call(ns1: 'ns1', ns2: 'ns2', batch_size: nil, single_transaction: false, debug: false, errors: [ZuoraAPI::Exceptions::ZuoraAPISessionError, ZuoraAPI::Exceptions::ZuoraAPIError, ZuoraAPI::Exceptions::ZuoraAPIRequestLimit, ZuoraAPI::Exceptions::ZuoraAPILockCompetition], z_session: true, timeout_retry: false, timeout: 120,**keyword_args)
404
390
  tries ||= 2
405
391
  xml = Nokogiri::XML::Builder.new do |xml|
406
392
  xml['SOAP-ENV'].Envelope('xmlns:SOAP-ENV' => "http://schemas.xmlsoap.org/soap/envelope/",
@@ -450,7 +436,7 @@ module ZuoraAPI
450
436
  return output_xml, input_xml, response
451
437
  end
452
438
  end
453
- rescue *ZUORA_API_ERRORS => ex
439
+ rescue ZuoraAPI::Exceptions::ZuoraAPIError, ZuoraAPI::Exceptions::ZuoraAPIRequestLimit, ZuoraAPI::Exceptions::ZuoraAPILockCompetition => ex
454
440
  if errors.include?(ex.class)
455
441
  raise ex
456
442
  else
@@ -472,12 +458,6 @@ module ZuoraAPI
472
458
  else
473
459
  raise ex
474
460
  end
475
- rescue Errno::ECONNRESET => ex
476
- if !(tries -= 1).zero? && ex.message.include?('SSL_connect')
477
- retry
478
- else
479
- raise ex
480
- end
481
461
  rescue => ex
482
462
  raise ex
483
463
  else
@@ -519,102 +499,93 @@ module ZuoraAPI
519
499
  if error.class == String
520
500
  case error
521
501
  when "INVALID_SESSION"
522
- raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{error}::#{message}", response)
502
+ raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{error}::#{message}", body, response.code )
523
503
  when "REQUEST_EXCEEDED_LIMIT"
524
- raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new("#{error}::#{message}", response)
504
+ raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new("#{error}::#{message}", body, response.code)
525
505
  when "LOCK_COMPETITION"
526
- raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("#{error}::#{message}", response)
506
+ raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("#{error}::#{message}", body, response.code)
527
507
  when "BATCH_FAIL_ERROR"
528
508
  if message.include?("optimistic locking failed")
529
- raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("#{error}::#{message}", response)
509
+ raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("#{error}::#{message}", body, response.code)
530
510
  else
531
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{error}::#{message}", response)
511
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{error}::#{message}", body, response.code)
532
512
  end
533
513
  when "TEMPORARY_ERROR"
534
- raise ZuoraAPI::Exceptions::ZuoraAPITemporaryError.new("#{error}::#{message}", response)
535
- when "INVALID_VALUE"
536
- if message.include?("data integrity violation")
537
- raise ZuoraAPI::Exceptions::ZuoraDataIntegrity.new("Data Integrity Violation", response)
538
- else
539
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{error}::#{message}", response)
540
- end
514
+ raise ZuoraAPI::Exceptions::ZuoraAPITemporaryError.new("#{error}::#{message}", body, response.code)
541
515
  else
542
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{error}::#{message}", response) if error.present?
516
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{error}::#{message}", body, response.code) if error.present?
543
517
  end
544
518
  elsif error.class == Array
545
- if error[0].include?("LOCK_COMPETITION") && error.count == 1
546
- raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new(error.group_by {|v| v}.map {|k,v| "(#{v.size}x) - #{k == "::" ? 'UNKNOWN::No error provided' : k}"}.join(', '), response)
547
- else
548
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new(error.group_by {|v| v}.map {|k,v| "(#{v.size}x) - #{k == "::" ? 'UNKNOWN::No error provided' : k}"}.join(', '), response, error, success)
549
- end
519
+ if error[0].include?("LOCK_COMPETITION") && error.count == 1
520
+ raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new(error.group_by {|v| v}.map {|k,v| "(#{v.size}x) - #{k == "::" ? 'UNKNOWN::No error provided' : k}"}.join(', '), body, response.code)
521
+ else
522
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new(error.group_by {|v| v}.map {|k,v| "(#{v.size}x) - #{k == "::" ? 'UNKNOWN::No error provided' : k}"}.join(', '), body, response.code, error, success)
523
+ end
550
524
  end
551
525
  end
552
-
526
+
553
527
  if response.code == 429
554
- 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)
528
+ raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new("The total number of concurrent requests has exceeded the limit allowed by the system. Please resubmit your request later.", body, response.code)
555
529
  end
556
530
 
557
531
  when :JSON
558
- body = body.dig("results").present? ? body["results"] : body if body.class == Hash
559
532
  if body.class == Hash && (!body["success"] || !body["Success"] || response.code != 200)
560
- messages_array = body.fetch("reasons", []).map {|error| error['message']}.compact
561
- messages_array = messages_array.push(body.dig("error", 'message')).compact if body.dig('error').class == Hash
562
- codes_array = body.fetch("reasons", []).map {|error| error['code']}.compact
563
- codes_array = codes_array.push(body.dig("error", 'code')).compact if body.dig('error').class == Hash
533
+ messages_array = (body["reasons"] || []).map {|error| error['message']}.compact
534
+ codes_array = (body["reasons"] || []).map {|error| error['code']}.compact
564
535
 
565
536
  if body['message'] == "No bearer token" && response.code == 400
566
- raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Authentication type is not supported by this Login", response)
537
+ raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new()
567
538
  end
568
539
 
569
540
  if body['errorMessage']
570
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new(body['errorMessage'], response)
541
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new(body['errorMessage'],body,response.code)
571
542
  end
572
543
 
573
544
  if body.dig("reasons").nil? ? false : body.dig("reasons")[0].dig("code") == 90000020
574
- raise ZuoraAPI::Exceptions::BadEntityError.new("#{messages_array.join(', ')}", response)
545
+ raise ZuoraAPI::Exceptions::BadEntityError.new("#{messages_array.join(', ')}", body, response.code)
575
546
  end
576
547
 
577
548
  if body['error'] == 'Unauthorized' && body['status'] = 401
578
- raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{messages_array.join(', ')}", response)
549
+ raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{messages_array.join(', ')}", body, response.code)
579
550
  end
580
551
  #Authentication failed
581
- if (codes_array.map{|code| code.to_s.slice(6,7).to_i}.include?(11) || response.code == 401) && !codes_array.include?(422)
582
- raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{messages_array.join(', ')}", response)
552
+ if codes_array.map{|code| code.to_s.slice(6,7).to_i}.include?(11) || response.code == 401
553
+ raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{messages_array.join(', ')}", body, response.code)
583
554
  end
584
555
 
585
556
  #Zuora REST Create Amendment error #Authentication failed
586
557
  if body["faultcode"].present? && body["faultcode"] == "fns:INVALID_SESSION"
587
- raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{body['faultstring']}", response)
558
+ raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{body['faultstring']}", body, response.code)
588
559
  end
589
560
 
590
561
  #Request exceeded limit
591
562
  if codes_array.map{|code| code.to_s.slice(6,7).to_i}.include?(70)
592
- raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new("#{messages_array.join(', ')}", response)
563
+ raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new("#{messages_array.join(', ')}", body, response.code)
593
564
  end
594
565
 
595
566
  #Locking contention
596
567
  if codes_array.map{|code| code.to_s.slice(6,7).to_i}.include?(50)
597
- raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("#{messages_array.join(', ')}", response)
598
- end
568
+ raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("#{messages_array.join(', ')}", body, response.code)
569
+ end
599
570
 
600
571
  #All Errors catch
601
572
  if codes_array.size > 0
602
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{messages_array.join(', ')}", response)
573
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{messages_array.join(', ')}", body, response.code)
603
574
  end
604
575
 
605
576
  #Zuora REST Query Errors
606
577
  if body["faultcode"].present?
607
578
  case body["faultcode"]
608
579
  when "fns:MALFORMED_QUERY"
609
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{body["faultcode"]}::#{body["faultstring"]}", response)
580
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{body["faultcode"]}::#{body["faultstring"]}", body, response.code)
610
581
  when "fns:REQUEST_EXCEEDED_LIMIT"
611
- raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new("#{body["faultcode"]}::#{body["faultstring"]}", response)
582
+ raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new("#{body["faultcode"]}::#{body["faultstring"]}", body, response.code)
612
583
  when "fns:LOCK_COMPETITION"
613
- raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("#{body["faultcode"]}::#{body["faultstring"]}", response)
584
+ raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("#{body["faultcode"]}::#{body["faultstring"]}", body, response.code)
614
585
  when "INVALID_SESSION"
615
- raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{body["faultcode"]}::#{body["faultstring"]}", response)
586
+ raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{body["faultcode"]}::#{body["faultstring"]}", body, response.code)
616
587
  else
617
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{body["faultcode"]}::#{body["faultstring"]}", response)
588
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{body["faultcode"]}::#{body["faultstring"]}", body, response.code)
618
589
  end
619
590
  end
620
591
 
@@ -623,39 +594,34 @@ module ZuoraAPI
623
594
  (body["Errors"] || []).select { |obj| errors.push(obj["Message"]) }.compact
624
595
  (body["errors"] || []).select { |obj| errors.push(obj["Message"]) }.compact
625
596
  if errors.size > 0
626
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{errors.join(", ")}", response, errors)
597
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{errors.join(", ")}", body, response.code, errors)
627
598
  end
628
599
  end
629
600
  end
630
601
 
631
- #Zuora REST Actions error (Create, Update, Delete, Amend)
602
+ #Zuora REST Actions error (Create, Update, Delete)
632
603
  if body.class == Array
633
604
  all_errors = body.select {|obj| !obj['Success'] || !obj['success'] }.map {|obj| obj['Errors'] || obj['errors'] }.compact
634
605
  all_success = body.select {|obj| obj['Success'] || obj['success']}.compact
635
606
 
636
607
  if all_success.blank? && all_errors.present?
637
608
  error_codes = all_errors.flatten.group_by {|error| error['Code']}.keys.uniq
638
- error_messages = all_errors.flatten.group_by {|error| error['Message']}.keys.uniq
639
- if error_codes.size == 1 || error_messages.size == 1
640
- if error_codes.first == "LOCK_COMPETITION"
641
- raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("Retry Lock Competition", response)
642
- elsif error_messages.first.include?("data integrity violation")
643
- raise ZuoraAPI::Exceptions::ZuoraDataIntegrity.new("Data Integrity Violation", response)
644
- end
609
+ if error_codes.size == 1 && error_codes[0] == "LOCK_COMPETITION"
610
+ raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("Retry Lock Competition", body, response.code)
645
611
  end
646
612
  end
647
613
 
648
614
  if all_errors.size > 0
649
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{all_errors.flatten.group_by {|error| error['Message']}.keys.uniq.join(' ')}", response, all_errors, all_success)
615
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{all_errors.flatten.group_by {|error| error['Message']}.keys.uniq.join(' ')}", body, response.code, all_errors, all_success )
650
616
  end
651
617
  end
652
618
 
653
619
  #All other errors
654
- if ![200,201].include?(response.code)
620
+ if response.code != 200
655
621
  if response.code == 429
656
- 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)
622
+ raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new("The total number of concurrent requests has exceeded the limit allowed by the system. Please resubmit your request later.", body, response.code)
657
623
  else
658
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{response.message}", response)
624
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{response.message}", body, response.code)
659
625
  end
660
626
  end
661
627
  end
@@ -678,7 +644,7 @@ module ZuoraAPI
678
644
  }
679
645
  response = self.rest_call(method: :post, body: params.to_json, url: self.aqua_endpoint("batch-query/"))
680
646
  if(response[0]["id"].nil?)
681
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Error in AQuA Process.", response)
647
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Error in AQuA Process. #{response}")
682
648
  end
683
649
  return getFileById(id: response[0]["id"])
684
650
  end
@@ -691,7 +657,7 @@ module ZuoraAPI
691
657
  response, fullResponse = self.rest_call(method: :get, body: {}, url: self.aqua_endpoint("batch-query/jobs/#{id}"))
692
658
  result = response["batches"][0]["status"]
693
659
  if result == "error"
694
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Aqua Error", response)
660
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Aqua Error: #{response}")
695
661
  break
696
662
  end
697
663
  end
@@ -707,7 +673,7 @@ module ZuoraAPI
707
673
  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"}
708
674
  response = HTTParty.get(url, headers: {"Authorization" => self.get_session(prefix: true, auth_type: :basic)}.merge(headers), :timeout => 120)
709
675
 
710
- raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error.present? ? self.current_error : 'Describe call 401', response) if response.code == 401
676
+ raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error.present? ? self.current_error : 'Describe call 401' ) if response.code == 401
711
677
 
712
678
  output_xml = Nokogiri::XML(response.body)
713
679
  des_hash = Hash.new
@@ -747,12 +713,11 @@ module ZuoraAPI
747
713
  raise ex
748
714
  end
749
715
  rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
750
- if !(tries -= 1).zero? && self.status == 'Active'
751
- Rails.logger.debug("Session expired. Starting new session.")
716
+ if !(tries -= 1).zero?
717
+ Rails.logger.info("Session expired. Starting new session.")
752
718
  self.new_session
753
719
  retry
754
720
  else
755
- Rails.logger.error("Session expired. Starting new session.")
756
721
  raise ex
757
722
  end
758
723
  rescue => ex
@@ -761,7 +726,7 @@ module ZuoraAPI
761
726
  return des_hash
762
727
  end
763
728
 
764
- def rest_call(method: :get, body: nil, headers: {}, url: rest_endpoint("catalog/products?pageSize=4"), debug: false, errors: [ZuoraAPI::Exceptions::ZuoraAPISessionError].concat(ZUORA_API_ERRORS), z_session: true, session_type: :basic, timeout_retry: false, timeout: 120, **keyword_args)
729
+ def rest_call(method: :get, body: nil, headers: {}, url: rest_endpoint("catalog/products?pageSize=4"), debug: false, errors: [ZuoraAPI::Exceptions::ZuoraAPISessionError, ZuoraAPI::Exceptions::ZuoraAPIError, ZuoraAPI::Exceptions::ZuoraAPIRequestLimit, ZuoraAPI::Exceptions::ZuoraAPILockCompetition], z_session: true, session_type: :basic, timeout_retry: false, timeout: 120, **keyword_args)
765
730
  tries ||= 2
766
731
 
767
732
  if self.entity_id.present?
@@ -772,9 +737,9 @@ module ZuoraAPI
772
737
  raise "Method not supported, supported methods include: :get, :post, :put, :delete, :patch, :head, :options" if ![:get, :post, :put, :delete, :patch, :head, :options].include?(method)
773
738
 
774
739
  authentication_headers = z_session ? {"Authorization" => self.get_session(prefix: true, auth_type: session_type) } : {}
775
- modified_headers = {'Content-Type' => "application/json; charset=utf-8"}.merge(authentication_headers).merge(headers)
740
+ headers = {'Content-Type' => "application/json; charset=utf-8"}.merge(headers).merge(authentication_headers)
776
741
 
777
- response = HTTParty::Request.new("Net::HTTP::#{method.to_s.capitalize}".constantize, url, body: body, headers: modified_headers, timeout: timeout).perform
742
+ response = HTTParty::Request.new("Net::HTTP::#{method.to_s.capitalize}".constantize, url, body: body, headers: headers, timeout: timeout).perform
778
743
  Rails.logger.debug("Response Code: #{response.code}") if debug
779
744
  begin
780
745
  output_json = JSON.parse(response.body)
@@ -785,8 +750,8 @@ module ZuoraAPI
785
750
 
786
751
  raise_errors(type: :JSON, body: output_json, response: response)
787
752
  rescue ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError => ex
788
- if self.class.to_s == 'ZuoraAPI::Oauth' && ex.message.include?("Authentication type is not supported by this Login")
789
- self.rest_call(method: method.to_sym, url: url, body: body, debug: debug, errors: errors, z_session: z_session, session_type: :bearer, timeout_retry: timeout_retry, timeout: timeout)
753
+ if self.class.to_s == 'ZuoraAPI::Oauth'
754
+ self.rest_call(method: method.to_sym, url: url, debug: debug, errors: errors, z_session: z_session, session_type: :bearer, timeout_retry: timeout_retry, timeout: timeout)
790
755
  else
791
756
  Rails.logger.debug("Rest Call - Session Bad Auth type")
792
757
  raise ex
@@ -803,7 +768,7 @@ module ZuoraAPI
803
768
  return [output_json, response]
804
769
  end
805
770
  end
806
- rescue *ZUORA_API_ERRORS => ex
771
+ rescue ZuoraAPI::Exceptions::ZuoraAPIError, ZuoraAPI::Exceptions::ZuoraAPIRequestLimit, ZuoraAPI::Exceptions::ZuoraAPILockCompetition => ex
807
772
  if errors.include?(ex.class)
808
773
  raise ex
809
774
  else
@@ -827,12 +792,6 @@ module ZuoraAPI
827
792
  else
828
793
  raise ex
829
794
  end
830
- rescue Errno::ECONNRESET => ex
831
- if !(tries -= 1).zero? && ex.message.include?('SSL_connect')
832
- retry
833
- else
834
- raise ex
835
- end
836
795
  rescue => ex
837
796
  raise ex
838
797
  else
@@ -860,7 +819,7 @@ module ZuoraAPI
860
819
  Rails.logger.debug("Fetch Catalog URL #{url}")
861
820
  output_json, response = self.rest_call(:debug => false, :url => url, :errors => [ZuoraAPI::Exceptions::ZuoraAPISessionError], :timeout_retry => true )
862
821
  if !output_json['success'] =~ (/(true|t|yes|y|1)$/i) || output_json['success'].class != TrueClass
863
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Error Getting Catalog: #{output_json}", response)
822
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Error Getting Catalog: #{output_json}")
864
823
  end
865
824
  output_json["products"].each do |product|
866
825
  catalog_map[product["id"]] = {"productId" => product["id"]}
@@ -897,130 +856,129 @@ module ZuoraAPI
897
856
  uri = URI.parse(url)
898
857
  http = Net::HTTP.new(uri.host, uri.port)
899
858
  http.read_timeout = timeout #Seconds
900
- http.use_ssl = true if !uri.scheme.nil? && uri.scheme.downcase == 'https'
859
+ http.use_ssl = true if uri.scheme.downcase == 'https'
901
860
  if z_session
902
861
  headers = headers.merge({"Authorization" => self.get_session(prefix: true)})
903
862
  headers = headers.merge({"Zuora-Entity-Ids" => self.entity_id}) if !self.entity_id.blank?
904
863
  end
905
864
 
906
865
  response_save = nil
907
- begin
908
- http.request_get(uri.request_uri, headers) do |response|
909
- response_save = response
910
- status_code = response.code if response
911
-
912
- case response
913
- when Net::HTTPNotFound
914
- raise
915
-
916
- when Net::HTTPUnauthorized
917
- if count <= 0
918
- if z_session
919
- raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error)
920
- else
921
- raise
922
- end
923
- end
924
- self.new_session if z_session
925
- return get_file(:url => url, :headers => headers, :count => count - 1, :z_session => z_session, :tempfile => tempfile, :file_path => file_path, :timeout_retries => timeout_retries, :timeout => timeout)
866
+ http.request_get(uri.request_uri, headers) do |response|
867
+ response_save = response
868
+ status_code = response.code if response
926
869
 
927
- when Net::HTTPClientError
928
- raise
870
+ case response
871
+ when Net::HTTPNotFound
872
+ Rails.logger.fatal("404 - Not Found")
873
+ raise
929
874
 
930
- when Net::HTTPOK
931
- headers = {}
932
- response.each_header do |k,v|
933
- headers[k] = v
934
- end
935
- Rails.logger.debug("Headers: #{headers.to_s}")
936
- if output_file_name.present?
937
- file_ending ||= output_file_name.end_with?(".csv.zip") ? ".csv.zip" : File.extname(output_file_name)
938
- filename ||= File.basename(output_file_name, file_ending)
875
+ when Net::HTTPUnauthorized
876
+ if count <= 0
877
+ if z_session
878
+ raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error)
879
+ else
880
+ raise
939
881
  end
882
+ end
883
+ Rails.logger.fatal("Unauthorized: Retry")
884
+ self.new_session if z_session
885
+ return get_file(:url => url, :headers => headers, :count => count - 1, :z_session => z_session, :tempfile => tempfile, :file_path => file_path, :timeout_retries => timeout_retries, :timeout => timeout)
940
886
 
941
- size, export_progress = [0, 0]
942
- encoding, type, full_filename = [nil, nil, nil]
943
- if response.header["Content-Disposition"].present?
944
- case response.header["Content-Disposition"]
945
- when /.*; filename\*=.*/
946
- full_filename ||= /.*; filename\*=(.*)''(.*)/.match(response.header["Content-Disposition"])[2].strip
947
- encoding = /.*; filename\*=(.*)''(.*)/.match(response.header["Content-Disposition"])[1].strip
948
- when /.*; filename=/
949
- full_filename ||= /.*; filename=(.*)/.match(response.header["Content-Disposition"])[1].strip
950
- else
951
- raise "Can't parse Content-Disposition header: #{response.header["Content-Disposition"]}"
952
- end
953
- file_ending ||= full_filename.end_with?(".csv.zip") ? ".csv.zip" : File.extname(full_filename)
954
- filename ||= File.basename(full_filename, file_ending)
955
- end
887
+ when *(CONNECTION_EXCEPTIONS).concat(CONNECTION_READ_EXCEPTIONS)
888
+ Rails.logger.fatal("#{response.class} timeout - retry")
889
+ return get_file(:url => url, :headers => headers, :count => count, :z_session => z_session, :tempfile => tempfile, :file_path => file_path, :timeout_retries => timeout_retries - 1, :timeout => timeout)
956
890
 
957
- #If user supplied a filename use it, else default to content header filename, else default to uri pattern
958
- file_ending ||= uri.path.end_with?(".csv.zip") ? ".csv.zip" : File.extname(uri.path)
959
- filename ||= File.basename(uri.path, file_ending)
960
-
961
- if response.header["Content-Type"].present?
962
- case response.header["Content-Type"]
963
- when /.*;charset=.*/
964
- type = /(.*);charset=(.*)/.match(response.header["Content-Type"])[1]
965
- encoding = /(.*);charset=(.*)/.match(response.header["Content-Type"])[2]
966
- else
967
- type = response.header["Content-Type"]
968
- encoding ||= 'UTF-8'
969
- end
970
- end
891
+ when Net::HTTPClientError
892
+ raise
893
+
894
+ when Net::HTTPOK
895
+ headers = {}
896
+ response.each_header do |k,v|
897
+ headers[k] = v
898
+ end
899
+ Rails.logger.debug("Headers: #{headers.to_s}")
971
900
 
972
- if response.header["Content-Length"].present?
973
- export_size = response.header["Content-Length"].to_i
974
- elsif response.header["ContentLength"].present?
975
- export_size = response.header["ContentLength"].to_i
901
+ if output_file_name.present?
902
+ file_ending ||= output_file_name.end_with?(".csv.zip") ? ".csv.zip" : File.extname(output_file_name)
903
+ filename ||= File.basename(output_file_name, file_ending)
904
+ end
905
+
906
+ size, export_progress = [0, 0]
907
+ encoding, type, full_filename = [nil, nil, nil]
908
+ if response.header["Content-Disposition"].present?
909
+ case response.header["Content-Disposition"]
910
+ when /.*; filename\*=.*/
911
+ full_filename ||= /.*; filename\*=(.*)''(.*)/.match(response.header["Content-Disposition"])[2].strip
912
+ encoding = /.*; filename\*=(.*)''(.*)/.match(response.header["Content-Disposition"])[1].strip
913
+ when /.*; filename=/
914
+ full_filename ||= /.*; filename=(.*)/.match(response.header["Content-Disposition"])[1].strip
915
+ else
916
+ raise "Can't parse Content-Disposition header: #{response.header["Content-Disposition"]}"
976
917
  end
918
+ file_ending ||= full_filename.end_with?(".csv.zip") ? ".csv.zip" : File.extname(full_filename)
919
+ filename ||= File.basename(full_filename, file_ending)
920
+ end
977
921
 
978
- Rails.logger.info("File: #{filename}#{file_ending} #{encoding} #{type} #{export_size}")
922
+ #If user supplied a filename use it, else default to content header filename, else default to uri pattern
923
+ file_ending ||= uri.path.end_with?(".csv.zip") ? ".csv.zip" : File.extname(uri.path)
924
+ filename ||= File.basename(uri.path, file_ending)
979
925
 
980
- file_prefix = add_timestamp ? "#{filename}_#{Time.now.to_i}" : filename
981
- if tempfile
982
- require 'tempfile'
983
- file_handle = ::Tempfile.new([file_prefix, "#{file_ending}"], file_path)
926
+ if response.header["Content-Type"].present?
927
+ case response.header["Content-Type"]
928
+ when /.*;charset=.*/
929
+ type = /(.*);charset=(.*)/.match(response.header["Content-Type"])[1]
930
+ encoding = /(.*);charset=(.*)/.match(response.header["Content-Type"])[2]
984
931
  else
985
- file_handle = File.new(file_path.join("#{file_prefix}#{file_ending}"), "w+")
932
+ type = response.header["Content-Type"]
933
+ encoding ||= 'UTF-8'
986
934
  end
987
- file_handle.binmode
988
-
989
- response.read_body do |chunk|
990
- file_handle << chunk
991
-
992
- if defined?(export_size) && export_size != 0 && export_size.class == Integer
993
- size += chunk.size
994
- new_progress = (size * 100) / export_size
995
- unless new_progress == export_progress
996
- Rails.logger.debug("Login: Export Downloading %s (%3d%%)" % [filename, new_progress])
997
- end
998
- export_progress = new_progress
935
+ end
936
+ Rails.logger.info("File: #{filename}#{file_ending} #{encoding} #{type}")
937
+
938
+ if response.header["Content-Length"].present?
939
+ export_size = response.header["Content-Length"].to_i
940
+ elsif response.header["ContentLength"].present?
941
+ export_size = response.header["ContentLength"].to_i
942
+ end
943
+
944
+ file_prefix = add_timestamp ? "#{filename}_#{Time.now.to_i}" : filename
945
+ if tempfile
946
+ require 'tempfile'
947
+ file_handle = ::Tempfile.new([file_prefix, "#{file_ending}"], file_path)
948
+ else
949
+ file_handle = File.new(file_path.join("#{file_prefix}#{file_ending}"), "w+")
950
+ end
951
+ file_handle.binmode
952
+
953
+ response.read_body do |chunk|
954
+ file_handle << chunk.force_encoding(encoding)
955
+
956
+ if defined?(export_size) && export_size != 0 && export_size.class == Integer
957
+ size += chunk.size
958
+ new_progress = (size * 100) / export_size
959
+ unless new_progress == export_progress
960
+ Rails.logger.debug("Login: Export Downloading %s (%3d%%)" % [filename, new_progress])
999
961
  end
962
+ export_progress = new_progress
1000
963
  end
964
+ end
1001
965
 
1002
- file_handle.close
1003
- Rails.logger.debug("Filepath: #{file_handle.path} Size: #{File.size(file_handle.path).to_f/1000000} mb")
966
+ file_handle.close
967
+ Rails.logger.debug("Filepath: #{file_handle.path} Size: #{File.size(file_handle.path).to_f/1000000} mb")
1004
968
 
1005
- return file_handle
1006
- end
1007
- end
1008
- rescue *(CONNECTION_EXCEPTIONS).concat(CONNECTION_READ_EXCEPTIONS).concat([Net::HTTPBadResponse]) => e
1009
- sleep(5)
1010
- if (timeout_retries -= 1) >= 0
1011
- Rails.logger.warn("Download Failed: #{e.class} : #{e.message}")
1012
- retry
1013
- else
1014
- raise
969
+ return file_handle
1015
970
  end
1016
971
  end
1017
- rescue => ex
1018
- Rails.logger.fatal(ex)
972
+ rescue Exception => e
973
+ Rails.logger.fatal("Download Failed: #{response_save} - #{e.class} : #{e.message}")
974
+ Rails.logger.fatal("Download Failed: #{e.backtrace.join("\n")}")
1019
975
  raise
1020
976
  end
1021
977
  end
1022
978
 
1023
979
  def getDataSourceExport(query, extract: true, encrypted: false, zip: true)
980
+ Rails.logger.debug("Build export")
981
+ Rails.logger.debug("#{query}")
1024
982
  request = Nokogiri::XML::Builder.new do |xml|
1025
983
  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
1026
984
  xml['SOAP-ENV'].Header do
@@ -1075,6 +1033,7 @@ module ZuoraAPI
1075
1033
  end
1076
1034
 
1077
1035
  file_id = output_xml.xpath('//ns2:FileId', 'ns2' =>'http://object.api.zuora.com/').text
1036
+ Rails.logger.debug('=====> Export finished')
1078
1037
  export_file = get_file(:url => self.fileURL(file_id))
1079
1038
  export_file_path = export_file.path
1080
1039
  Rails.logger.debug("=====> Export path #{export_file.path}")
@@ -1093,6 +1052,7 @@ module ZuoraAPI
1093
1052
  end
1094
1053
 
1095
1054
  def query(query, parse = false)
1055
+ Rails.logger.debug("Querying Zuora for #{query}")
1096
1056
  output_xml, input_xml = self.soap_call({:debug => false, :timeout_retry => true}) do |xml|
1097
1057
  xml['ns1'].query do
1098
1058
  xml['ns1'].queryString query
@@ -1,17 +1,15 @@
1
1
  module ZuoraAPI
2
2
  class Basic < Login
3
- attr_accessor :username, :password, :session
4
- def initialize(username: nil, password: nil, session: nil, **keyword_args)
5
- self.username = username
6
- self.password = password
7
- self.current_session = session
8
- raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Request Basic Login but either 'Username' or 'Password' were not passed.") if self.current_session.blank? && (self.password.blank? && self.username.blank?)
3
+ attr_accessor :username, :password
4
+ def initialize(username: nil, password: nil, **keyword_args)
5
+ @username = username
6
+ @password = password
9
7
  super
10
8
  end
11
9
 
12
- def new_session(auth_type: :basic, debug: false)
10
+ def new_session( auth_type: :basic, debug: false)
13
11
  raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Basic Login, does not support Authentication of Type: #{auth_type}") if auth_type != :basic
14
- raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Request Basic Login but either 'Username' or 'Password' were not passed.") if (self.password.blank? && self.username.blank?)
12
+ raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Basic Login requires username and password to be set.") if auth_type == :basic && (self.password.blank? && self.username.blank?)
15
13
 
16
14
  tries ||= 2
17
15
  request = Nokogiri::XML::Builder.new do |xml|
@@ -29,16 +27,16 @@ module ZuoraAPI
29
27
 
30
28
  input_xml = Nokogiri::XML(request.to_xml(:save_with => XML_SAVE_OPTIONS).strip)
31
29
  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
30
+ Rails.logger.debug('Connect') {"Request Code: #{@response_query.code} SOAP XML: #{input_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}"} if debug
33
31
 
34
- response_query = HTTParty.post(self.url,:body => request.to_xml(:save_with => XML_SAVE_OPTIONS).strip, :headers => {'Content-Type' => "text/xml; charset=utf-8"}, :timeout => 10)
35
- output_xml = Nokogiri::XML(response_query.body)
36
- Rails.logger.debug('Connect') {"Response Code: #{response_query.code} SOAP XML: #{output_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}"} if debug
32
+ @response_query = HTTParty.post(self.url,:body => request.to_xml(:save_with => XML_SAVE_OPTIONS).strip, :headers => {'Content-Type' => "text/xml; charset=utf-8"}, :timeout => 10)
33
+ @output_xml = Nokogiri::XML(@response_query.body)
34
+ Rails.logger.debug('Connect') {"Response Code: #{@response_query.code} SOAP XML: #{@output_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}"} if debug
37
35
 
38
- if !response_query.success?
36
+ if !@response_query.success?
39
37
  self.current_session = nil
40
- if output_xml.namespaces.size > 0 && output_xml.xpath('//soapenv:Fault').size > 0
41
- self.current_error = output_xml.xpath('//fns:FaultMessage', 'fns' =>'http://fault.api.zuora.com/').text
38
+ if @output_xml.namespaces.size > 0 && @output_xml.xpath('//soapenv:Fault').size > 0
39
+ self.current_error = @output_xml.xpath('//fns:FaultMessage', 'fns' =>'http://fault.api.zuora.com/').text
42
40
  if self.current_error.include?('deactivated')
43
41
  self.status = 'Deactivated'
44
42
  self.current_error = 'Deactivated user login, please check with Zuora tenant administrator'
@@ -77,20 +75,19 @@ module ZuoraAPI
77
75
  self.errors[:base] = self.current_error
78
76
  else
79
77
  self.status = 'Unknown'
80
- self.current_error = output_xml.xpath('//faultstring').text if self.current_error.blank?
78
+ self.current_error = @output_xml.xpath('//faultstring').text if self.current_error.blank?
81
79
  self.errors[:base] = self.current_error
82
80
  end
83
81
 
84
82
  else
85
83
  self.status = 'Unknown'
86
- self.current_error = output_xml.xpath('//faultstring').text if self.current_error.blank?
84
+ self.current_error = @output_xml.xpath('//faultstring').text if self.current_error.blank?
87
85
  self.errors[:base] = self.current_error
88
86
  end
89
87
  else
90
88
  #Username & password combo
91
- retrieved_session = output_xml.xpath('//ns1:Session', 'ns1' =>'http://api.zuora.com/').text
92
- raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("No session found for api call.", response_query) if retrieved_session.blank?
93
- self.status = 'Active'
89
+ retrieved_session = @output_xml.xpath('//ns1:Session', 'ns1' =>'http://api.zuora.com/').text
90
+ raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("No session found for api call.") if retrieved_session.blank?
94
91
  self.current_session = retrieved_session
95
92
  end
96
93
  return self.status
@@ -104,12 +101,6 @@ module ZuoraAPI
104
101
  self.status = 'Timeout'
105
102
  return self.status
106
103
  end
107
- rescue EOFError
108
- if self.url.match?(/.*services\d{1,}.zuora.com*/)
109
- self.current_error = "Services tenant '#{self.url.scan(/.*\/\/(services\d{1,}).zuora.com*/).last.first}' is no longer available."
110
- self.status = 'Not Available'
111
- return self.status
112
- end
113
104
  end
114
105
  end
115
106
  end
@@ -5,9 +5,9 @@ module ZuoraAPI
5
5
  def initialize(oauth_client_id: nil, oauth_secret: nil, bearer_token: nil, oauth_session_expires_at: nil, **keyword_args)
6
6
  self.oauth_client_id = oauth_client_id
7
7
  self.oauth_secret = oauth_secret
8
- self.bearer_token = bearer_token
9
- self.oauth_session_expires_at = oauth_session_expires_at
10
- raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Request Oauth Login but either 'Oauth Client Id' or 'Oauth Secret' were not passed") if self.bearer_token.blank? && (self.oauth_client_id.blank? || self.oauth_secret.blank?)
8
+ self.bearer_token = bearer_token if !bearer_token.blank?
9
+ self.oauth_session_expires_at = oauth_session_expires_at if !oauth_session_expires_at.blank?
10
+ raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Request Oauth Login but either 'Oauth Client Id' or 'Oauth Secret' were not passed") if @oauth_client_id.blank? || @oauth_secret.blank?
11
11
  super
12
12
  end
13
13
 
@@ -16,10 +16,10 @@ module ZuoraAPI
16
16
  get_bearer_token()
17
17
  elsif auth_type == :basic
18
18
  get_bearer_token() if self.oauth_expired?
19
- get_z_session() if self.status == 'Active'
19
+ get_z_session()
20
20
  else
21
21
  get_bearer_token()
22
- get_z_session() if self.status == 'Active'
22
+ get_z_session()
23
23
  end
24
24
  return self.status
25
25
  end
@@ -66,8 +66,6 @@ module ZuoraAPI
66
66
 
67
67
  def get_bearer_token
68
68
  tries ||= 2
69
- 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?
70
-
71
69
  output_json, response = self.rest_call(:method => :post,
72
70
  :url => self.rest_endpoint.chomp('v1/').concat("oauth/token"),
73
71
  :z_session => false,
@@ -89,7 +87,11 @@ module ZuoraAPI
89
87
  self.status = 'Invalid Login'
90
88
  return self.status
91
89
  rescue ZuoraAPI::Exceptions::ZuoraAPIError, ZuoraAPI::Exceptions::ZuoraAPIRequestLimit, ZuoraAPI::Exceptions::ZuoraAPILockCompetition => ex
92
- raise ex
90
+ if errors.include?(ex.class)
91
+ raise ex
92
+ else
93
+ return [output_json, response]
94
+ end
93
95
  rescue *(CONNECTION_EXCEPTIONS).concat(CONNECTION_READ_EXCEPTIONS) => ex
94
96
  if !(tries -= 1).zero?
95
97
  Rails.logger.info {"#{ex.class} Timed out will retry after 5 seconds"}
@@ -1,3 +1,3 @@
1
1
  module ZuoraAPI
2
- VERSION = "1.6.54"
2
+ VERSION = "1.6.251"
3
3
  end
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.6.54
4
+ version: 1.6.251
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: 2019-07-29 00:00:00.000000000 Z
11
+ date: 2019-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -186,7 +186,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
186
186
  - !ruby/object:Gem::Version
187
187
  version: '0'
188
188
  requirements: []
189
- rubygems_version: 3.0.3
189
+ rubyforge_project:
190
+ rubygems_version: 2.6.8
190
191
  signing_key:
191
192
  specification_version: 4
192
193
  summary: Gem that provides easy integration to Zuora