zuora_api 1.7.7 → 1.7.08

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.
@@ -5,7 +5,7 @@ require 'zuora_api/exceptions'
5
5
 
6
6
  module ZuoraAPI
7
7
  class Login
8
- ENVIRONMENTS = [TEST = 'Test', SANDBOX = 'Sandbox', PRODUCTION = 'Production', PREFORMANCE = 'Preformance', SERVICES = 'Services', UNKNOWN = 'Unknown', STAGING = 'Staging' ]
8
+ ENVIRONMENTS = [SANDBOX = 'Sandbox', PRODUCTION = 'Production', PREFORMANCE = 'Preformance', SERVICES = 'Services', UNKNOWN = 'Unknown', STAGING = 'Staging' ]
9
9
  REGIONS = [EU = 'EU', US = 'US', NA = 'NA' ]
10
10
  MIN_Endpoint = '96.0'
11
11
  XML_SAVE_OPTIONS = Nokogiri::XML::Node::SaveOptions::AS_XML | Nokogiri::XML::Node::SaveOptions::NO_DECLARATION
@@ -16,8 +16,7 @@ module ZuoraAPI
16
16
  Errno::ECONNREFUSED,
17
17
  SocketError,
18
18
  Errno::EHOSTUNREACH,
19
- Errno::EADDRNOTAVAIL,
20
- Errno::ETIMEDOUT,
19
+ Errno::EADDRNOTAVAIL
21
20
  ].freeze
22
21
 
23
22
  CONNECTION_READ_EXCEPTIONS = [
@@ -31,17 +30,7 @@ module ZuoraAPI
31
30
  ZuoraAPI::Exceptions::ZuoraAPIRequestLimit,
32
31
  ZuoraAPI::Exceptions::ZuoraAPILockCompetition,
33
32
  ZuoraAPI::Exceptions::ZuoraAPITemporaryError,
34
- ZuoraAPI::Exceptions::ZuoraDataIntegrity,
35
- ZuoraAPI::Exceptions::ZuoraAPIInternalServerError,
36
- ZuoraAPI::Exceptions::ZuoraUnexpectedError,
37
- ZuoraAPI::Exceptions::ZuoraAPIUnkownError
38
- ].freeze
39
-
40
- ZUORA_SERVER_ERRORS = [
41
- ZuoraAPI::Exceptions::ZuoraAPIInternalServerError,
42
- ZuoraAPI::Exceptions::ZuoraAPIConnectionTimeout,
43
- ZuoraAPI::Exceptions::ZuoraAPIReadTimeout,
44
- ZuoraAPI::Exceptions::ZuoraUnexpectedError
33
+ ZuoraAPI::Exceptions::ZuoraDataIntegrity
45
34
  ].freeze
46
35
 
47
36
  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
@@ -72,12 +61,27 @@ module ZuoraAPI
72
61
 
73
62
  def get_identity(cookies)
74
63
  zsession = cookies["ZSession"]
64
+ zconnect_accesstoken = get_zconnect_accesstoken(cookies)
75
65
  begin
76
66
  if !zsession.blank?
77
67
  response = HTTParty.get("https://#{self.hostname}/apps/v1/identity", :headers => {'Cookie' => "ZSession=#{zsession}", 'Content-Type' => 'application/json'})
78
68
  output_json = JSON.parse(response.body)
69
+ elsif zconnect_accesstoken.present?
70
+ begin
71
+ code = zconnect_accesstoken.split("#!").last
72
+ encrypted_token, tenant_id = Base64.decode64(code).split(":")
73
+ body = {'token' => encrypted_token}.to_json
74
+ rescue => ex
75
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Invalid ZConnect Cookie")
76
+ end
77
+ response = HTTParty.post("https://#{self.hostname}/apps/zconnectsession/identity", :body => body, :headers => { 'Content-Type' => 'application/json' })
78
+ output_json = JSON.parse(response.body)
79
79
  else
80
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present")
80
+ if zconnect_accesstoken.blank? && cookies.keys.any? { |x| x.include? "ZConnect"}
81
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZConnect cookie present matching #{self.hostname}")
82
+ else
83
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present")
84
+ end
81
85
  end
82
86
  rescue JSON::ParserError => ex
83
87
  output_json = {}
@@ -88,12 +92,20 @@ module ZuoraAPI
88
92
 
89
93
  def get_full_nav(cookies)
90
94
  zsession = cookies["ZSession"]
95
+ zconnect_accesstoken = get_zconnect_accesstoken(cookies)
91
96
  begin
92
97
  if zsession.present?
93
98
  response = HTTParty.get("https://#{self.hostname}/apps/v1/navigation", :headers => {'Cookie' => "ZSession=#{zsession}", 'Content-Type' => 'application/json'})
94
99
  output_json = JSON.parse(response.body)
100
+ elsif zconnect_accesstoken.present?
101
+ response = HTTParty.get("https://#{self.hostname}/apps/zconnectsession/navigation", :headers => {'Cookie' => "#{self.zconnect_provider}=#{zconnect_accesstoken}",'Content-Type' => 'application/json'})
102
+ output_json = JSON.parse(response.body)
95
103
  else
96
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present")
104
+ if zconnect_accesstoken.blank? && cookies.keys.any? { |x| x.include? "ZConnect"}
105
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZConnect cookie present matching #{self.hostname}")
106
+ else
107
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present")
108
+ end
97
109
  end
98
110
  rescue JSON::ParserError => ex
99
111
  output_json = {}
@@ -104,12 +116,20 @@ module ZuoraAPI
104
116
 
105
117
  def set_nav(state, cookies)
106
118
  zsession = cookies["ZSession"]
119
+ zconnect_accesstoken = get_zconnect_accesstoken(cookies)
107
120
  begin
108
121
  if !zsession.blank?
109
122
  response = HTTParty.put("https://#{self.hostname}/apps/v1/preference/navigation", :body => state.to_json, :headers => {'Cookie' => "ZSession=#{zsession}", 'Content-Type' => 'application/json'})
110
123
  output_json = JSON.parse(response.body)
124
+ elsif !zconnect_accesstoken.blank?
125
+ response = HTTParty.post("https://#{self.hostname}/apps/zconnectsession/navigationstate", :body => state.to_json, :headers => {'Cookie' => "#{self.zconnect_provider}=#{zconnect_accesstoken}", 'Content-Type' => 'application/json'})
126
+ output_json = JSON.parse(response.body)
111
127
  else
112
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present")
128
+ if zconnect_accesstoken.blank? && cookies.keys.any? { |x| x.include? "ZConnect"}
129
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZConnect cookie present matching #{self.hostname}")
130
+ else
131
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present")
132
+ end
113
133
  end
114
134
  rescue JSON::ParserError => ex
115
135
  output_json = {}
@@ -120,12 +140,20 @@ module ZuoraAPI
120
140
 
121
141
  def refresh_nav(cookies)
122
142
  zsession = cookies["ZSession"]
143
+ zconnect_accesstoken = get_zconnect_accesstoken(cookies)
123
144
  begin
124
145
  if !zsession.blank?
125
146
  response = HTTParty.post("https://#{self.hostname}/apps/v1/navigation/fetch", :headers => {'Cookie' => "ZSession=#{zsession}", 'Content-Type' => 'application/json'})
126
147
  output_json = JSON.parse(response.body)
148
+ elsif !zconnect_accesstoken.blank?
149
+ response = HTTParty.post("https://#{self.hostname}/apps/zconnectsession/refresh-navbarcache", :headers => {'Cookie' => "#{self.zconnect_provider}=#{zconnect_accesstoken}", 'Content-Type' => 'application/json'})
150
+ output_json = JSON.parse(response.body)
127
151
  else
128
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present")
152
+ if zconnect_accesstoken.blank? && cookies.keys.any? { |x| x.include? "ZConnect"}
153
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZConnect cookie present matching #{self.hostname}")
154
+ else
155
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present")
156
+ end
129
157
  end
130
158
  rescue JSON::ParserError => ex
131
159
  output_json = {}
@@ -134,21 +162,27 @@ module ZuoraAPI
134
162
  return output_json
135
163
  end
136
164
 
165
+ def get_zconnect_accesstoken(cookies)
166
+ accesstoken = nil
167
+ self.update_zconnect_provider
168
+ if !cookies[self.zconnect_provider].nil? && !cookies[self.zconnect_provider].empty?
169
+ accesstoken = cookies[self.zconnect_provider]
170
+ end
171
+ return accesstoken
172
+ end
173
+
137
174
  def reporting_url(path)
138
175
  map = {"US" => {"Sandbox" => "https://zconnectsandbox.zuora.com/api/rest/v1/",
139
176
  "Production" => "https://zconnect.zuora.com/api/rest/v1/",
140
- "Test" => "https://reporting-sbx.zan.0001.sbx.auw2.zuora.com/api/rest/v1/",
141
- "Staging" => "https://reporting-stg11.zan.svc.auw2.zuora.com/api/rest/v1/",
142
- "Performance" => "https://zconnectpt1.zuora.com/api/rest/v1/",
143
- "Services" => "https://reporting-svc08.svc.auw2.zuora.com/api/rest/v1/"},
177
+ "Services"=> ""},
144
178
  "EU" => {"Sandbox" => "https://zconnect.sandbox.eu.zuora.com/api/rest/v1/",
145
179
  "Production" => "https://zconnect.eu.zuora.com/api/rest/v1/",
146
- "Services"=> "https://reporting-sbx0000.sbx.aec1.zuora.com/api/rest/v1/"},
180
+ "Services"=> ""},
147
181
  "NA" => {"Sandbox" => "https://zconnect.sandbox.na.zuora.com/api/rest/v1/",
148
182
  "Production" => "https://zconnect.na.zuora.com/api/rest/v1/",
149
183
  "Services"=> ""}
150
184
  }
151
- return map[self.region][self.environment].insert(-1, path)
185
+ return map[zuora_client.region][zuora_client.environment].insert(-1, path)
152
186
  end
153
187
 
154
188
  # There are two ways to call this method. The first way is best.
@@ -198,7 +232,7 @@ module ZuoraAPI
198
232
  end
199
233
 
200
234
  def self.environments
201
- %w(Sandbox Production Services Performance Staging Test)
235
+ %w(Sandbox Production Services Performance Staging)
202
236
  end
203
237
 
204
238
  def self.regions
@@ -210,13 +244,11 @@ module ZuoraAPI
210
244
  "Production" => "https://www.zuora.com/apps/services/a/",
211
245
  "Performance" => "https://pt1.zuora.com/apps/services/a/",
212
246
  "Services" => "https://services347.zuora.com/apps/services/a/",
213
- "Staging" => "https://staging2.zuora.com/apps/services/a/",
214
- "Test" => "https://test.zuora.com/apps/services/a/"},
247
+ "Staging" => "https://staging2.zuora.com/apps/services/a/"},
215
248
  "EU" => {"Sandbox" => "https://sandbox.eu.zuora.com/apps/services/a/",
216
249
  "Production" => "https://eu.zuora.com/apps/services/a/",
217
250
  "Performance" => "https://pt1.eu.zuora.com/apps/services/a/",
218
- "Services" => "https://services347.eu.zuora.com/apps/services/a/",
219
- "Test" => "https://test.eu.zuora.com/apps/services/a/"},
251
+ "Services" => "https://services347.eu.zuora.com/apps/services/a/"},
220
252
  "NA" => {"Sandbox" => "https://sandbox.na.zuora.com/apps/services/a/",
221
253
  "Production" => "https://na.zuora.com/apps/services/a/",
222
254
  "Performance" => "https://pt1.na.zuora.com/apps/services/a/",
@@ -253,18 +285,15 @@ module ZuoraAPI
253
285
 
254
286
  def update_environment
255
287
  if !self.url.blank?
256
- case self.hostname
257
- when /(?<=\.|\/|-|^)(apisandbox|sandbox)(?=\.|\/|-|$)/
288
+ if /(?<=\.|\/|-|^)(apisandbox|sandbox)(?=\.|\/|-|$)/ === self.hostname
258
289
  self.environment = 'Sandbox'
259
- when /(?<=\.|\/|^)(service[\d]*|services[\d]*|ep-edge)(?=\.|\/|$)/
290
+ elsif /(?<=\.|\/|^)(service[\d]*|services[\d]*|ep-edge)(?=\.|\/|$)/ === self.hostname
260
291
  self.environment = 'Services'
261
- when /(?<=\.|\/|-|^)(pt[\d]*)(?=\.|\/|-|$)/
292
+ elsif /(?<=\.|\/|-|^)(pt[\d]*)(?=\.|\/|-|$)/ === self.hostname
262
293
  self.environment = 'Performance'
263
- when /(?<=\.|\/|^)(staging1|staging2|stg)(?=\.|\/|$)/
294
+ elsif /(?<=\.|\/|^)(staging1|staging2|stg)(?=\.|\/|$)/ === self.hostname
264
295
  self.environment = 'Staging'
265
- when /(?<=\.|\/|^)(test)(?=\.|\/|$)/
266
- self.environment = 'Test'
267
- when /(?<=\.|\/|^)(www|api)(?=\.|\/|$)/, /(^|tls10\.|origin-www\.|zforsf\.|eu\.|na\.)(zuora\.com)/
296
+ elsif is_prod_env
268
297
  self.environment = 'Production'
269
298
  else
270
299
  self.environment = 'Unknown'
@@ -274,14 +303,25 @@ module ZuoraAPI
274
303
  end
275
304
  end
276
305
 
306
+ def is_prod_env
307
+ is_prod = false
308
+ www_or_api = /(?<=\.|\/|^)(www|api)(?=\.|\/|$)/ === self.hostname
309
+ host_prefix_match = /(^|tls10\.|origin-www\.|zforsf\.|eu\.|na\.)(zuora\.com)/ === self.hostname
310
+ if www_or_api || host_prefix_match
311
+ is_prod = true
312
+ end
313
+ return is_prod
314
+ end
315
+
277
316
  def update_zconnect_provider
278
317
  region = update_region
279
318
  environment = update_environment
280
- mappings = {"US" => {"Sandbox" => "ZConnectSbx", "Services" => "ZConnectSvcUS", "Production" => "ZConnectProd", "Performance" => "ZConnectPT1", "Test" => "ZConnectTest", "Staging" => "ZConnectQA", "KubeSTG" => "ZConnectDev", "KubeDEV" => "ZConnectDev", "KubePROD" => "ZConnectDev"},
281
- "NA" => {"Sandbox" => "ZConnectSbxNA", "Services" => "ZConnectSvcNA", "Production" => "ZConnectProdNA", "Performance" => "ZConnectPT1NA"},
282
- "EU" => {"Sandbox" => "ZConnectSbxEU", "Services" => "ZConnectSvcEU", "Production" => "ZConnectProdEU", "Performance" => "ZConnectPT1EU", "Test" => "ZConnectTest"},
319
+ mappings = {"US" => {"Sandbox" => "ZConnectSbx", "KubeSTG" => "ZConnectDev", "KubeDEV" => "ZConnectDev", "KubePROD" => "ZConnectDev", "Services" => "ZConnectQA", "Production" => "ZConnectProd", "Performance" => "ZConnectPT1", "Staging" => "ZConnectQA"},
320
+ "NA" => {"Sandbox" => "ZConnectSbxNA", "Services" => "ZConnectQANA", "Production" => "ZConnectProdNA", "Performance" => "ZConnectPT1NA"},
321
+ "EU" => {"Sandbox" => "ZConnectSbxEU", "Services" => "ZConnectQAEU", "Production" => "ZConnectProdEU", "Performance" => "ZConnectPT1EU"},
283
322
  "Unknown" => {"Unknown" => "Unknown"}}
284
323
  self.zconnect_provider = mappings[region][environment]
324
+ # raise "Can't find ZConnect Provider for #{region} region and #{environment} environment" if self.zconnect_provider.nil?
285
325
  end
286
326
 
287
327
  def aqua_endpoint(url="")
@@ -294,35 +334,45 @@ module ZuoraAPI
294
334
  return "#{url_slash_apps_slash}api/#{url}"
295
335
  end
296
336
 
297
- def rest_endpoint(url="", domain=true, prefix='/v1/')
337
+ def rest_endpoint(url="")
298
338
  update_environment
299
339
  endpoint = url
300
- url_postfix = {"US" => ".", "EU" => ".eu.", "NA" => ".na."}[self.region]
301
-
340
+
302
341
  case self.environment
303
- when 'Test'
304
- endpoint = "https://rest.test#{url_postfix}zuora.com"
305
342
  when 'Sandbox'
306
- endpoint = "https://rest.sandbox#{url_postfix}zuora.com"
307
- endpoint = "https://rest.apisandbox.zuora.com" if self.region == "US"
343
+ case self.region
344
+ when 'US'
345
+ endpoint = "https://rest.apisandbox.zuora.com/v1/".concat(url)
346
+ when 'EU'
347
+ endpoint = "https://rest.sandbox.eu.zuora.com/v1/".concat(url)
348
+ when 'NA'
349
+ endpoint = "https://rest.sandbox.na.zuora.com/v1/".concat(url)
350
+ end
308
351
  when 'Production'
309
- endpoint = "https://rest#{url_postfix}zuora.com"
352
+ case self.region
353
+ when 'US'
354
+ endpoint = "https://rest.zuora.com/v1/".concat(url)
355
+ when 'EU'
356
+ endpoint = "https://rest.eu.zuora.com/v1/".concat(url)
357
+ when 'NA'
358
+ endpoint = "https://rest.na.zuora.com/v1/".concat(url)
359
+ end
310
360
  when 'Performance'
311
- endpoint = "https://rest.pt1.zuora.com"
361
+ endpoint = "https://rest.pt1.zuora.com/v1/".concat(url)
312
362
  when 'Services'
313
363
  https = /https:\/\/|http:\/\//.match(self.url)[0]
314
364
  host = self.hostname
315
- endpoint = "#{https}rest#{host}"
365
+ endpoint = "#{https}rest#{host}/v1/#{url}"
316
366
  when 'Staging'
317
- endpoint = "https://rest-staging2.zuora.com"
367
+ endpoint = "https://rest-staging2.zuora.com/v1/".concat(url)
318
368
  when 'Unknown'
319
369
  raise "Environment unknown, returning passed in parameter unaltered"
320
370
  end
321
- return domain ? endpoint.concat(prefix).concat(url) : prefix.concat(url)
371
+ return endpoint
322
372
  end
323
373
 
324
374
  def rest_domain
325
- return URI(self.rest_endpoint).host
375
+ return URI(self.rest_endpoint).host
326
376
  end
327
377
 
328
378
  def fileURL(url="")
@@ -333,10 +383,10 @@ module ZuoraAPI
333
383
  return self.wsdl_number > 68 ? '%Y-%m-%d' : '%Y-%m-%dT%H:%M:%S'
334
384
  end
335
385
 
336
- def new_session(auth_type: :basic, debug: false, zuora_track_id: nil)
386
+ def new_session(auth_type: :basic, debug: false)
337
387
  end
338
388
 
339
- def get_session(prefix: false, auth_type: :basic, zuora_track_id: nil)
389
+ def get_session(prefix: false, auth_type: :basic)
340
390
  Rails.logger.debug("Get session for #{auth_type} - #{self.class.to_s}") if Rails.env.to_s == 'development'
341
391
  case auth_type
342
392
  when :basic
@@ -344,13 +394,13 @@ module ZuoraAPI
344
394
  case self.class.to_s
345
395
  when 'ZuoraAPI::Oauth'
346
396
  if self.bearer_token.blank? || self.oauth_expired?
347
- self.new_session(auth_type: :bearer, zuora_track_id: zuora_track_id)
397
+ self.new_session(auth_type: :bearer)
348
398
  end
349
- self.get_z_session(zuora_track_id: zuora_track_id) if self.status == 'Active'
399
+ self.get_z_session if self.status == 'Active'
350
400
  when 'ZuoraAPI::Basic'
351
- self.new_session(auth_type: :basic, zuora_track_id: zuora_track_id)
401
+ self.new_session(auth_type: :basic)
352
402
  else
353
- self.new_session(auth_type: :basic, zuora_track_id: zuora_track_id)
403
+ raise "No Zuora Login Specified"
354
404
  end
355
405
  end
356
406
  raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error) if self.status != 'Active'
@@ -359,33 +409,17 @@ module ZuoraAPI
359
409
  case self.class.to_s
360
410
  when 'ZuoraAPI::Oauth'
361
411
  if self.bearer_token.blank? || self.oauth_expired?
362
- self.new_session(auth_type: :bearer, zuora_track_id: zuora_track_id)
412
+ self.new_session(auth_type: :bearer)
363
413
  end
364
414
  when 'ZuoraAPI::Basic'
365
415
  raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Basic Login, does not support Authentication of Type: #{auth_type}")
366
- else
367
- raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Unknown Login, does not support Authentication of Type: #{auth_type}")
368
416
  end
369
-
370
417
  raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error) if self.status != 'Active'
371
418
  return prefix ? "Bearer #{self.bearer_token}" : self.bearer_token.to_s
372
419
  end
373
420
  end
374
421
 
375
- def soap_call(
376
- ns1: 'ns1',
377
- ns2: 'ns2',
378
- batch_size: nil,
379
- single_transaction: false,
380
- debug: false,
381
- zuora_track_id: nil,
382
- errors: [ZuoraAPI::Exceptions::ZuoraAPISessionError].concat(ZUORA_API_ERRORS),
383
- z_session: true,
384
- timeout_retry: false,
385
- timeout: 120,
386
- timeout_sleep_interval: self.timeout_sleep,
387
- output_exception_messages: true,
388
- **keyword_args)
422
+ 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
423
  tries ||= 2
390
424
  xml = Nokogiri::XML::Builder.new do |xml|
391
425
  xml['SOAP-ENV'].Envelope('xmlns:SOAP-ENV' => "http://schemas.xmlsoap.org/soap/envelope/",
@@ -395,7 +429,7 @@ module ZuoraAPI
395
429
  "xmlns:#{ns1}" => "http://api.zuora.com/") do
396
430
  xml['SOAP-ENV'].Header do
397
431
  xml["#{ns1}"].SessionHeader do
398
- xml["#{ns1}"].session self.get_session(prefix: false, auth_type: :basic, zuora_track_id: zuora_track_id)
432
+ xml["#{ns1}"].session self.get_session(prefix: false, auth_type: :basic)
399
433
  end
400
434
  if single_transaction
401
435
  xml["#{ns1}"].CallOptions do
@@ -418,34 +452,15 @@ module ZuoraAPI
418
452
  input_xml.xpath('//ns1:session', 'ns1' =>'http://api.zuora.com/').children.remove
419
453
  Rails.logger.debug("Request SOAP XML: #{input_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}") if debug
420
454
 
421
- headers = { 'Content-Type' => "text/xml; charset=utf-8", 'Accept' => 'text/xml'}
422
- headers['Zuora-Track-Id'] = zuora_track_id if zuora_track_id.present?
423
-
424
- request = HTTParty::Request.new(
425
- Net::HTTP::Post,
426
- self.url,
427
- body: xml.doc.to_xml(:save_with => XML_SAVE_OPTIONS).strip,
428
- headers: headers,
429
- timeout: timeout,
430
- )
431
-
432
- response = request.perform
433
-
455
+ response = HTTParty.post(self.url,:body => xml.doc.to_xml(:save_with => XML_SAVE_OPTIONS).strip, :headers => {'Content-Type' => "text/xml; charset=utf-8"}, :timeout => timeout)
434
456
  output_xml = Nokogiri::XML(response.body)
435
457
  Rails.logger.debug("Response SOAP XML: #{output_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}") if debug
436
458
 
437
459
  raise_errors(type: :SOAP, body: output_xml, response: response)
438
460
  rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
439
- if !tries.zero? && z_session
440
- tries -= 1
461
+ if !(tries -= 1).zero? && z_session
441
462
  Rails.logger.debug("SOAP Call - Session Invalid")
442
-
443
- begin
444
- self.new_session(auth_type: :basic, zuora_track_id: zuora_track_id)
445
- rescue *ZUORA_API_ERRORS => ex
446
- return output_xml, input_xml, ex.response
447
- end
448
-
463
+ self.new_session(auth_type: :basic)
449
464
  retry
450
465
  else
451
466
  if errors.include?(ex.class)
@@ -458,45 +473,30 @@ module ZuoraAPI
458
473
  if errors.include?(ex.class)
459
474
  raise ex
460
475
  else
461
- response = ex.response unless response
462
476
  return output_xml, input_xml, response
463
477
  end
464
478
  rescue *CONNECTION_EXCEPTIONS => ex
465
- if tries.zero?
466
- if output_exception_messages
467
- if Rails.logger.class.to_s == "Ougai::Logger"
468
- Rails.logger.error("SOAP Call - Timed out will retry after #{timeout_sleep_interval} seconds", ex)
469
- else
470
- Rails.logger.error("SOAP Call - #{ex.class} Timed out will retry after #{timeout_sleep_interval} seconds")
471
- end
472
- end
473
- raise ex
479
+ if !(tries -= 1).zero?
480
+ Rails.logger.info("SOAP Call - #{ex.class} Timed out will retry after 5 seconds")
481
+ sleep(self.timeout_sleep)
482
+ retry
483
+ else
484
+ raise ex
474
485
  end
475
-
476
- tries -= 1
477
- sleep(timeout_sleep_interval)
478
- retry
479
486
  rescue *CONNECTION_READ_EXCEPTIONS => ex
480
- if !tries.zero?
481
- tries -= 1
482
-
483
- if ex.is_a?(Errno::ECONNRESET) && ex.message.include?('SSL_connect')
484
- retry
485
- elsif timeout_retry
486
- sleep(timeout_sleep_interval)
487
- retry
488
- end
487
+ if !(tries -= 1).zero? && timeout_retry
488
+ Rails.logger.info("SOAP Call - #{ex.class} Timed out will retry after 5 seconds")
489
+ sleep(self.timeout_sleep)
490
+ retry
491
+ else
492
+ raise ex
489
493
  end
490
-
491
- if output_exception_messages
492
- if Rails.logger.class.to_s == "Ougai::Logger"
493
- Rails.logger.error("SOAP Call - Timed out will retry after #{timeout_sleep_interval} seconds", ex)
494
- else
495
- Rails.logger.error("SOAP Call - #{ex.class} Timed out will retry after #{timeout_sleep_interval} seconds")
496
- end
494
+ rescue Errno::ECONNRESET => ex
495
+ if !(tries -= 1).zero? && ex.message.include?('SSL_connect')
496
+ retry
497
+ else
498
+ raise ex
497
499
  end
498
- raise ZuoraAPI::Exceptions::ZuoraAPIReadTimeout.new("Received read timeout from #{url}", nil, request) if ex.instance_of?(Net::ReadTimeout)
499
- raise ex
500
500
  rescue => ex
501
501
  raise ex
502
502
  else
@@ -504,60 +504,39 @@ module ZuoraAPI
504
504
  end
505
505
 
506
506
  def raise_errors(type: :SOAP, body: nil, response: nil)
507
- request_uri, request_path, match_string = "", "", ""
508
- if response.class.to_s == "HTTP::Message"
509
- request_uri = response.http_header.request_uri.to_s
510
- request_path = response.http_header.request_uri.path
511
- match_string = "#{response.http_header.request_method}::#{response.code}::#{request_uri}"
512
- else
513
- request = response.request
514
- request_uri = response.request.uri
515
- request_path = request.path.path
516
- match_string = "#{request.http_method.to_s.split("Net::HTTP::").last.upcase}::#{response.code}::#{request_path}"
517
- end
518
-
519
507
  if [502,503].include?(response.code)
520
- raise ZuoraAPI::Exceptions::ZuoraAPIConnectionTimeout.new("Received #{response.code} from #{request_uri}", response)
508
+ raise ZuoraAPI::Exceptions::ZuoraAPIConnectionTimeout.new("Received #{response.code} from downstream host", response)
521
509
  end
522
510
 
523
- # Check failure response code
524
- case response.code
525
- when 504
526
- raise ZuoraAPI::Exceptions::ZuoraAPIReadTimeout.new("Received 504 from #{request_uri}", response)
527
- when 429
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.", response)
529
- when 401
530
-
531
- else
532
- if body.class == Hash
533
- case request_path
534
- when /^\/v1\/connections$/
535
- response_headers = response.headers.to_h
536
- raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new("Missing cookies for authentication call", response) if response_headers['set-cookie'].blank?
537
- z_session_cookie = response_headers.fetch('set-cookie', []).select{|x| x.match(/^ZSession=.*/) }.first
538
- raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new("Missing ZSession cookie for authentication call", response) if z_session_cookie.blank?
539
- end
540
- end
511
+ if response.code == 504
512
+ raise ZuoraAPI::Exceptions::ZuoraAPIReadTimeout.new("Received 504 from downstream host", response)
541
513
  end
542
514
 
543
515
  case type
544
516
  when :SOAP
545
- error, success, message = get_soap_error_and_message(body)
546
-
547
- if body.xpath('//ns1:queryResponse', 'ns1' => 'http://api.zuora.com/').present? &&
548
- body.xpath(
549
- '//ns1:records[@xsi:type="ns2:Export"]',
550
- 'ns1' => 'http://api.zuora.com/', 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
551
- ).present?
552
- result = body.xpath('//ns2:Status', 'ns2' => 'http://object.api.zuora.com/').text
553
- if result == 'Failed'
554
- reason = body.xpath('//ns2:StatusReason', 'ns2' => 'http://object.api.zuora.com/').text
555
- if reason.present?
556
- message = body.xpath('//ns2:StatusReason', 'ns2' => 'http://object.api.zuora.com/').text
557
- error = message.match(/^[\w\d]{16}\: (Unexpected error.|No HTTP Response|Socket Timeout|There is an internal error, please try again later)/).present? ? 'UNEXPECTED_ERROR' : 'FATAL_ERROR'
517
+ error = body.xpath('//fns:FaultCode', 'fns' =>'http://fault.api.zuora.com/').text
518
+ message = body.xpath('//fns:FaultMessage', 'fns' =>'http://fault.api.zuora.com/').text
519
+
520
+ if error.blank? || message.blank?
521
+ error = body.xpath('//faultcode').text
522
+ message = body.xpath('//faultstring').text
523
+ end
524
+
525
+ if error.blank? || message.blank?
526
+ error = body.xpath('//ns1:Code', 'ns1' =>'http://api.zuora.com/').text
527
+ message = body.xpath('//ns1:Message', 'ns1' =>'http://api.zuora.com/').text
528
+ end
529
+
530
+ #Update/Create/Delete Calls with multiple requests and responses
531
+ if body.xpath('//ns1:result', 'ns1' =>'http://api.zuora.com/').size > 0 && body.xpath('//ns1:Errors', 'ns1' =>'http://api.zuora.com/').size > 0
532
+ error = []
533
+ success = []
534
+ body.xpath('//ns1:result', 'ns1' =>'http://api.zuora.com/').each_with_index do |call, object_index|
535
+ if call.xpath('./ns1:Success', 'ns1' =>'http://api.zuora.com/').text == 'false' && call.xpath('./ns1:Errors', 'ns1' =>'http://api.zuora.com/').size > 0
536
+ message = "#{call.xpath('./*/ns1:Code', 'ns1' =>'http://api.zuora.com/').text}::#{call.xpath('./*/ns1:Message', 'ns1' =>'http://api.zuora.com/').text}"
537
+ error.push(message)
558
538
  else
559
- error = 'FATAL_ERROR'
560
- message = 'Export failed due to unknown reason. Consult api logs.'
539
+ success.push(call.xpath('./ns1:Id', 'ns1' =>'http://api.zuora.com/').text)
561
540
  end
562
541
  end
563
542
  end
@@ -565,48 +544,44 @@ module ZuoraAPI
565
544
  #By default response if not passed in for SOAP as all SOAP is 200
566
545
  if error.present?
567
546
  if error.class == String
568
- raise_errors_helper(error: error, message: message, response: response)
547
+ case error
548
+ when "INVALID_SESSION"
549
+ raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{error}::#{message}", response)
550
+ when "REQUEST_EXCEEDED_LIMIT"
551
+ raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new("#{error}::#{message}", response)
552
+ when "LOCK_COMPETITION"
553
+ raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("#{error}::#{message}", response)
554
+ when "BATCH_FAIL_ERROR"
555
+ if message.include?("optimistic locking failed")
556
+ raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("#{error}::#{message}", response)
557
+ else
558
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{error}::#{message}", response)
559
+ end
560
+ when "TEMPORARY_ERROR"
561
+ raise ZuoraAPI::Exceptions::ZuoraAPITemporaryError.new("#{error}::#{message}", response)
562
+ when "INVALID_VALUE"
563
+ if message.include?("data integrity violation")
564
+ raise ZuoraAPI::Exceptions::ZuoraDataIntegrity.new("Data Integrity Violation", response)
565
+ else
566
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{error}::#{message}", response)
567
+ end
568
+ else
569
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{error}::#{message}", response) if error.present?
570
+ end
569
571
  elsif error.class == Array
570
- if error.uniq.size == 1
571
- err, msg = error[0].split('::')
572
- raise_errors_helper(error: err, message: msg, response: response, errors: error, success: success)
572
+ if error[0].include?("LOCK_COMPETITION") && error.count == 1
573
+ raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new(error.group_by {|v| v}.map {|k,v| "(#{v.size}x) - #{k == "::" ? 'UNKNOWN::No error provided' : k}"}.join(', '), response)
573
574
  else
574
575
  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)
575
576
  end
576
577
  end
577
578
  end
578
-
579
- self.errors_via_content_type(response: response, type: :xml)
580
579
 
581
- when :JSON
582
- case request_path
583
- when /^\/query\/jobs.*/ #DataQuery Paths
584
- return if body.class != Hash
585
- case match_string
586
- when /^GET::200::\/query\/jobs\/([a-zA-Z0-9\-_]+)$/ #Get DQ job, Capture of the id is present if needed in future error responses.
587
- if body.dig('data', "errorCode") == "LINK_10000005"
588
- raise ZuoraAPI::Exceptions::ZuoraAPITemporaryError.new(body.dig('data', "errorMessage"), response)
589
- elsif (body.dig('data', "errorMessage").present? || body.dig('data', "queryStatus") == "failed")
590
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new(body.dig('data', "errorMessage"), response)
591
- end
592
- when /^GET::404::\/query\/jobs\/([a-zA-Z0-9\-_]+)$/ #Get DQ job not found, capture of the id is present if needed in future error responses.
593
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new(body.dig('message'), response) if body.dig('message').present?
594
- when /^POST::400::\/query\/jobs$/ #Create DQ job
595
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new(body.dig('message'), response) if body.dig('message').present?
596
- end
597
- when /^\/api\/rest\/v1\/reports.*/ #Reporting Paths
598
- reporting_message = response.parsed_response.dig("ZanResponse", "response", "message") || body.dig("message")
599
- if reporting_message&.include?("com.zuora.rest.RestUsageException: The user does not have permissions for this API.")
600
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new(reporting_message, response)
601
- elsif reporting_message&.include?("500 Internal Server Error")
602
- raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new("Internal Server Error. The Reporting API is down. Contact Support.", response)
603
- end
604
- case match_string
605
- when /^GET::400::\/api\/rest\/v1\/reports\/(reportlabels\/)?([a-zA-Z0-9\-_]+)\/report-details$/ # Get report, capture of the id is present if needed in future error responses.
606
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new(reporting_message, response) if reporting_message.present?
607
- end
580
+ if response.code == 429
581
+ 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)
608
582
  end
609
583
 
584
+ when :JSON
610
585
  body = body.dig("results").present? ? body["results"] : body if body.class == Hash
611
586
  if body.class == Hash && (!body["success"] || !body["Success"] || response.code != 200)
612
587
  messages_array = body.fetch("reasons", []).map {|error| error['message']}.compact
@@ -614,14 +589,6 @@ module ZuoraAPI
614
589
  codes_array = body.fetch("reasons", []).map {|error| error['code']}.compact
615
590
  codes_array = codes_array.push(body.dig("error", 'code')).compact if body.dig('error').class == Hash
616
591
 
617
- if body['message'] == 'request exceeded limit'
618
- 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)
619
- end
620
-
621
- if (body.dig('message') || '').downcase.include?('unexpected error') && response.code != 500
622
- raise ZuoraAPI::Exceptions::ZuoraUnexpectedError.new(body['message'], response)
623
- end
624
-
625
592
  if body['message'] == "No bearer token" && response.code == 400
626
593
  raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Authentication type is not supported by this Login", response)
627
594
  end
@@ -635,12 +602,8 @@ module ZuoraAPI
635
602
  end
636
603
 
637
604
  #Oauth Tokens - User deactivated
638
- if body['path'] == '/oauth/token'
639
- if body['status'] == 403 && response.code == 403
640
- raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("Forbidden", response)
641
- elsif body['status'] == 400 && response.code == 400 && body['message'].include?("Invalid client id")
642
- raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("Invalid Oauth Client Id", response)
643
- end
605
+ if body['reason'] == 'Forbidden' && body['status'] == 403 && response.code == 403
606
+ raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("Forbidden", response)
644
607
  end
645
608
 
646
609
  if body['error'] == 'Unauthorized' && body['status'] == 401
@@ -648,12 +611,7 @@ module ZuoraAPI
648
611
  end
649
612
  #Authentication failed
650
613
  if (codes_array.map{|code| code.to_s.slice(6,7).to_i}.include?(11) || response.code == 401) && !codes_array.include?(422)
651
- new_message = messages_array.join(', ')
652
- if new_message.present?
653
- raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(new_message, response)
654
- else
655
- raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(body['message'], response)
656
- end
614
+ raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{messages_array.join(', ')}", response)
657
615
  end
658
616
 
659
617
  #Zuora REST Create Amendment error #Authentication failed
@@ -661,30 +619,16 @@ module ZuoraAPI
661
619
  raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{body['faultstring']}", response)
662
620
  end
663
621
 
664
- #Locking contention
665
- if codes_array.map{|code| code.to_s.slice(6,7).to_i}.include?(50)
666
- raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("#{messages_array.join(', ')}", response)
667
- end
668
- #Internal Server Error
669
- if codes_array.map{|code| code.to_s.slice(6,7).to_i}.include?(60)
670
- if messages_array.uniq.size == 1
671
- if messages_array.first.match(/^Transaction declined.*|^There is an invoice pending tax.*|^The Zuora GetTax call to Avalara.*|^The tax calculation call to Zuora Connect returned the following error: Status Code: 4.*/)
672
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new(messages_array.first, response)
673
- end
674
- end
675
- raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new("#{messages_array.join(', ')}", response)
676
- end
677
-
678
- #Retryiable Service Error
679
- if codes_array.map{|code| code.to_s.slice(6,7).to_i}.include?(61)
680
- raise ZuoraAPI::Exceptions::ZuoraAPITemporaryError.new("#{messages_array.join(', ')}", response)
681
- end
682
-
683
622
  #Request exceeded limit
684
623
  if codes_array.map{|code| code.to_s.slice(6,7).to_i}.include?(70)
685
624
  raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new("#{messages_array.join(', ')}", response)
686
625
  end
687
626
 
627
+ #Locking contention
628
+ if codes_array.map{|code| code.to_s.slice(6,7).to_i}.include?(50)
629
+ raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("#{messages_array.join(', ')}", response)
630
+ end
631
+
688
632
  #All Errors catch
689
633
  if codes_array.size > 0
690
634
  raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{messages_array.join(', ')}", response)
@@ -692,20 +636,26 @@ module ZuoraAPI
692
636
 
693
637
  #Zuora REST Query Errors
694
638
  if body["faultcode"].present?
695
- raise_errors_helper(error: body["faultcode"], message: body["faultstring"], response: response)
639
+ case body["faultcode"]
640
+ when "fns:MALFORMED_QUERY"
641
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{body["faultcode"]}::#{body["faultstring"]}", response)
642
+ when "fns:REQUEST_EXCEEDED_LIMIT"
643
+ raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new("#{body["faultcode"]}::#{body["faultstring"]}", response)
644
+ when "fns:LOCK_COMPETITION"
645
+ raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("#{body["faultcode"]}::#{body["faultstring"]}", response)
646
+ when "INVALID_SESSION"
647
+ raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{body["faultcode"]}::#{body["faultstring"]}", response)
648
+ else
649
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{body["faultcode"]}::#{body["faultstring"]}", response)
650
+ end
696
651
  end
697
652
 
698
653
  if body["Errors"].present? || body["errors"].present?
699
- codes, messages = [[],[]]
700
- body.fetch("Errors", []).each { |obj| messages.push(obj["Message"]); messages.push(obj["title"]); codes.push(obj["Code"]); codes.push(obj["code"]) }
701
- body.fetch("errors", []).each { |obj| messages.push(obj["Message"]); messages.push(obj["title"]); codes.push(obj["Code"]); codes.push(obj["code"]) }
702
- codes, messages = [codes.uniq.compact, messages.uniq.compact]
703
- if codes.size > 0
704
- if codes.size == 1
705
- raise_errors_helper(error: codes.first, message: messages.first, response: response, errors: messages)
706
- else
707
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{messages.join(", ")}", response, messages)
708
- end
654
+ errors = []
655
+ (body["Errors"] || []).select { |obj| errors.push(obj["Message"]) }.compact
656
+ (body["errors"] || []).select { |obj| errors.push(obj["Message"]) }.compact
657
+ if errors.size > 0
658
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{errors.join(", ")}", response, errors)
709
659
  end
710
660
  end
711
661
  end
@@ -723,7 +673,7 @@ module ZuoraAPI
723
673
  raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("Retry Lock Competition", response)
724
674
  elsif error_messages.first.include?("data integrity violation")
725
675
  raise ZuoraAPI::Exceptions::ZuoraDataIntegrity.new("Data Integrity Violation", response)
726
- end
676
+ end
727
677
  end
728
678
  end
729
679
 
@@ -732,128 +682,15 @@ module ZuoraAPI
732
682
  end
733
683
  end
734
684
 
735
- if body.class == Hash && body['message'].present?
736
- raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new(body['message'], response) if response.code == 500
737
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new(body['message'], response) if ![200,201].include?(response.code)
738
- end
739
-
740
- self.errors_via_content_type(response: response, type: :json)
741
-
742
685
  #All other errors
743
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new(response.body, response) if ![200,201].include?(response.code)
744
- end
745
- end
746
-
747
- def errors_via_content_type(response: nil, type: :xml)
748
- response_content_types = response.headers.transform_keys(&:downcase).fetch('content-type', []).first || ""
749
-
750
- if response_content_types.include?('application/json') && type != :json
751
- output_json = JSON.parse(response.body)
752
- self.raise_errors(type: :JSON, body: output_json, response: response)
753
-
754
- elsif (response_content_types.include?('application/xml') || response_content_types.include?('text/xml')) and type != :xml
755
- output_xml = Nokogiri::XML(response.body)
756
- self.raise_errors(type: :SOAP, body: output_xml, response: response)
757
-
758
- elsif response_content_types.include?('text/html')
759
- raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new("Akamai Error", response) if response.headers.fetch('server', '') == 'AkamaiGHost'
760
-
761
- parse_body = Nokogiri::HTML(response.body)
762
- error_title = parse_body.xpath('//h2').text
763
- error_title = parse_body.xpath('//h1').text if error_title.blank?
764
- error_message = parse_body.xpath('//p').text
765
-
766
- error_message = error_title if error_message.blank?
767
-
768
- if error_title.present?
769
- case error_title
770
- when /Service Unavailable/
771
- raise ZuoraAPI::Exceptions::ZuoraAPIConnectionTimeout.new(error_message, response)
772
- when /Client sent a bad request./, /Bad Request/, /403 Forbidden/
773
- raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new(error_message, response)
774
- else
775
- raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new(error_message, response)
776
- end
777
- end
778
-
779
- raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new("Http response body is missing", response) if response.body.blank?
780
- end
781
-
782
- raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new(response.body, response) if response.code == 500
783
- end
784
-
785
-
786
- def get_soap_error_and_message(body)
787
- error = body.xpath('//fns:FaultCode', 'fns' =>'http://fault.api.zuora.com/').text
788
- message = body.xpath('//fns:FaultMessage', 'fns' =>'http://fault.api.zuora.com/').text
789
-
790
- if error.blank? || message.blank?
791
- error = body.xpath('//faultcode').text
792
- message = body.xpath('//faultstring').text
793
- end
794
-
795
- if error.blank? || message.blank?
796
- error = body.xpath('//ns1:Code', 'ns1' =>'http://api.zuora.com/').text
797
- message = body.xpath('//ns1:Message', 'ns1' =>'http://api.zuora.com/').text
798
- end
799
-
800
- #Update/Create/Delete Calls with multiple requests and responses
801
- if body.xpath('//ns1:result', 'ns1' =>'http://api.zuora.com/').size > 0 && body.xpath('//ns1:Errors', 'ns1' =>'http://api.zuora.com/').size > 0
802
- error = []
803
- success = []
804
- body.xpath('//ns1:result', 'ns1' =>'http://api.zuora.com/').each_with_index do |call, object_index|
805
- if call.xpath('./ns1:Success', 'ns1' =>'http://api.zuora.com/').text == 'false' && call.xpath('./ns1:Errors', 'ns1' =>'http://api.zuora.com/').size > 0
806
- message = "#{call.xpath('./*/ns1:Code', 'ns1' =>'http://api.zuora.com/').text}::#{call.xpath('./*/ns1:Message', 'ns1' =>'http://api.zuora.com/').text}"
807
- error.push(message)
686
+ if ![200,201].include?(response.code)
687
+ if response.code == 429
688
+ 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)
808
689
  else
809
- success.push(call.xpath('./ns1:Id', 'ns1' =>'http://api.zuora.com/').text)
690
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{response.message}", response)
810
691
  end
811
692
  end
812
693
  end
813
- return error, success, message
814
- end
815
-
816
- def raise_errors_helper(error: nil, message: nil, response: nil, errors: [], success: [])
817
- case error
818
- when /.*INVALID_SESSION/
819
- raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(message, response, errors, success)
820
- when /.*REQUEST_EXCEEDED_LIMIT/
821
- raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new(message, response, errors, success)
822
- when /.*LOCK_COMPETITION/
823
- raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new(message, response, errors, success)
824
- when /.*BATCH_FAIL_ERROR/
825
- if message.include?("optimistic locking failed") || message.include?("Operation failed due to a lock competition, please retry later.")
826
- raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new(message, response, errors, success)
827
- elsif message.include?("org.hibernate.exception.ConstraintViolationException")
828
- raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new(message, response, errors, success)
829
- end
830
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new(message, response, errors, success)
831
- when /.*TEMPORARY_ERROR/, /.*TRANSACTION_TIMEOUT/
832
- raise ZuoraAPI::Exceptions::ZuoraAPITemporaryError.new(message, response, errors, success)
833
- when /.*INVALID_VALUE/
834
- if message.include?("data integrity violation")
835
- raise ZuoraAPI::Exceptions::ZuoraDataIntegrity.new("Data Integrity Violation", response, errors), success
836
- end
837
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new(message, response, errors, success)
838
- when /.*UNKNOWN_ERROR/
839
- if /payment\/refund|Credit Balance Adjustment|Payment Gateway|ARSettlement permission/.match(message).nil?
840
- raise ZuoraAPI::Exceptions::ZuoraAPIUnkownError.new(message, response, errors, success)
841
- end
842
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new(message, response, errors, success)
843
- when /invalid/, /^DUPLICATE_VALUE/, /^REQUEST_REJECTED/, /INVALID_ID/, /MAX_RECORDS_EXCEEDED/, /INVALID_FIELD/, /MALFORMED_QUERY/, /NO_PERMISSION/, /PDF_QUERY_ERROR/, /MISSING_REQUIRED_VALUE/, /INVALID_TYPE/, /TRANSACTION_FAILED/, /API_DISABLED/, /CANNOT_DELETE/, /ACCOUNTING_PERIOD_CLOSED/
844
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new(message, response, errors, success)
845
- when /.*UNEXPECTED_ERROR/
846
- raise ZuoraAPI::Exceptions::ZuoraUnexpectedError.new(message, response, errors, success)
847
- when /.*soapenv:Server.*/
848
- if /^Invalid value.*for type.*|^Id is invalid|^date string can not be less than 19 charactors$/.match(message).present?
849
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new(message, response, errors, success)
850
- elsif /^Invalid white space character \(.*\) in text to output$|^Invalid null character in text to output$/.match(message).present?
851
- raise ZuoraAPI::Exceptions::ZuoraAPIUnkownError.new(message, response, errors, success)
852
- end
853
- raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new(message, response, errors, success)
854
- else
855
- raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new("Z:#{error}::#{message}", response, errors, success)
856
- end
857
694
  end
858
695
 
859
696
  def aqua_query(queryName: '', query: '', version: '1.2', jobName: 'Aqua',partner: '', project: '')
@@ -934,23 +771,15 @@ module ZuoraAPI
934
771
  des_hash[:related_objects] = output_xml.xpath(".//related-objects").xpath(".//object").map{ |x| [x.xpath(".//name").text.to_sym, [ [:url, x.attributes["href"].value], [:label, x.xpath(".//name").text ] ].to_h] }.to_h
935
772
  end
936
773
  rescue *(CONNECTION_EXCEPTIONS + CONNECTION_READ_EXCEPTIONS) => ex
937
- if tries.zero?
938
- if log_errors
939
- if Rails.logger.class.to_s == "Ougai::Logger"
940
- Rails.logger.error("Describe - Timed out will retry after #{self.timeout_sleep} seconds", ex)
941
- else
942
- Rails.logger.error("Describe - #{ex.class} Timed out will retry after #{self.timeout_sleep} seconds")
943
- end
944
- end
945
- raise ex
774
+ if !(tries -= 1).zero?
775
+ Rails.logger.info("Describe - #{ex.class} Timed out will retry after 5 seconds")
776
+ sleep(self.timeout_sleep)
777
+ retry
778
+ else
779
+ raise ex
946
780
  end
947
-
948
- tries -= 1
949
- sleep(self.timeout_sleep)
950
- retry
951
781
  rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
952
- if !tries.zero? && self.status == 'Active'
953
- tries -= 1
782
+ if !(tries -= 1).zero? && self.status == 'Active'
954
783
  Rails.logger.debug("Describe session expired. Starting new session.")
955
784
  self.new_session
956
785
  retry
@@ -975,73 +804,50 @@ module ZuoraAPI
975
804
  session_type: :basic,
976
805
  timeout_retry: false,
977
806
  timeout: 120,
978
- timeout_sleep_interval: self.timeout_sleep,
979
807
  multipart: false,
980
- stream_body: false,
981
- output_exception_messages: true,
982
- **keyword_args,
983
- &block
808
+ **keyword_args
984
809
  )
985
810
  tries ||= 2
986
811
 
987
- raise "Method not supported, supported methods include: :get, :post, :put, :delete, :patch, :head, :options" if ![:get, :post, :put, :delete, :patch, :head, :options].include?(method)
988
-
989
- authentication_headers = {}
990
- if z_session
991
- authentication_headers = {"Authorization" => self.get_session(prefix: true, auth_type: session_type) }
992
- if self.entity_id.present?
993
- authentication_headers["Zuora-Entity-Ids"] = self.entity_id if headers.dig("Zuora-Entity-Ids").nil?
994
- authentication_headers.delete_if { |key, value| ["entityId", "entityName"].include?(key.to_s) }
995
- end
812
+ if self.entity_id.present?
813
+ headers["Zuora-Entity-Ids"] = self.entity_id if headers.dig("Zuora-Entity-Ids").nil?
814
+ headers.delete_if { |key, value| ["entityId", "entityName"].include?(key.to_s) }
996
815
  end
997
816
 
817
+ raise "Method not supported, supported methods include: :get, :post, :put, :delete, :patch, :head, :options" if ![:get, :post, :put, :delete, :patch, :head, :options].include?(method)
818
+
819
+ authentication_headers = z_session ? {"Authorization" => self.get_session(prefix: true, auth_type: session_type) } : {}
998
820
  modified_headers = {'Content-Type' => "application/json; charset=utf-8"}.merge(authentication_headers).merge(headers)
999
821
 
1000
- begin
1001
- request = HTTParty::Request.new(
1002
- "Net::HTTP::#{method.to_s.capitalize}".constantize,
1003
- url,
1004
- body: body,
1005
- headers: modified_headers,
1006
- timeout: timeout,
1007
- multipart: multipart,
1008
- stream_body: stream_body
1009
- )
1010
-
1011
- response = request.perform(&block)
1012
-
1013
- Rails.logger.debug("Response Code: #{response.code}") if debug
1014
- begin
1015
- output_json = JSON.parse(response.body)
1016
- rescue JSON::ParserError => ex
1017
- output_json = {}
1018
- end
1019
- Rails.logger.debug("Response JSON: #{output_json}") if debug && output_json.present?
822
+ response = HTTParty::Request.new(
823
+ "Net::HTTP::#{method.to_s.capitalize}".constantize,
824
+ url,
825
+ body: body,
826
+ headers: modified_headers,
827
+ timeout: timeout,
828
+ multipart: multipart,
829
+ ).perform
1020
830
 
1021
- raise_errors(type: :JSON, body: output_json, response: response)
1022
- rescue
1023
- reset_files(body) if multipart
1024
- raise
831
+ Rails.logger.debug("Response Code: #{response.code}") if debug
832
+ begin
833
+ output_json = JSON.parse(response.body)
834
+ rescue JSON::ParserError => ex
835
+ output_json = {}
1025
836
  end
837
+ Rails.logger.debug("Response JSON: #{output_json}") if debug && output_json.present?
838
+
839
+ raise_errors(type: :JSON, body: output_json, response: response)
1026
840
  rescue ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError => ex
1027
841
  if self.class.to_s == 'ZuoraAPI::Oauth' && ex.message.include?("Authentication type is not supported by this Login")
1028
- session_type = :bearer
1029
- retry
842
+ 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)
1030
843
  else
1031
844
  Rails.logger.debug("Rest Call - Session Bad Auth type")
1032
845
  raise ex
1033
846
  end
1034
847
  rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
1035
- if !tries.zero? && z_session
1036
- tries -= 1
848
+ if !(tries -= 1).zero? && z_session
1037
849
  Rails.logger.debug("Rest Call - Session Invalid #{session_type}")
1038
-
1039
- begin
1040
- self.new_session(auth_type: session_type)
1041
- rescue *ZUORA_API_ERRORS => ex
1042
- return [output_json, ex.response]
1043
- end
1044
-
850
+ self.new_session(auth_type: session_type)
1045
851
  retry
1046
852
  else
1047
853
  if errors.include?(ex.class)
@@ -1054,46 +860,32 @@ module ZuoraAPI
1054
860
  if errors.include?(ex.class)
1055
861
  raise ex
1056
862
  else
1057
- response = ex.response unless response
1058
863
  return [output_json, response]
1059
864
  end
1060
865
  rescue ZuoraAPI::Exceptions::BadEntityError => ex
1061
866
  raise ex
1062
867
  rescue *CONNECTION_EXCEPTIONS => ex
1063
- if tries.zero?
1064
- if output_exception_messages
1065
- if Rails.logger.class.to_s == "Ougai::Logger"
1066
- Rails.logger.error("Rest Call - Timed out will retry after #{timeout_sleep_interval} seconds", ex)
1067
- else
1068
- Rails.logger.error("Rest Call - #{ex.class} Timed out will retry after #{timeout_sleep_interval} seconds")
1069
- end
1070
- end
1071
- raise ex
868
+ if !(tries -= 1).zero?
869
+ Rails.logger.info("Rest Call - #{ex.class} Timed out will retry after 5 seconds")
870
+ sleep(self.timeout_sleep)
871
+ retry
872
+ else
873
+ raise ex
1072
874
  end
1073
-
1074
- tries -= 1
1075
- sleep(timeout_sleep_interval)
1076
- retry
1077
875
  rescue *CONNECTION_READ_EXCEPTIONS => ex
1078
- if !tries.zero?
1079
- tries -= 1
1080
- if ex.is_a?(Errno::ECONNRESET) && ex.message.include?('SSL_connect')
1081
- retry
1082
- elsif timeout_retry
1083
- sleep(timeout_sleep_interval)
1084
- retry
1085
- end
876
+ if !(tries -= 1).zero? && timeout_retry
877
+ Rails.logger.info("Rest Call - #{ex.class} Timed out will retry after 5 seconds")
878
+ sleep(self.timeout_sleep)
879
+ retry
880
+ else
881
+ raise ex
1086
882
  end
1087
-
1088
- if output_exception_messages
1089
- if Rails.logger.class.to_s == "Ougai::Logger"
1090
- Rails.logger.error("Rest Call - Timed out will retry after #{timeout_sleep_interval} seconds", ex)
1091
- else
1092
- Rails.logger.error("Rest Call - #{ex.class} Timed out will retry after #{timeout_sleep_interval} seconds")
1093
- end
883
+ rescue Errno::ECONNRESET => ex
884
+ if !(tries -= 1).zero? && ex.message.include?('SSL_connect')
885
+ retry
886
+ else
887
+ raise ex
1094
888
  end
1095
- raise ZuoraAPI::Exceptions::ZuoraAPIReadTimeout.new("Received read timeout from #{url}", nil, request) if ex.instance_of?(Net::ReadTimeout)
1096
- raise ex
1097
889
  rescue => ex
1098
890
  raise ex
1099
891
  else
@@ -1146,11 +938,9 @@ module ZuoraAPI
1146
938
  return products, catalog_map
1147
939
  end
1148
940
 
1149
- def get_file(url: nil, headers: {}, z_session: true, tempfile: true, output_file_name: nil, zuora_track_id: nil, add_timestamp: true, file_path: defined?(Rails.root.join('tmp')) ? Rails.root.join('tmp') : Pathname.new(Dir.pwd), timeout_retries: 3, timeout: 120, session_type: :basic, **execute_params)
941
+ def get_file(url: nil, headers: {}, z_session: true, tempfile: true, output_file_name: nil, add_timestamp: true, file_path: defined?(Rails.root.join('tmp')) ? Rails.root.join('tmp') : Pathname.new(Dir.pwd), timeout_retries: 3, timeout: 120, session_type: :basic, **execute_params)
1150
942
  raise "file_path must be of class Pathname" if file_path.class != Pathname
1151
943
 
1152
- retry_count ||= timeout_retries
1153
-
1154
944
  #Make sure directory exists
1155
945
  require 'fileutils'
1156
946
  FileUtils.mkdir_p(file_path) unless File.exists?(file_path)
@@ -1165,9 +955,8 @@ module ZuoraAPI
1165
955
  headers = headers.merge({"Zuora-Entity-Ids" => self.entity_id}) if !self.entity_id.blank?
1166
956
  end
1167
957
 
1168
- headers['Zuora-Track-Id'] = zuora_track_id if zuora_track_id.present?
1169
-
1170
958
  response_save = nil
959
+ retry_count ||= timeout_retries
1171
960
  http.request_get(uri.request_uri, headers) do |response|
1172
961
  response_save = response
1173
962
  status_code = response.code if response
@@ -1261,11 +1050,11 @@ module ZuoraAPI
1261
1050
  raise
1262
1051
  end
1263
1052
  else
1264
- raise ZuoraAPI::Exceptions::FileDownloadError.new("File Download Failed #{response.class}")
1053
+ raise StandardError.new("File Download Failed #{response.class}")
1265
1054
  end
1266
1055
  end
1267
-
1268
- rescue => ex
1056
+
1057
+ rescue => ex
1269
1058
  sleep(5)
1270
1059
  if (retry_count -= 1) >= 0
1271
1060
  retry
@@ -1275,122 +1064,75 @@ module ZuoraAPI
1275
1064
  end
1276
1065
  end
1277
1066
 
1278
- def getDataSourceExport(query, extract: true, encrypted: false, zip: true, z_track_id: "")
1279
- begin
1280
- tries ||= 3
1281
- request = Nokogiri::XML::Builder.new do |xml|
1282
- 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
1283
- xml['SOAP-ENV'].Header do
1284
- xml['ns1'].SessionHeader do
1285
- xml['ns1'].session self.get_session(prefix: false, auth_type: :basic, zuora_track_id: z_track_id)
1286
- end
1067
+ def getDataSourceExport(query, extract: true, encrypted: false, zip: true)
1068
+ request = Nokogiri::XML::Builder.new do |xml|
1069
+ 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
1070
+ xml['SOAP-ENV'].Header do
1071
+ xml['ns1'].SessionHeader do
1072
+ xml['ns1'].session self.get_session(prefix: false, auth_type: :basic)
1287
1073
  end
1288
- xml['SOAP-ENV'].Body do
1289
- xml['ns1'].create do
1290
- xml['ns1'].zObjects('xsi:type' => "ns2:Export") do
1291
- xml['ns2'].Format 'csv'
1292
- xml['ns2'].Zip zip
1293
- xml['ns2'].Name 'googman'
1294
- xml['ns2'].Query query
1295
- xml['ns2'].Encrypted encrypted
1296
- end
1074
+ end
1075
+ xml['SOAP-ENV'].Body do
1076
+ xml['ns1'].create do
1077
+ xml['ns1'].zObjects('xsi:type' => "ns2:Export") do
1078
+ xml['ns2'].Format 'csv'
1079
+ xml['ns2'].Zip zip
1080
+ xml['ns2'].Name 'googman'
1081
+ xml['ns2'].Query query
1082
+ xml['ns2'].Encrypted encrypted
1297
1083
  end
1298
1084
  end
1299
1085
  end
1300
1086
  end
1087
+ end
1301
1088
 
1302
- response_query = HTTParty.post(self.url, body: request.to_xml(:save_with => XML_SAVE_OPTIONS).strip, headers: {'Content-Type' => "application/json; charset=utf-8", "Z-Track-Id" => z_track_id}, :timeout => 120)
1089
+ response_query = HTTParty.post(self.url, body: request.to_xml(:save_with => XML_SAVE_OPTIONS).strip, headers: {'Content-Type' => "application/json; charset=utf-8"}, :timeout => 120)
1303
1090
 
1304
- output_xml = Nokogiri::XML(response_query.body)
1305
- raise_errors(type: :SOAP, body: output_xml, response: response_query) if output_xml.xpath('//ns1:Success', 'ns1' =>'http://api.zuora.com/').text != "true"
1091
+ output_xml = Nokogiri::XML(response_query.body)
1092
+ raise 'Export Creation Unsuccessful : ' + output_xml.xpath('//ns1:Message', 'ns1' =>'http://api.zuora.com/').text if output_xml.xpath('//ns1:Success', 'ns1' =>'http://api.zuora.com/').text != "true"
1093
+ id = output_xml.xpath('//ns1:Id', 'ns1' =>'http://api.zuora.com/').text
1306
1094
 
1307
- # raise "Export Creation Unsuccessful : #{response_query.code}: #{response_query.parsed_response}" if output_xml.xpath('//ns1:Success', 'ns1' =>'http://api.zuora.com/').text != "true"
1308
-
1309
- id = output_xml.xpath('//ns1:Id', 'ns1' =>'http://api.zuora.com/').text
1310
-
1311
- confirmRequest = Nokogiri::XML::Builder.new do |xml|
1312
- 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
1313
- xml['SOAP-ENV'].Header do
1314
- xml['ns1'].SessionHeader do
1315
- xml['ns1'].session self.get_session(prefix: false, auth_type: :basic, zuora_track_id: z_track_id)
1316
- end
1095
+ confirmRequest = Nokogiri::XML::Builder.new do |xml|
1096
+ 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
1097
+ xml['SOAP-ENV'].Header do
1098
+ xml['ns1'].SessionHeader do
1099
+ xml['ns1'].session self.get_session(prefix: false, auth_type: :basic)
1317
1100
  end
1318
- xml['SOAP-ENV'].Body do
1319
- xml['ns1'].query do
1320
- xml['ns1'].queryString "SELECT Id, CreatedById, CreatedDate, Encrypted, FileId, Format, Name, Query, Size, Status, StatusReason, UpdatedById, UpdatedDate, Zip From Export where Id = '#{id}'"
1321
- end
1101
+ end
1102
+ xml['SOAP-ENV'].Body do
1103
+ xml['ns1'].query do
1104
+ xml['ns1'].queryString "SELECT Id, CreatedById, CreatedDate, Encrypted, FileId, Format, Name, Query, Size, Status, StatusReason, UpdatedById, UpdatedDate, Zip From Export where Id = '#{id}'"
1322
1105
  end
1323
1106
  end
1324
1107
  end
1325
- result = 'Waiting'
1326
-
1327
- while result != "Completed"
1328
- sleep 3
1329
- response_query = HTTParty.post(self.url, body: confirmRequest.to_xml(:save_with => XML_SAVE_OPTIONS).strip, headers: {'Content-Type' => "application/json; charset=utf-8", "Z-Track-Id" => z_track_id}, :timeout => 120)
1330
-
1331
- output_xml = Nokogiri::XML(response_query.body)
1332
- result = output_xml.xpath('//ns2:Status', 'ns2' =>'http://object.api.zuora.com/').text
1333
- status_code = response_query.code if response_query
1334
-
1335
- raise_errors(type: :SOAP, body: output_xml, response: response_query) if result.blank? || result == "Failed"
1336
- # raise "Export Creation Unsuccessful : #{response_query.code}: #{response_query.parsed_response}" if result.blank? || result == "Failed"
1337
- end
1338
-
1339
- file_id = output_xml.xpath('//ns2:FileId', 'ns2' =>'http://object.api.zuora.com/').text
1340
- export_file = get_file(:url => self.fileURL(file_id))
1341
- export_file_path = export_file.path
1342
- Rails.logger.debug("=====> Export path #{export_file.path}")
1343
-
1344
- if extract && zip
1345
- require "zip"
1346
- new_path = export_file_path.partition('.zip').first
1347
- zipped = Zip::File.open(export_file_path)
1348
- file_handle = zipped.entries.first
1349
- file_handle.extract(new_path)
1350
- File.delete(export_file_path)
1351
- return new_path
1352
- else
1353
- return export_file_path
1354
- end
1355
- rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
1356
- if !(tries -= 1).zero?
1357
- Rails.logger.info("Export call failed - Trace ID: #{z_track_id}")
1358
- self.new_session
1359
- retry
1360
- else
1361
- raise ex
1362
- end
1363
-
1364
- rescue ZuoraAPI::Exceptions::ZuoraUnexpectedError => ex
1365
- if !(tries -= 1).zero?
1366
- Rails.logger.info("Trace ID: #{z_track_id} UnexpectedError, will retry after 10 seconds")
1367
- sleep 10
1368
- retry
1369
- else
1370
- raise ex
1371
- end
1108
+ end
1109
+ result = 'Waiting'
1372
1110
 
1373
- rescue *ZUORA_API_ERRORS => ex
1374
- raise ex
1111
+ while result != "Completed"
1112
+ sleep 3
1113
+ response_query = HTTParty.post(self.url, body: confirmRequest.to_xml(:save_with => XML_SAVE_OPTIONS).strip, headers: {'Content-Type' => "application/json; charset=utf-8"}, :timeout => 120)
1375
1114
 
1376
- rescue *(CONNECTION_EXCEPTIONS + CONNECTION_READ_EXCEPTIONS) => ex
1377
- if !(tries -= 1).zero?
1378
- Rails.logger.info("Trace ID: #{z_track_id} Timed out will retry after 5 seconds")
1379
- sleep 5
1380
- retry
1381
- else
1382
- raise ex
1383
- end
1384
-
1385
- rescue Errno::ECONNRESET => ex
1386
- if !(tries -= 1).zero? && ex.message.include?('SSL_connect')
1387
- retry
1388
- else
1389
- raise ex
1390
- end
1115
+ output_xml = Nokogiri::XML(response_query.body)
1116
+ result = output_xml.xpath('//ns2:Status', 'ns2' =>'http://object.api.zuora.com/').text
1117
+ status_code = response_query.code if response_query
1118
+ raise "Export Creation Unsuccessful : #{output_xml.xpath('//ns1:Message', 'ns1' =>'http://api.zuora.com/').text}" if result.blank? || result == "Failed"
1119
+ end
1391
1120
 
1392
- rescue ZuoraAPI::Exceptions::BadEntityError => ex
1393
- raise ex
1121
+ file_id = output_xml.xpath('//ns2:FileId', 'ns2' =>'http://object.api.zuora.com/').text
1122
+ export_file = get_file(:url => self.fileURL(file_id))
1123
+ export_file_path = export_file.path
1124
+ Rails.logger.debug("=====> Export path #{export_file.path}")
1125
+
1126
+ if extract && zip
1127
+ require "zip"
1128
+ new_path = export_file_path.partition('.zip').first
1129
+ zipped = Zip::File.open(export_file_path)
1130
+ file_handle = zipped.entries.first
1131
+ file_handle.extract(new_path)
1132
+ File.delete(export_file_path)
1133
+ return new_path
1134
+ else
1135
+ return export_file_path
1394
1136
  end
1395
1137
  end
1396
1138
 
@@ -1457,17 +1199,5 @@ module ZuoraAPI
1457
1199
  end
1458
1200
  return "failure"
1459
1201
  end
1460
-
1461
- def reset_files(body)
1462
- return unless body.is_a? Hash
1463
-
1464
- body.transform_values! do |v|
1465
- if v.is_a?(File)
1466
- v.reopen(v.path)
1467
- else
1468
- v
1469
- end
1470
- end
1471
- end
1472
1202
  end
1473
1203
  end