zuora_api 1.6.54 → 1.6.251

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 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