zuora_api 1.4.11 → 1.4.12a

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bdfec52e22872643c4bebaf0180674c09e5a2f60
4
- data.tar.gz: d090db16a0cb99fa37052909bb08bfb87a76c8e1
3
+ metadata.gz: 9c2ff60f716bb9b66d52c5767f031985de537182
4
+ data.tar.gz: 648b9c11245171abd400674c003249bb38306d2f
5
5
  SHA512:
6
- metadata.gz: c7cab09f0e5afc76f8edaf57a6a759d38f1b4731238cfb67e0b2f33f6876192a508f59f08907de3a6b60d7dec1bb3783d2e808bd7f9d44310c9cd592fed14fcf
7
- data.tar.gz: 2f8b5b10781c75f7a628e8cfe2499d937abfa921220bebe68fe23d4f76367188fe356ac5967c9ca46b9a4ca239ae5d226ce246736a095eed3969f0a1867f35eb
6
+ metadata.gz: 97b99413b83727c39068d3e139b39a91d8370235520010167e0bcddd965693cbdb32484e2ea1542b86ef37c7c5550068787a5129108a30a7de01057be724a381
7
+ data.tar.gz: 9d6ef8cb0f11fdf5a911a8e9f97b804b850ca941ec7b940d96b2f2d1d7062e85285dbaf3eb53f87df8980d99724a5f93ddab7e9913fa64cecc2f6f16c99ccc76
@@ -48,3 +48,16 @@ rubygems-deploy:
48
48
  - gem push $version
49
49
  only:
50
50
  - master
51
+
52
+ rubygems-deploy:
53
+ stage: deploy
54
+ allow_failure: false
55
+ when: manual
56
+ script:
57
+ - bundle install
58
+ - gem install rake
59
+ - version=$(rake install | grep -o 'pkg/zuora_api-.*gem')
60
+ - curl -u $USERNAME:$PASSWORD https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials; chmod 0600 ~/.gem/credentials
61
+ - gem push $version
62
+ only:
63
+ - staging
@@ -2,6 +2,7 @@ require 'rails'
2
2
  require "zuora_api/login"
3
3
  require 'zuora_api/exceptions'
4
4
  require "insights_api/login"
5
+ require "zuora_api/metrics_helper"
5
6
  module ZuoraAPI
6
7
  # Your code goes here...
7
8
  end
@@ -1,9 +1,12 @@
1
1
  require "httparty"
2
2
  require "nokogiri"
3
+ require "uri"
4
+
3
5
  module ZuoraAPI
4
6
  class Login
5
7
  ENVIRONMENTS = [SANDBOX = 'Sandbox', PRODUCTION = 'Production', PREFORMANCE = 'Preformance', SERVICES = 'Services', UNKNOWN = 'Unknown' ]
6
8
  REGIONS = [EU = 'EU', US = 'US' ]
9
+ XML_SAVE_OPTIONS = Nokogiri::XML::Node::SaveOptions::AS_XML | Nokogiri::XML::Node::SaveOptions::NO_DECLARATION
7
10
  attr_accessor :username, :password, :region,:url, :wsdl_number, :current_session, :environment, :status, :errors, :current_error, :user_info, :tenant_id, :tenant_name, :entity_id, :timeout_sleep
8
11
 
9
12
  def initialize(username: nil, password: nil, status: nil, url: nil, entity_id: nil, session: nil, **keyword_args)
@@ -40,7 +43,6 @@ module ZuoraAPI
40
43
  }
41
44
  end
42
45
 
43
-
44
46
  def update_environment
45
47
  if !self.url.blank?
46
48
  env_path = self.url.split('https://').last.split('.zuora.com').first
@@ -113,15 +115,15 @@ module ZuoraAPI
113
115
  end
114
116
  end
115
117
  end
116
-
117
118
 
118
- input_xml = Nokogiri::XML(request.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML | Nokogiri::XML::Node::SaveOptions::NO_DECLARATION).strip)
119
+
120
+ input_xml = Nokogiri::XML(request.to_xml(:save_with => XML_SAVE_OPTIONS).strip)
119
121
  input_xml.xpath('//ns1:session', 'ns1' =>'http://api.zuora.com/').children.remove
120
- Rails.logger.debug('Connect') {"Request SOAP XML: #{input_xml.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML | Nokogiri::XML::Node::SaveOptions::NO_DECLARATION).strip}"} if debug
121
-
122
- @response_query = HTTParty.post(self.url,:body => request.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML | Nokogiri::XML::Node::SaveOptions::NO_DECLARATION).strip, :headers => {'Content-Type' => "text/xml; charset=utf-8"}, :timeout => 10)
122
+ Rails.logger.debug('Connect') {"Request SOAP XML: #{input_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}"} if debug
123
+
124
+ @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)
123
125
  @output_xml = Nokogiri::XML(@response_query.body)
124
- Rails.logger.debug('Connect') {"Response SOAP XML: #{@output_xml.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML | Nokogiri::XML::Node::SaveOptions::NO_DECLARATION).strip}"} if debug
126
+ Rails.logger.debug('Connect') {"Response SOAP XML: #{@output_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}"} if debug
125
127
 
126
128
 
127
129
  if !@response_query.success?
@@ -173,16 +175,16 @@ module ZuoraAPI
173
175
  else
174
176
  #If Session only is used for Gem TODO Depercate
175
177
  if (self.password.blank? && self.current_session.present?)
176
- self.current_session = self.current_session
178
+ self.current_session = self.current_session
177
179
  self.username = @output_xml.xpath('//ns1:Username', 'ns1' =>'http://api.zuora.com/').text if self.username.blank?
178
-
180
+
179
181
  #Username & password combo
180
182
  elsif (self.password.present? && self.username.present?)
181
183
  retrieved_session = @output_xml.xpath('//ns1:Session', 'ns1' =>'http://api.zuora.com/').text
182
184
  raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("No session found for api call.") if retrieved_session.blank?
183
185
  self.current_session = retrieved_session
184
186
  end
185
-
187
+
186
188
  self.current_error = nil
187
189
  self.status = 'Active'
188
190
  end
@@ -208,6 +210,9 @@ module ZuoraAPI
208
210
 
209
211
  def soap_call(ns1: 'ns1', ns2: 'ns2', batch_size: nil, single_transaction: false, debug: true, errors: [ZuoraAPI::Exceptions::ZuoraAPISessionError, ZuoraAPI::Exceptions::ZuoraAPIError, ZuoraAPI::Exceptions::ZuoraAPIRequestLimit, ZuoraAPI::Exceptions::ZuoraAPILockCompetition], z_session: true, timeout_retry: false, timeout: 120,**keyword_args)
210
212
  tries ||= 2
213
+ error_type = ""
214
+ start_time = Time.now
215
+
211
216
  xml = Nokogiri::XML::Builder.new do |xml|
212
217
  xml['SOAP-ENV'].Envelope('xmlns:SOAP-ENV' => "http://schemas.xmlsoap.org/soap/envelope/",
213
218
  "xmlns:#{ns2}" => "http://object.api.zuora.com/",
@@ -235,16 +240,18 @@ module ZuoraAPI
235
240
  end
236
241
  end
237
242
 
238
- input_xml = Nokogiri::XML(xml.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML | Nokogiri::XML::Node::SaveOptions::NO_DECLARATION).strip)
243
+ input_xml = Nokogiri::XML(xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip)
239
244
  input_xml.xpath('//ns1:session', 'ns1' =>'http://api.zuora.com/').children.remove
240
- Rails.logger.debug('Connect') {"Request SOAP XML: #{input_xml.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML | Nokogiri::XML::Node::SaveOptions::NO_DECLARATION).strip}"} if debug
241
- response = HTTParty.post(self.url,:body => xml.doc.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML | Nokogiri::XML::Node::SaveOptions::NO_DECLARATION).strip, :headers => {'Content-Type' => "text/xml; charset=utf-8"}, :timeout => timeout)
245
+ Rails.logger.debug('Connect') {"Request SOAP XML: #{input_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}"} if debug
246
+
247
+ 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)
242
248
  output_xml = Nokogiri::XML(response.body)
243
- Rails.logger.debug('Connect') {"Response SOAP XML: #{output_xml.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML | Nokogiri::XML::Node::SaveOptions::NO_DECLARATION).strip}"} if debug
249
+ Rails.logger.debug('Connect') {"Response SOAP XML: #{output_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}"} if debug
244
250
 
245
251
  raise_errors(type: :SOAP, body: output_xml, response: response)
246
-
252
+
247
253
  rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
254
+ error_type = "#{ex.class}"
248
255
  if !(tries -= 1).zero? && z_session
249
256
  Rails.logger.debug {"Session Invalid"}
250
257
  self.new_session
@@ -253,16 +260,18 @@ module ZuoraAPI
253
260
  if errors.include?(ex.class)
254
261
  raise ex
255
262
  else
256
- return [output_xml, input_xml]
263
+ return output_xml, input_xml, response
257
264
  end
258
265
  end
259
266
  rescue ZuoraAPI::Exceptions::ZuoraAPIError, ZuoraAPI::Exceptions::ZuoraAPIRequestLimit, ZuoraAPI::Exceptions::ZuoraAPILockCompetition => ex
267
+ error_type = "#{ex.class}"
260
268
  if errors.include?(ex.class)
261
269
  raise ex
262
270
  else
263
- return [output_xml, input_xml]
271
+ return output_xml, input_xml, response
264
272
  end
265
273
  rescue Net::OpenTimeout, Errno::ECONNRESET, Errno::ECONNREFUSED, SocketError => ex
274
+ error_type = "#{ex.class}"
266
275
  if !(tries -= 1).zero? && timeout_retry
267
276
  Rails.logger.info {"#{ex.class} Timed out will retry after 5 seconds"}
268
277
  sleep(self.timeout_sleep)
@@ -271,15 +280,22 @@ module ZuoraAPI
271
280
  raise ex
272
281
  end
273
282
  rescue => ex
283
+ error_type = "#{ex.class}"
274
284
  raise ex
275
285
  else
276
- return [output_xml, input_xml]
286
+ return output_xml, input_xml, response
287
+ ensure
288
+ # Writing to telegraf
289
+ end_time = Time.now #if exception is caught, need to measure end_time again
290
+ response_time = end_time - start_time
291
+ status_code = response.code if response
292
+ endpoint_name = URI(url).host
293
+ ::MetricsHelpers::MetricsHelpers.write_to_telegraf("response_time": response_time, "status_code": status_code, "endpoint_name": endpoint_name, "direction": "outbound", "error_type": error_type, "function_name": "#{self.class}##{__method__}", "method_name": "POST")
277
294
  end
278
295
 
279
296
  def raise_errors(type: :SOAP, body: nil, response: nil)
280
297
  case type
281
298
  when :SOAP
282
-
283
299
  error = body.xpath('//fns:FaultCode', 'fns' =>'http://fault.api.zuora.com/').text
284
300
  message = body.xpath('//fns:FaultMessage', 'fns' =>'http://fault.api.zuora.com/').text
285
301
 
@@ -287,7 +303,7 @@ module ZuoraAPI
287
303
  error = body.xpath('//faultcode').text
288
304
  message = body.xpath('//faultstring').text
289
305
  end
290
-
306
+
291
307
  if error.blank? || message.blank?
292
308
  error = body.xpath('//ns1:Code', 'ns1' =>'http://api.zuora.com/').text
293
309
  message = body.xpath('//ns1:Message', 'ns1' =>'http://api.zuora.com/').text
@@ -298,9 +314,9 @@ module ZuoraAPI
298
314
  error = []
299
315
  success = []
300
316
  body.xpath('//ns1:result', 'ns1' =>'http://api.zuora.com/').each_with_index do |call, object_index|
301
-
317
+
302
318
  if call.xpath('./ns1:Success', 'ns1' =>'http://api.zuora.com/').text == 'false'
303
- message = "#{call.xpath('./*/ns1:Code', 'ns1' =>'http://api.zuora.com/').text}::#{call.xpath('./*/ns1:Message', 'ns1' =>'http://api.zuora.com/').text}"
319
+ message = "#{call.xpath('./*/ns1:Code', 'ns1' =>'http://api.zuora.com/').text}::#{call.xpath('./*/ns1:Message', 'ns1' =>'http://api.zuora.com/').text}"
304
320
  error.push(message)
305
321
  else
306
322
  success.push(call.xpath('./ns1:Id', 'ns1' =>'http://api.zuora.com/').text)
@@ -312,23 +328,27 @@ module ZuoraAPI
312
328
  if error.present?
313
329
  if error.class == String
314
330
  if error == "INVALID_SESSION"
315
- raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{error}::#{message}", body, response.present? ? response.code : nil )
331
+ raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{error}::#{message}", body, response.code )
316
332
  end
317
333
  if error == "REQUEST_EXCEEDED_LIMIT"
318
- raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new("#{error}::#{message}", body, response.present? ? response.code : nil)
334
+ raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new("#{error}::#{message}", body, response.code)
319
335
  end
320
336
  if error == "LOCK_COMPETITION"
321
- raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("#{error}::#{message}", body, response.present? ? response.code : nil)
337
+ raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("#{error}::#{message}", body, response.code)
322
338
  end
323
339
  if error.present?
324
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{error}::#{message}", body, response.present? ? response.code : nil)
340
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{error}::#{message}", body, response.code)
325
341
  end
326
342
  elsif error.class == Array
327
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new(error.group_by {|v| v}.map {|k,v| "(#{v.size}x) - #{k}"}.join(', '), body, response.present? ? response.code : nil, error, success)
343
+ 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)
328
344
  end
329
345
  end
330
-
331
- when :JSON
346
+
347
+ if response.code == 429
348
+ 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)
349
+ end
350
+
351
+ when :JSON
332
352
  if body.class == Hash && (!body["success"] || !body["Success"] || response.code != 200)
333
353
  messages_array = (body["reasons"] || []).map {|error| error['message']}.compact
334
354
  codes_array = (body["reasons"] || []).map {|error| error['code']}.compact
@@ -354,7 +374,7 @@ module ZuoraAPI
354
374
  end
355
375
 
356
376
  #All Errors catch
357
- if codes_array.size > 0
377
+ if codes_array.size > 0
358
378
  raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{messages_array.join(', ')}", body, response.code)
359
379
  end
360
380
 
@@ -371,7 +391,7 @@ module ZuoraAPI
371
391
  raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{body["faultcode"]}::#{body["faultstring"]}", body, response.code)
372
392
  else
373
393
  raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{body["faultcode"]}::#{body["faultstring"]}", body, response.code)
374
- end
394
+ end
375
395
  end
376
396
 
377
397
  if body["Errors"].present? || body["errors"].present?
@@ -383,20 +403,24 @@ module ZuoraAPI
383
403
  end
384
404
  end
385
405
  end
386
-
406
+
387
407
  #Zuora REST Actions error (Create, Update, Delete)
388
408
  if body.class == Array
389
409
  all_errors = body.select {|obj| !obj['Success'] || !obj['success'] }.map {|obj| obj['Errors'] || obj['errors'] }.compact
390
410
  all_success = body.select {|obj| obj['Success'] || obj['success']}.compact
391
411
 
392
- if all_errors.size > 0
393
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{all_errors.flatten.group_by {|error| error['Message']}.keys.uniq.join(' ')}", body, response.code, all_errors, all_success )
412
+ if all_errors.size > 0
413
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{all_errors.flatten.group_by {|error| error['Message']}.keys.uniq.join(' ')}", body, response.code, all_errors, all_success )
394
414
  end
395
415
  end
396
416
 
397
417
  #All other errors
398
418
  if response.code != 200
399
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{response.message}", body, response.code)
419
+ if response.code == 429
420
+ 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)
421
+ else
422
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{response.message}", body, response.code)
423
+ end
400
424
  end
401
425
  end
402
426
  end
@@ -441,11 +465,16 @@ module ZuoraAPI
441
465
 
442
466
  def describe_call(object = nil)
443
467
  tries ||= 2
468
+
469
+ error_type = ""
470
+ start_time = Time.now
471
+
444
472
  self.get_session
445
473
  base = self.url.include?(".com") ? self.url.split(".com")[0].concat(".com") : self.url.split(".eu")[0].concat(".eu")
446
474
  url = object ? "#{base}/apps/api/describe/#{object}" : "#{base}/apps/api/describe/"
447
475
  headers = !self.entity_id.blank? ? {"entityId" => self.entity_id, 'Content-Type' => "text/xml; charset=utf-8"} : {'Content-Type' => "text/xml; charset=utf-8"}
448
- response = HTTParty.get(url, :headers => headers , basic_auth: {:username => self.username, :password => self.password}, :timeout => 120)
476
+ response = HTTParty.get(url, :headers => headers , basic_auth: {:username => self.username, :password => self.password}, :timeout => 1)
477
+
449
478
  output_xml = Nokogiri::XML(response.body)
450
479
  des_hash = Hash.new
451
480
  if object == nil
@@ -476,6 +505,7 @@ module ZuoraAPI
476
505
  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
477
506
  end
478
507
  rescue Net::ReadTimeout, Net::OpenTimeout, Errno::EPIPE, Errno::ECONNRESET, Errno::ECONNREFUSED, SocketError => ex
508
+ error_type = "#{ex.class}"
479
509
  if !(tries -= 1).zero?
480
510
  Rails.logger.info {"#{ex.class} Timed out will retry after 5 seconds"}
481
511
  sleep(self.timeout_sleep)
@@ -484,18 +514,28 @@ module ZuoraAPI
484
514
  raise ex
485
515
  end
486
516
  rescue => ex
517
+ error_type = "#{ex.class}"
487
518
  raise ex
488
519
  else
489
520
  return des_hash
521
+ ensure
522
+ # Writing to telegraf
523
+ end_time = Time.now
524
+ response_time = end_time - start_time
525
+ status_code = response.code if response
526
+ endpoint_name = URI(url).host
527
+ ::MetricsHelpers::MetricsHelpers.write_to_telegraf("response_time": response_time, "status_code": status_code, "endpoint_name": endpoint_name, "direction": "outbound", "error_type": error_type, "function_name": "#{self.class}##{__method__}", "method_name": "GET")
490
528
  end
491
529
 
492
530
  def rest_call(method: :get, body: {},headers: {}, url: rest_endpoint("catalog/products?pageSize=4"), debug: true, errors: [ZuoraAPI::Exceptions::ZuoraAPISessionError, ZuoraAPI::Exceptions::ZuoraAPIError, ZuoraAPI::Exceptions::ZuoraAPIRequestLimit, ZuoraAPI::Exceptions::ZuoraAPILockCompetition], z_session: true, timeout_retry: false, timeout: 120, **keyword_args)
493
531
  tries ||= 2
494
532
  headers["entityId"] = self.entity_id if !self.entity_id.blank?
495
533
  raise "Method not supported, supported methods include: :get, :post, :put, :delete, :patch, :head, :options" if ![:get, :post, :put, :delete, :patch, :head, :options].include?(method)
534
+
535
+ error_type = ""
536
+ start_time = Time.now
496
537
  response = HTTParty::Request.new("Net::HTTP::#{method.to_s.capitalize}".constantize, url, body: body, headers: {'Content-Type' => "application/json; charset=utf-8"}.merge(z_session ? {"Authorization" => "ZSession #{self.get_session}"} : {}).merge(headers), timeout: timeout).perform
497
538
 
498
- Rails.logger.debug('Connect') {"Response Code: #{response.code}" } if debug
499
539
  begin
500
540
  output_json = JSON.parse(response.body)
501
541
  rescue JSON::ParserError => ex
@@ -506,6 +546,7 @@ module ZuoraAPI
506
546
  raise_errors(type: :JSON, body: output_json, response: response)
507
547
 
508
548
  rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
549
+ error_type = "#{ex.class}"
509
550
  if !(tries -= 1).zero? && z_session
510
551
  Rails.logger.debug {"Session Invalid"}
511
552
  self.new_session
@@ -518,12 +559,14 @@ module ZuoraAPI
518
559
  end
519
560
  end
520
561
  rescue ZuoraAPI::Exceptions::ZuoraAPIError, ZuoraAPI::Exceptions::ZuoraAPIRequestLimit, ZuoraAPI::Exceptions::ZuoraAPILockCompetition => ex
562
+ error_type = "#{ex.class}"
521
563
  if errors.include?(ex.class)
522
564
  raise ex
523
565
  else
524
566
  return [output_json, response]
525
567
  end
526
568
  rescue Net::OpenTimeout, Errno::ECONNRESET, Errno::ECONNREFUSED, SocketError => ex
569
+ error_type = "#{ex.class}"
527
570
  if !(tries -= 1).zero? && timeout_retry
528
571
  Rails.logger.info {"#{ex.class} Timed out will retry after 5 seconds"}
529
572
  sleep(self.timeout_sleep)
@@ -532,9 +575,17 @@ module ZuoraAPI
532
575
  raise ex
533
576
  end
534
577
  rescue => ex
578
+ error_type = "#{ex.class}"
535
579
  raise ex
536
580
  else
537
581
  return [output_json, response]
582
+ ensure
583
+ # Writing to telegraf
584
+ end_time = Time.now
585
+ response_time = end_time - start_time
586
+ status_code = response.code if response
587
+ endpoint_name = URI(url).host
588
+ ::MetricsHelpers::MetricsHelpers.write_to_telegraf("response_time": response_time, "status_code": status_code, "endpoint_name": endpoint_name, "direction": "outbound", "error_type": error_type, "function_name": "#{self.class}##{__method__}", "method_name": "#{method.upcase}")
538
589
  end
539
590
 
540
591
  def update_create_tenant
@@ -590,9 +641,12 @@ module ZuoraAPI
590
641
  require 'fileutils'
591
642
  FileUtils.mkdir_p(file_path) unless File.exists?(file_path)
592
643
 
644
+ error_type = ""
645
+ start_time = Time.now
646
+
593
647
  begin
648
+ status_code = nil
594
649
  uri = URI.parse(url)
595
-
596
650
  http = Net::HTTP.new(uri.host, uri.port)
597
651
  http.read_timeout = timeout #Seconds
598
652
  http.use_ssl = true if uri.scheme.downcase == 'https'
@@ -601,6 +655,8 @@ module ZuoraAPI
601
655
  response_save = nil
602
656
  http.request_get(uri.path, headers) do |response|
603
657
  response_save = response
658
+ status_code = response.code if response
659
+
604
660
  case response
605
661
  when Net::HTTPNotFound
606
662
  Rails.logger.fatal("404 - Not Found")
@@ -686,18 +742,27 @@ module ZuoraAPI
686
742
 
687
743
  file_handle.close
688
744
  Rails.logger.info("Filepath: #{file_handle.path} Size: #{File.size(file_handle.path).to_f/1000000} mb")
689
-
745
+
690
746
  return file_handle
691
747
  end
692
748
  end
693
749
  rescue Exception => e
750
+ error_type = "#{e.class}"
694
751
  Rails.logger.fatal('GetFile') {"Download Failed: #{response_save} - #{e.class} : #{e.message}"}
695
752
  Rails.logger.fatal('GetFile') {"Download Failed: #{e.backtrace.join("\n")}"}
696
753
  raise
754
+ ensure
755
+ # Writing to telegraf
756
+ end_time = Time.now
757
+ response_time = end_time - start_time
758
+ endpoint_name = URI(url).host
759
+ ::MetricsHelpers::MetricsHelpers.write_to_telegraf("response_time": response_time, "status_code": status_code, "endpoint_name": endpoint_name, "direction": "outbound", "error_type": error_type, "function_name": "#{self.class}##{__method__}", "method_name": "GET")
697
760
  end
698
761
  end
699
762
 
700
763
  def getDataSourceExport(query, extract: true, encrypted: false, zip: true)
764
+ error_type = ""
765
+ start_time = Time.now
701
766
  Rails.logger.info('Export') {"Build export"}
702
767
  Rails.logger.debug('Export query') {"#{query}"}
703
768
  request = Nokogiri::XML::Builder.new do |xml|
@@ -720,7 +785,19 @@ module ZuoraAPI
720
785
  end
721
786
  end
722
787
  end
723
- response_query = HTTParty.post(self.url, body: request.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML | Nokogiri::XML::Node::SaveOptions::NO_DECLARATION).strip, headers: {'Content-Type' => "application/json; charset=utf-8"}, :timeout => 120)
788
+
789
+ begin
790
+ 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)
791
+ rescue => e
792
+ error_type = "#{e.class}"
793
+ ensure
794
+ end_time = Time.now
795
+ response_time = end_time - start_time
796
+ status_code = response_query.code if response_query
797
+ endpoint_name = URI(url).host
798
+ ::MetricsHelpers::MetricsHelpers.write_to_telegraf("response_time": response_time, "status_code": status_code, "endpoint_name": endpoint_name, "direction": "outbound", "error_type": error_type, "function_name": "#{self.class}##{__method__}", "method_name": "POST")
799
+ end
800
+
724
801
  output_xml = Nokogiri::XML(response_query.body)
725
802
 
726
803
  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"
@@ -741,15 +818,29 @@ module ZuoraAPI
741
818
  end
742
819
  end
743
820
  result = 'Waiting'
821
+
822
+ start_time = Time.now
823
+ error_type = ""
824
+
744
825
  while result != "Completed"
745
826
  sleep 3
746
- response_query = HTTParty.post(self.url, body: confirmRequest.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML | Nokogiri::XML::Node::SaveOptions::NO_DECLARATION).strip, headers: {'Content-Type' => "application/json; charset=utf-8"}, :timeout => 120)
827
+ begin
828
+ 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)
829
+ rescue => e
830
+ error_type = "#{e.class}"
831
+ end
747
832
  output_xml = Nokogiri::XML(response_query.body)
748
-
749
833
  result = output_xml.xpath('//ns2:Status', 'ns2' =>'http://object.api.zuora.com/').text
834
+ status_code = response_query.code if response_query
750
835
  raise "Export Creation Unsuccessful : #{output_xml.xpath('//ns1:Message', 'ns1' =>'http://api.zuora.com/').text}" if result.blank? || result == "Failed"
751
836
  end
752
837
 
838
+ end_time = Time.now
839
+ response_time = end_time - start_time
840
+ endpoint_name = URI(url).host
841
+ ::MetricsHelpers::MetricsHelpers.write_to_telegraf("response_time": response_time, "status_code": status_code, "endpoint_name": endpoint_name, "direction": "outbound", "error_type": error_type, "function_name": "#{self.class}##{__method__}", "method_name": "POST")
842
+
843
+
753
844
  file_id = output_xml.xpath('//ns2:FileId', 'ns2' =>'http://object.api.zuora.com/').text
754
845
  Rails.logger.info('Export') {'=====> Export finished'}
755
846
  export_file = get_file(:url => self.fileURL(file_id))
@@ -777,7 +868,7 @@ module ZuoraAPI
777
868
  end
778
869
  end
779
870
  if parse
780
- return [] if output_xml.xpath('//ns1:size', 'ns1' =>'http://api.zuora.com/').text == '0'
871
+ return [] if output_xml.xpath('//ns1:size', 'ns1' =>'http://api.zuora.com/').text == '0'
781
872
  data = output_xml.xpath('//ns1:records', 'ns1' =>'http://api.zuora.com/').map {|record| record.children.map {|element| [element.name, element.text]}.to_h}
782
873
  return data
783
874
  else
@@ -786,14 +877,29 @@ module ZuoraAPI
786
877
  end
787
878
 
788
879
  def createJournalRun(call)
880
+ error_type = ""
881
+ start_time = Time.now
882
+
789
883
  url = rest_endpoint("/journal-runs")
790
884
  uri = URI(url)
791
885
  req = Net::HTTP::Post.new(uri,initheader = {'Content-Type' =>'application/json'})
792
886
  req.basic_auth self.username, self.password
793
887
  req.body = call
794
- response = Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
795
- http.request req
888
+
889
+ begin
890
+ response = Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
891
+ http.request req
892
+ end
893
+ rescue => e
894
+ error_type = "#{e.class}"
895
+ ensure
896
+ end_time = Time.now
897
+ response_time = end_time - start_time
898
+ status_code = response.code if response
899
+ endpoint_name = URI(url).host
900
+ ::MetricsHelpers::MetricsHelpers.write_to_telegraf("response_time": response_time, "status_code": status_code, "endpoint_name": endpoint_name, "direction": "outbound", "error_type": error_type, "function_name": "#{self.class}##{__method__}", "method_name": "POST")
796
901
  end
902
+
797
903
  Rails.logger.debug('Journal Run') {"Response #{response.code} #{response.message}:
798
904
  #{response.body}"}
799
905
 
@@ -806,17 +912,35 @@ module ZuoraAPI
806
912
  Rails.logger.debug('Journal Run') {"Journal Run failed with message #{message}"}
807
913
  return result
808
914
  end
915
+
809
916
  end
810
917
 
811
918
  def checkJRStatus(jrNumber)
919
+ error_type = ""
920
+
812
921
  Rails.logger.info('Journal Run') {"Check for completion"}
922
+
923
+ start_time = Time.now
924
+
813
925
  url = rest_endpoint("/journal-runs/#{jrNumber}")
814
926
  uri = URI(url)
815
927
  req = Net::HTTP::Get.new(uri,initheader = {'Content-Type' =>'application/json'})
816
928
  req.basic_auth self.username, self.password
817
- response = Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
818
- http.request req
929
+
930
+ begin
931
+ response = Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
932
+ http.request req
933
+ end
934
+ rescue => e
935
+ error_type = "#{e.class}"
936
+ ensure
937
+ end_time = Time.now
938
+ response_time = end_time - start_time
939
+ status_code = response.code if response
940
+ endpoint_name = URI(url).host
941
+ ::MetricsHelpers::MetricsHelpers.write_to_telegraf("response_time": response_time, "status_code": status_code, "endpoint_name": endpoint_name, "direction": "outbound", "error_type": error_type, "function_name": "#{self.class}##{__method__}", "method_name": "GET")
819
942
  end
943
+
820
944
  result = JSON.parse(response.body)
821
945
 
822
946
  if result["success"]
@@ -0,0 +1,12 @@
1
+ module MetricsHelpers
2
+
3
+ class MetricsHelpers
4
+ def self.write_to_telegraf(response_time: nil, status_code: nil, endpoint_name: nil, direction: nil, error_type: nil, function_name: nil, method_name: nil)
5
+ if Gem.loaded_specs.has_key?('zuora_connect') && defined?(::ZuoraConnect::AppInstance.write_to_telegraf)
6
+ Thread.current[:appinstance].present? ? app_instance = Thread.current[:appinstance].id : app_instance = 0
7
+ ZuoraConnect::AppInstanceBase.write_to_telegraf("response_time": response_time, "status_code": status_code, "endpoint_name": endpoint_name, "direction": "outbound", "error_type": error_type, "app_instance": app_instance, "function_name": function_name, "method_name": method_name)
8
+ end
9
+ end
10
+ end
11
+
12
+ end
@@ -1,3 +1,3 @@
1
1
  module ZuoraAPI
2
- VERSION = "1.4.11"
2
+ VERSION = "1.4.12a"
3
3
  end
@@ -27,4 +27,5 @@ Gem::Specification.new do |spec|
27
27
  spec.add_dependency("httparty")
28
28
  spec.add_dependency("rubyzip")
29
29
  spec.add_dependency("railties", ">= 4.1.0", "< 5.1")
30
+ spec.add_dependency('telegraf', '~> 0.4.0') # Add dependency for telegraf
30
31
  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.4.11
4
+ version: 1.4.12a
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: 2018-04-23 00:00:00.000000000 Z
11
+ date: 2018-08-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -142,6 +142,20 @@ dependencies:
142
142
  - - "<"
143
143
  - !ruby/object:Gem::Version
144
144
  version: '5.1'
145
+ - !ruby/object:Gem::Dependency
146
+ name: telegraf
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - "~>"
150
+ - !ruby/object:Gem::Version
151
+ version: 0.4.0
152
+ type: :runtime
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: 0.4.0
145
159
  description: Gem that provides easy integration to Zuora
146
160
  email:
147
161
  - connect@zuora.com
@@ -163,6 +177,7 @@ files:
163
177
  - lib/zuora_api.rb
164
178
  - lib/zuora_api/exceptions.rb
165
179
  - lib/zuora_api/login.rb
180
+ - lib/zuora_api/metrics_helper.rb
166
181
  - lib/zuora_api/version.rb
167
182
  - zuora_api.gemspec
168
183
  homepage: https://connect.zuora.com
@@ -179,9 +194,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
179
194
  version: '0'
180
195
  required_rubygems_version: !ruby/object:Gem::Requirement
181
196
  requirements:
182
- - - ">="
197
+ - - ">"
183
198
  - !ruby/object:Gem::Version
184
- version: '0'
199
+ version: 1.3.1
185
200
  requirements: []
186
201
  rubyforge_project:
187
202
  rubygems_version: 2.6.8