zuora_api 1.6.3b → 1.6.03

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 7a5f3d85642928cb6296595c0d644bb39a4a91543d08536ce8cd500cfb848b60
4
- data.tar.gz: bd2b2670f4997b05ddd9ad8f0be6be3c5376b5b373d68d695491d9d7a22249fe
2
+ SHA1:
3
+ metadata.gz: b6080a42e4f36dd631e4f6891dcdeda528462a0b
4
+ data.tar.gz: d347833d58451c496186bd0dd089a8919a271e0b
5
5
  SHA512:
6
- metadata.gz: 59356375be3c396d05309b29859ece9d961312ad774abeb5f0138f89a29e004371cce349315ec53b8bf16230dd679e106bae18f629a9cadd0522d2c44dfcc096
7
- data.tar.gz: e2b094fe4d063f7719a2f428290111e20e7e505a709522e71b885f662459534e2eb914c80e1e3d4635f9dc266cabf0d35fcae0b25495a50e4dc56dc8be85734e
6
+ metadata.gz: 927346daacd2e830f8e8460d18de45e9315d21cd6cb7a0f214edef3225925b5ce73a7d4d3423e6d78ebb21220c072ad3b0375d27256a7a02e6514a310ada8e11
7
+ data.tar.gz: 596e78be771998f9f8ef852d410ea407c1c9e65c8fadd8388d53bd18f97b30c1fc777f00d050f879dc91a0f343726d45073e5058cc2e626b9b953f7863b02525
data/.gitlab-ci.yml CHANGED
@@ -1,4 +1,5 @@
1
- image: ruby:2.6
1
+
2
+ image: ruby:2.3.1
2
3
  stages:
3
4
  - setup
4
5
  - test
@@ -40,24 +41,10 @@ rubygems-deploy:
40
41
  stage: deploy
41
42
  allow_failure: false
42
43
  script:
43
- - echo "deb http://ftp.us.debian.org/debian testing main contrib non-free" >> /etc/apt/sources.list
44
- - apt-get update
45
- - apt-get install -y git
46
- - apt-get clean all
47
- - gem install dpl
48
- - if [[ "staging" == $CI_BUILD_REF_SLUG ]];then export VERSION=`git describe --match "[0-9]*\.[0-9]*\.[0-9]*[a-z]" --abbrev=0 --tags HEAD`; fi
49
- - if [[ "master" == $CI_BUILD_REF_SLUG ]];then export VERSION=`git describe --exclude "[0-9]*\.[0-9]*\.[0-9]*[a-z]" --abbrev=0 --tags HEAD`; fi
50
- - echo $VERSION
51
- - sed -i "s/0.0.1/$VERSION/" /Connect/zuora-gem/lib/zuora_api/version.rb
52
- - git add /Connect/zuora-gem/lib/zuora_api/version.rb
53
- - git config --global user.email "connect@zuora.com"
54
- - git config --global user.name "Connect Automation"
55
- - git commit -m "Automated Version Update $VERSION"
56
44
  - bundle install
57
45
  - gem install rake
58
46
  - version=$(rake install | grep -o 'pkg/zuora_api-.*gem')
59
47
  - curl -u $USERNAME:$PASSWORD https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials; chmod 0600 ~/.gem/credentials
60
48
  - gem push $version
61
49
  only:
62
- - master
63
- - staging
50
+ - master
@@ -42,7 +42,7 @@ module InsightsAPI
42
42
  if status['status']== "COMPLETE"
43
43
  signedUrl = status['signedUrl']
44
44
  return status
45
- elsif status['status'] == "FAILED" || status['status'] == "ERROR"
45
+ elsif status['status'] == "FAILED"
46
46
  return status
47
47
  else
48
48
  sleep(60)
@@ -86,21 +86,6 @@ module ZuoraAPI
86
86
  end
87
87
  end
88
88
 
89
- class ZuoraAPITemporaryError < Error
90
- attr_reader :code, :response
91
- attr_writer :default_message
92
-
93
- def initialize(message = nil,response=nil, code =nil)
94
- @code = code
95
- @message = message
96
- @response = response
97
- @default_message = "There is a temporary error with zuora system."
98
- end
99
-
100
- def to_s
101
- @message || @default_message
102
- end
103
- end
104
89
 
105
90
  class ZuoraAPIAuthenticationTypeError < Error
106
91
  attr_reader :code, :response
@@ -4,203 +4,22 @@ require "uri"
4
4
 
5
5
  module ZuoraAPI
6
6
  class Login
7
- ENVIRONMENTS = [SANDBOX = 'Sandbox', PRODUCTION = 'Production', PREFORMANCE = 'Preformance', SERVICES = 'Services', UNKNOWN = 'Unknown', STAGING = 'Staging' ]
8
- REGIONS = [EU = 'EU', US = 'US', NA = 'NA' ]
9
- MIN_Endpoint = '91.0'
10
- XML_SAVE_OPTIONS = Nokogiri::XML::Node::SaveOptions::AS_XML | Nokogiri::XML::Node::SaveOptions::NO_DECLARATION
11
- CONNECTION_EXCEPTIONS = [Net::OpenTimeout, OpenSSL::SSL::SSLError, Errno::ECONNREFUSED, SocketError]
12
- CONNECTION_READ_EXCEPTIONS = [Net::ReadTimeout, Errno::ECONNRESET, Errno::EPIPE]
13
-
14
- attr_accessor :region, :url, :wsdl_number, :current_session, :environment, :status, :errors, :current_error, :user_info, :tenant_id, :tenant_name, :entity_id, :timeout_sleep, :hostname, :zconnect_provider
7
+ ENVIRONMENTS = [SANDBOX = 'Sandbox', PRODUCTION = 'Production', PREFORMANCE = 'Preformance', SERVICES = 'Services', UNKNOWN = 'Unknown' ]
8
+ REGIONS = [EU = 'EU', US = 'US' ]
9
+ XML_SAVE_OPTIONS = Nokogiri::XML::Node::SaveOptions::AS_XML | Nokogiri::XML::Node::SaveOptions::NO_DECLARATION
10
+ attr_accessor :region, :url, :wsdl_number, :current_session, :environment, :status, :errors, :current_error, :user_info, :tenant_id, :tenant_name, :entity_id, :timeout_sleep
15
11
 
16
12
  def initialize(url: nil, entity_id: nil, session: nil, status: nil, **keyword_args)
17
- raise "URL is nil or empty, but URL is required" if url.nil? || url.empty?
18
- # raise "URL is improper. URL must contain zuora.com, zuora.eu, or zuora.na" if /zuora.com|zuora.eu|zuora.na/ === url
19
- @url = url.gsub(/(\d{2}\.\d)$/, MIN_Endpoint)
20
- @hostname = /(?<=https:\/\/|http:\/\/)(.*?)(?=\/|$)/.match(url)[0] if !/(?<=https:\/\/|http:\/\/)(.*?)(?=\/|$)/.match(url).nil?
21
- @entity_id = get_entity_id(entity_id: entity_id)
13
+ @url = url
14
+ @entity_id = entity_id
22
15
  @errors = Hash.new
23
16
  @current_session = session
24
17
  @status = status.blank? ? "Active" : status
25
18
  @user_info = Hash.new
26
- self.update_region
27
19
  self.update_environment
28
- self.update_zconnect_provider
29
20
  @timeout_sleep = 5
30
21
  end
31
22
 
32
- def get_identity(cookies)
33
- zsession = cookies["ZSession"]
34
- zconnect_accesstoken = get_zconnect_accesstoken(cookies)
35
- begin
36
- if !zsession.blank?
37
- response = HTTParty.get("https://#{self.hostname}/apps/v1/identity", :headers => {'Cookie' => "ZSession=#{zsession}", 'Content-Type' => 'application/json'})
38
- output_json = JSON.parse(response.body)
39
- elsif !zconnect_accesstoken.blank?
40
- code = zconnect_accesstoken.split("#!").last
41
- encrypted_token, tenant_id = Base64.decode64(code).split(":")
42
- begin
43
- body = {'token' => encrypted_token}.to_json
44
- rescue => ex
45
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Invalid ZConnect Cookie", {}, 400)
46
- end
47
- response = HTTParty.post("https://#{self.hostname}/apps/zconnectsession/identity", :body => body, :headers => { 'Content-Type' => 'application/json' })
48
- output_json = JSON.parse(response.body)
49
- else
50
- if zconnect_accesstoken.blank? && cookies.keys.any? { |x| x.include? "ZConnect"}
51
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZConnect cookie present matching #{self.hostname}", {}, 400)
52
- else
53
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present", {}, 400)
54
- end
55
- end
56
- rescue JSON::ParserError => ex
57
- output_json = {}
58
- end
59
- raise_errors(type: :JSON, body: output_json, response: response)
60
- return output_json
61
- end
62
-
63
- def get_full_nav(cookies)
64
- zsession = cookies["ZSession"]
65
- zconnect_accesstoken = get_zconnect_accesstoken(cookies)
66
- begin
67
- if !zsession.blank?
68
- response = HTTParty.get("https://#{self.hostname}/apps/v1/navigation", :headers => {'Cookie' => "ZSession=#{zsession}", 'Content-Type' => 'application/json'})
69
- output_json = JSON.parse(response.body)
70
- elsif !zconnect_accesstoken.blank?
71
- response = HTTParty.get("https://#{self.hostname}/apps/zconnectsession/navigation", :headers => {'Cookie' => "#{self.zconnect_provider}=#{zconnect_accesstoken}",'Content-Type' => 'application/json'})
72
- output_json = JSON.parse(response.body)
73
- else
74
- if zconnect_accesstoken.blank? && cookies.keys.any? { |x| x.include? "ZConnect"}
75
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZConnect cookie present matching #{self.hostname}", {}, 400)
76
- else
77
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present", {}, 400)
78
- end
79
- end
80
- rescue JSON::ParserError => ex
81
- output_json = {}
82
- end
83
- raise_errors(type: :JSON, body: output_json, response: response)
84
- return output_json
85
- end
86
-
87
- def set_nav(state, cookies)
88
- zsession = cookies["ZSession"]
89
- zconnect_accesstoken = get_zconnect_accesstoken(cookies)
90
- begin
91
- if !zsession.blank?
92
- response = HTTParty.put("https://#{self.hostname}/apps/v1/preference/navigation", :body => state.to_json, :headers => {'Cookie' => "ZSession=#{zsession}", 'Content-Type' => 'application/json'})
93
- output_json = JSON.parse(response.body)
94
- elsif !zconnect_accesstoken.blank?
95
- response = HTTParty.post("https://#{self.hostname}/apps/zconnectsession/navigationstate", :body => state.to_json, :headers => {'Cookie' => "#{self.zconnect_provider}=#{zconnect_accesstoken}", 'Content-Type' => 'application/json'})
96
- output_json = JSON.parse(response.body)
97
- else
98
- if zconnect_accesstoken.blank? && cookies.keys.any? { |x| x.include? "ZConnect"}
99
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZConnect cookie present matching #{self.hostname}", {}, 400)
100
- else
101
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present", {}, 400)
102
- end
103
- end
104
- rescue JSON::ParserError => ex
105
- output_json = {}
106
- end
107
- raise_errors(type: :JSON, body: output_json, response: response)
108
- return output_json
109
- end
110
-
111
- def refresh_nav(cookies)
112
- zsession = cookies["ZSession"]
113
- zconnect_accesstoken = get_zconnect_accesstoken(cookies)
114
- begin
115
- if !zsession.blank?
116
- response = HTTParty.post("https://#{self.hostname}/apps/v1/navigation/fetch", :headers => {'Cookie' => "ZSession=#{zsession}", 'Content-Type' => 'application/json'})
117
- output_json = JSON.parse(response.body)
118
- elsif !zconnect_accesstoken.blank?
119
- response = HTTParty.post("https://#{self.hostname}/apps/zconnectsession/refresh-navbarcache", :headers => {'Cookie' => "#{self.zconnect_provider}=#{zconnect_accesstoken}", 'Content-Type' => 'application/json'})
120
- output_json = JSON.parse(response.body)
121
- else
122
- if zconnect_accesstoken.blank? && cookies.keys.any? { |x| x.include? "ZConnect"}
123
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZConnect cookie present matching #{self.hostname}", {}, 400)
124
- else
125
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present", {}, 400)
126
- end
127
- end
128
- rescue JSON::ParserError => ex
129
- output_json = {}
130
- end
131
- raise_errors(type: :JSON, body: output_json, response: response)
132
- return output_json
133
- end
134
-
135
- def get_zconnect_accesstoken(cookies)
136
- accesstoken = nil
137
- self.update_zconnect_provider
138
- if !cookies[self.zconnect_provider].nil? && !cookies[self.zconnect_provider].empty?
139
- accesstoken = cookies[self.zconnect_provider]
140
- end
141
- return accesstoken
142
- end
143
-
144
- def reporting_url(path)
145
- map = {"US" => {"Sandbox" => "https://zconnectsandbox.zuora.com/api/rest/v1/",
146
- "Production" => "https://zconnect.zuora.com/api/rest/v1/",
147
- "Services"=> ""},
148
- "EU" => {"Sandbox" => "https://zconnect.sandbox.eu.zuora.com/api/rest/v1/",
149
- "Production" => "https://zconnect.eu.zuora.com/api/rest/v1/",
150
- "Services"=> ""},
151
- "NA" => {"Sandbox" => "https://zconnect.sandbox.na.zuora.com/api/rest/v1/",
152
- "Production" => "https://zconnect.na.zuora.com/api/rest/v1/",
153
- "Services"=> ""}
154
- }
155
- return map[zuora_client.region][zuora_client.environment].insert(-1, path)
156
- end
157
-
158
- # There are two ways to call this method. The first way is best.
159
- # 1. Pass in cookies and optionally custom_authorities, name, and description
160
- # 2. Pass in user_id, entity_ids, client_id, client_secret, and optionally custom_authorities, name, and description
161
- # https://intranet.zuora.com/confluence/display/Sunburst/Create+an+OAuth+Client+through+API+Gateway#CreateanOAuthClientthroughAPIGateway-ZSession
162
- def get_oauth_client (custom_authorities = [], info_name: "No Name", info_desc: "This client was created without a description.", user_id: nil, entity_ids: nil, client_id: nil, client_secret: nil, new_client_id: nil, new_client_secret: nil, cookies: nil)
163
- authorization = ""
164
- new_client_id = SecureRandom.uuid if new_client_id.blank?
165
- new_client_secret = SecureRandom.hex(10) if new_client_secret.blank?
166
-
167
- if !cookies.nil?
168
- authorization = cookies["ZSession"]
169
- authorization = "ZSession-a3N2w #{authorization}"
170
- if entity_ids.blank? && cookies["ZuoraCurrentEntity"].present?
171
- entity_ids = Array(cookies["ZuoraCurrentEntity"].unpack("a8a4a4a4a12").join('-'))
172
- else
173
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Zuora Entity ID not provided", {}, 400)
174
- end
175
- if user_id.blank? && cookies["Zuora-User-Id"].present?
176
- user_id = cookies["Zuora-User-Id"]
177
- else
178
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Zuora User ID not provided", {}, 400)
179
- end
180
- elsif !client_id.nil? && !client_secret.nil?
181
- bearer_response = HTTParty.post("https://#{self.hostname}/oauth/token", :headers => {'Content-Type' => 'application/x-www-form-urlencoded', 'Accept' => 'application/json'}, :body => {'client_id' => client_id, 'client_secret' => URI::encode(client_secret), 'grant_type' => 'client_credentials'})
182
- bearer_hash = JSON.parse(bearer_response.body)
183
- bearer_token = bearer_hash["access_token"]
184
- authorization = "Bearer #{bearer_token}"
185
- end
186
-
187
- if !authorization.blank? && !user_id.blank? && !entity_ids.blank?
188
- endpoint = self.rest_endpoint("genesis/clients")
189
- oauth_response = HTTParty.post(endpoint, :headers => {'authorization' => authorization, 'Content-Type' => 'application/json'}, :body => {'clientId' => new_client_id, 'clientSecret' => new_client_secret, 'userId' => user_id, 'entityIds' => entity_ids, 'customAuthorities' => custom_authorities, 'additionalInformation' => {'description' => info_desc, 'name' => info_name}}.to_json)
190
- output_json = JSON.parse(oauth_response.body)
191
- if oauth_response.code == 201
192
- output_json["clientSecret"] = new_client_secret
193
- return output_json
194
- elsif oauth_response.code == 401 && !oauth_response.message.blank?
195
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new(output_json["message"], {}, oauth_response.code)
196
- else
197
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new(output_json["error"], {}, oauth_response.code)
198
- end
199
- else
200
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Insufficient credentials provided", {}, 400)
201
- end
202
- end
203
-
204
23
  def self.environments
205
24
  %w(Sandbox Production Services Performance Staging)
206
25
  end
@@ -213,8 +32,7 @@ module ZuoraAPI
213
32
  return {"US" => {"Sandbox" => "https://apisandbox.zuora.com/apps/services/a/",
214
33
  "Production" => "https://www.zuora.com/apps/services/a/",
215
34
  "Performance" => "https://pt1.zuora.com/apps/services/a/",
216
- "Services" => "https://services347.zuora.com/apps/services/a/",
217
- "Staging" => "https://staging2.zuora.com/apps/services/a/"},
35
+ "Services" => "https://services347.zuora.com/apps/services/a/"},
218
36
  "EU" => {"Sandbox" => "https://sandbox.eu.zuora.com/apps/services/a/",
219
37
  "Production" => "https://eu.zuora.com/apps/services/a/",
220
38
  "Performance" => "https://pt1.eu.zuora.com/apps/services/a/",
@@ -226,119 +44,43 @@ module ZuoraAPI
226
44
  }
227
45
  end
228
46
 
229
- def get_entity_id(entity_id: nil)
230
- if entity_id.present?
231
- entity_match = /[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}$/.match(entity_id)
232
- if entity_match.blank?
233
- raise "Entity length is wrong." if entity_id.length != 32
234
- part_one, part_two, part_three, part_four, part_five = [entity_id[0..7], entity_id[8..11], entity_id[12..15], entity_id[16..19], entity_id[20..31]]
235
- entity_id = "#{part_one}-#{part_two}-#{part_three}-#{part_four}-#{part_five}"
236
- end
237
- end
238
- return entity_id
239
- end
240
-
241
- def update_region
242
- if !self.hostname.blank?
243
- if /(?<=\.|\/|^)(eu)(?=\.|\/|$)/ === self.hostname
244
- self.region = "EU"
245
- elsif /(?<=\.|\/|^)(na)(?=\.|\/|$)/ === self.hostname
246
- self.region = "NA"
247
- else
248
- self.region = "US"
249
- end
250
- else # This will never happen
251
- # raise "Can't update region because URL is blank"
252
- self.region = "Unknown"
253
- end
254
- end
255
-
256
47
  def update_environment
257
48
  if !self.url.blank?
258
- if /(?<=\.|\/|-|^)(apisandbox|sandbox)(?=\.|\/|-|$)/ === self.hostname
49
+ env_path = self.url.split('https://').last.split('.zuora.com').first
50
+ self.region = self.url.include?("eu.") ? "EU" : self.url.include?("na.") ? "NA" : "US"
51
+ if env_path == 'apisandbox' || self.url.include?('sandbox')
259
52
  self.environment = 'Sandbox'
260
- elsif /(?<=\.|\/|^)(service|services[\d]*|ep-edge)(?=\.|\/|$)/ === self.hostname
53
+ elsif env_path == 'www' || env_path == 'api' || self.url.include?('tls10.zuora.com') || self.url.include?('origin-www.zuora.com') || self.url.include?('zforsf.zuora.com') || self.url.include?('https://zuora.com') || self.url.include?('eu.zuora.com') || self.url.include?('https://na.zuora.com')
54
+ self.environment = 'Production'
55
+ elsif env_path.include?('service') || env_path.include?('ep-edge')
261
56
  self.environment = 'Services'
262
- elsif /(?<=\.|\/|-|^)(pt[\d]*)(?=\.|\/|-|$)/ === self.hostname
57
+ elsif env_path.include?('pt')
263
58
  self.environment = 'Performance'
264
- elsif /(?<=\.|\/|^)(staging1|staging2|stg)(?=\.|\/|$)/ === self.hostname
59
+ elsif env_path.include?('staging2') || env_path.include?('staging1')
60
+ self.region = 'US'
265
61
  self.environment = 'Staging'
266
- elsif is_prod_env
267
- self.environment = 'Production'
268
62
  else
269
63
  self.environment = 'Unknown'
270
64
  end
271
- else # this will never happen
272
- raise "Can't determine environment from blank URL"
273
- end
274
- end
275
-
276
- def is_prod_env
277
- is_prod = false
278
- www_or_api = /(?<=\.|\/|^)(www|api)(?=\.|\/|$)/ === self.hostname
279
- host_prefix_match = /(^|tls10\.|origin-www\.|zforsf\.|eu\.|na\.)(zuora\.com)/ === self.hostname
280
- if www_or_api || host_prefix_match
281
- is_prod = true
282
65
  end
283
- return is_prod
284
- end
285
-
286
- def update_zconnect_provider
287
- region = update_region
288
- environment = update_environment
289
- mappings = {"US" => {"Sandbox" => "ZConnectSbx", "KubeSTG" => "ZConnectDev", "KubeDEV" => "ZConnectDev", "KubePROD" => "ZConnectDev", "Services" => "ZConnectQA", "Production" => "ZConnectProd", "Performance" => "ZConnectPT1", "Staging" => "ZConnectQA"},
290
- "NA" => {"Sandbox" => "ZConnectSbxNA", "Services" => "ZConnectQANA", "Production" => "ZConnectProdNA", "Performance" => "ZConnectPT1NA"},
291
- "EU" => {"Sandbox" => "ZConnectSbxEU", "Services" => "ZConnectQAEU", "Production" => "ZConnectProdEU", "Performance" => "ZConnectPT1EU"},
292
- "Unknown" => {"Unknown" => "Unknown"}}
293
- self.zconnect_provider = mappings[region][environment]
294
- # raise "Can't find ZConnect Provider for #{region} region and #{environment} environment" if self.zconnect_provider.nil?
295
66
  end
296
67
 
297
68
  def aqua_endpoint(url="")
298
- match = /.*(\/apps\/)/.match(self.url)
299
- if !match.nil?
300
- url_slash_apps_slash = match[0]
301
- else
302
- raise "self.url has no /apps in it"
303
- end
304
- return "#{url_slash_apps_slash}api/#{url}"
69
+ return "#{self.url.split("/apps").first}/apps/api/".concat(url)
305
70
  end
306
71
 
307
72
  def rest_endpoint(url="")
308
- update_environment
309
- endpoint = url
310
-
311
- case self.environment
312
- when 'Sandbox'
313
- case self.region
314
- when 'US'
315
- endpoint = "https://rest.apisandbox.zuora.com/v1/".concat(url)
316
- when 'EU'
317
- endpoint = "https://rest.sandbox.eu.zuora.com/v1/".concat(url)
318
- when 'NA'
319
- endpoint = "https://rest.sandbox.na.zuora.com/v1/".concat(url)
320
- end
321
- when 'Production'
322
- case self.region
323
- when 'US'
324
- endpoint = "https://rest.zuora.com/v1/".concat(url)
325
- when 'EU'
326
- endpoint = "https://rest.eu.zuora.com/v1/".concat(url)
327
- when 'NA'
328
- endpoint = "https://rest.na.zuora.com/v1/".concat(url)
329
- end
330
- when 'Performance'
331
- endpoint = "https://rest.pt1.zuora.com/v1/".concat(url)
332
- when 'Services'
333
- https = /https:\/\/|http:\/\//.match(self.url)[0]
334
- host = self.hostname
335
- endpoint = "#{https}#{host}/apps/v1/#{url}"
336
- when 'Staging'
337
- endpoint = "https://rest-staging2.zuora.com/".concat(url)
338
- when 'Unknown'
339
- raise "Environment unknown, returning passed in parameter unaltered"
73
+ if self.environment == 'Sandbox'
74
+ return self.region == "US" ? "https://rest.apisandbox.zuora.com/v1/".concat(url) : self.region == "EU" ? "https://rest.sandbox.eu.zuora.com/v1/".concat(url) : "https://rest.sandbox.na.zuora.com/v1/".concat(url)
75
+ elsif self.environment == 'Production'
76
+ return self.region == "US" ? "https://rest.zuora.com/v1/".concat(url) : self.region == "EU" ? "https://rest.eu.zuora.com/v1/".concat(url) : "https://rest.na.zuora.com/v1/".concat(url)
77
+ elsif self.environment == 'Services'
78
+ return self.url.split('/')[0..2].join('/').concat('/apps/v1/').concat(url)
79
+ elsif self.environment == 'Performance'
80
+ return self.url.split('/')[0..2].join('/').concat('/apps/v1/').concat(url)
81
+ else self.environment == 'Unknown'
82
+ return url
340
83
  end
341
- return endpoint
342
84
  end
343
85
 
344
86
  def fileURL(url="")
@@ -349,14 +91,15 @@ module ZuoraAPI
349
91
  return self.wsdl_number > 68 ? '%Y-%m-%d' : '%Y-%m-%dT%H:%M:%S'
350
92
  end
351
93
 
352
- def new_session(auth_type: :basic, debug: false)
94
+ def new_session(auth_type: :basic, debug: false)
353
95
  end
354
96
 
355
97
  def get_session(prefix: false, auth_type: :basic)
356
- Rails.logger.debug("Get session for #{auth_type} - #{self.class.to_s}") if Rails.env.to_s == 'development'
98
+ Rails.logger.debug("Get session for #{auth_type} - #{self.class.to_s}")
357
99
  case auth_type
358
100
  when :basic
359
101
  if self.current_session.blank?
102
+ Rails.logger.debug("Create new session")
360
103
  case self.class.to_s
361
104
  when 'ZuoraAPI::Oauth'
362
105
  if self.bearer_token.blank? || self.oauth_expired?
@@ -441,15 +184,7 @@ module ZuoraAPI
441
184
  else
442
185
  return output_xml, input_xml, response
443
186
  end
444
- rescue *CONNECTION_EXCEPTIONS => ex
445
- if !(tries -= 1).zero?
446
- Rails.logger.info("SOAP Call - #{ex.class} Timed out will retry after 5 seconds")
447
- sleep(self.timeout_sleep)
448
- retry
449
- else
450
- raise ex
451
- end
452
- rescue *CONNECTION_READ_EXCEPTIONS => ex
187
+ rescue Net::OpenTimeout, Errno::ECONNRESET, OpenSSL::SSL::SSLError, Errno::ECONNREFUSED, SocketError => ex
453
188
  if !(tries -= 1).zero? && timeout_retry
454
189
  Rails.logger.info("SOAP Call - #{ex.class} Timed out will retry after 5 seconds")
455
190
  sleep(self.timeout_sleep)
@@ -484,7 +219,8 @@ module ZuoraAPI
484
219
  error = []
485
220
  success = []
486
221
  body.xpath('//ns1:result', 'ns1' =>'http://api.zuora.com/').each_with_index do |call, object_index|
487
- if call.xpath('./ns1:Success', 'ns1' =>'http://api.zuora.com/').text == 'false' && call.xpath('./ns1:Errors', 'ns1' =>'http://api.zuora.com/').size > 0
222
+
223
+ if call.xpath('./ns1:Success', 'ns1' =>'http://api.zuora.com/').text == 'false'
488
224
  message = "#{call.xpath('./*/ns1:Code', 'ns1' =>'http://api.zuora.com/').text}::#{call.xpath('./*/ns1:Message', 'ns1' =>'http://api.zuora.com/').text}"
489
225
  error.push(message)
490
226
  else
@@ -496,28 +232,22 @@ module ZuoraAPI
496
232
  #By default response if not passed in for SOAP as all SOAP is 200
497
233
  if error.present?
498
234
  if error.class == String
499
- case error
500
- when "INVALID_SESSION"
235
+ if error == "INVALID_SESSION"
501
236
  raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{error}::#{message}", body, response.code )
502
- when "REQUEST_EXCEEDED_LIMIT"
237
+ end
238
+ if error == "REQUEST_EXCEEDED_LIMIT"
503
239
  raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new("#{error}::#{message}", body, response.code)
504
- when "LOCK_COMPETITION"
240
+ end
241
+ if error == "LOCK_COMPETITION"
505
242
  raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("#{error}::#{message}", body, response.code)
506
- when "BATCH_FAIL_ERROR"
507
- if message.include?("optimistic locking failed")
508
- raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("#{error}::#{message}", body, response.code)
509
- else
510
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{error}::#{message}", body, response.code)
511
- end
512
- when "TEMPORARY_ERROR"
513
- raise ZuoraAPI::Exceptions::ZuoraAPITemporaryError.new("#{error}::#{message}", body, response.code)
514
- else
515
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{error}::#{message}", body, response.code) if error.present?
243
+ end
244
+ if error.present?
245
+ raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{error}::#{message}", body, response.code)
516
246
  end
517
247
  elsif error.class == Array
518
248
  if error[0].include?("LOCK_COMPETITION") && error.count == 1
519
249
  raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new(error.group_by {|v| v}.map {|k,v| "(#{v.size}x) - #{k == "::" ? 'UNKNOWN::No error provided' : k}"}.join(', '), body, response.code)
520
- else
250
+ else
521
251
  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)
522
252
  end
523
253
  end
@@ -528,7 +258,6 @@ module ZuoraAPI
528
258
  end
529
259
 
530
260
  when :JSON
531
- body = body.dig("results").present? ? body["results"] : body if body.class == Hash
532
261
  if body.class == Hash && (!body["success"] || !body["Success"] || response.code != 200)
533
262
  messages_array = (body["reasons"] || []).map {|error| error['message']}.compact
534
263
  codes_array = (body["reasons"] || []).map {|error| error['code']}.compact
@@ -537,10 +266,6 @@ module ZuoraAPI
537
266
  raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new()
538
267
  end
539
268
 
540
- if body['errorMessage']
541
- raise ZuoraAPI::Exceptions::ZuoraAPIError.new(body['errorMessage'],body,response.code)
542
- end
543
-
544
269
  if body.dig("reasons").nil? ? false : body.dig("reasons")[0].dig("code") == 90000020
545
270
  raise ZuoraAPI::Exceptions::BadEntityError.new("#{messages_array.join(', ')}", body, response.code)
546
271
  end
@@ -599,18 +324,11 @@ module ZuoraAPI
599
324
  end
600
325
  end
601
326
 
602
- #Zuora REST Actions error (Create, Update, Delete, Amend)
327
+ #Zuora REST Actions error (Create, Update, Delete)
603
328
  if body.class == Array
604
329
  all_errors = body.select {|obj| !obj['Success'] || !obj['success'] }.map {|obj| obj['Errors'] || obj['errors'] }.compact
605
330
  all_success = body.select {|obj| obj['Success'] || obj['success']}.compact
606
331
 
607
- if all_success.blank? && all_errors.present?
608
- error_codes = all_errors.flatten.group_by {|error| error['Code']}.keys.uniq
609
- if error_codes.size == 1 && error_codes[0] == "LOCK_COMPETITION"
610
- raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("Retry Lock Competition", body, response.code)
611
- end
612
- end
613
-
614
332
  if all_errors.size > 0
615
333
  raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{all_errors.flatten.group_by {|error| error['Message']}.keys.uniq.join(' ')}", body, response.code, all_errors, all_success )
616
334
  end
@@ -670,11 +388,9 @@ module ZuoraAPI
670
388
 
671
389
  base = self.url.include?(".com") ? self.url.split(".com")[0].concat(".com") : self.url.split(".eu")[0].concat(".eu")
672
390
  url = object ? "#{base}/apps/api/describe/#{object}" : "#{base}/apps/api/describe/"
673
- headers = self.entity_id.present? ? {"Zuora-Entity-Ids" => self.entity_id, 'Content-Type' => "text/xml; charset=utf-8"} : {'Content-Type' => "text/xml; charset=utf-8"}
391
+ headers = !self.entity_id.blank? ? {"entityId" => self.entity_id, 'Content-Type' => "text/xml; charset=utf-8"} : {'Content-Type' => "text/xml; charset=utf-8"}
674
392
  response = HTTParty.get(url, headers: {"Authorization" => self.get_session(prefix: true, auth_type: :basic)}.merge(headers), :timeout => 120)
675
393
 
676
- raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error.present? ? self.current_error : 'Describe call 401' ) if response.code == 401
677
-
678
394
  output_xml = Nokogiri::XML(response.body)
679
395
  des_hash = Hash.new
680
396
  if object == nil
@@ -704,7 +420,7 @@ module ZuoraAPI
704
420
  end
705
421
  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
706
422
  end
707
- rescue *(CONNECTION_EXCEPTIONS).concat(CONNECTION_READ_EXCEPTIONS) => ex
423
+ rescue Net::ReadTimeout, Net::OpenTimeout, Errno::EPIPE, Errno::ECONNRESET, OpenSSL::SSL::SSLError, Errno::ECONNREFUSED, SocketError => ex
708
424
  if !(tries -= 1).zero?
709
425
  Rails.logger.info("Describe - #{ex.class} Timed out will retry after 5 seconds")
710
426
  sleep(self.timeout_sleep)
@@ -712,30 +428,17 @@ module ZuoraAPI
712
428
  else
713
429
  raise ex
714
430
  end
715
- rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
716
- if !(tries -= 1).zero?
717
- Rails.logger.info("Session expired. Starting new session.")
718
- self.new_session
719
- retry
720
- else
721
- raise ex
722
- end
723
431
  rescue => ex
724
432
  raise ex
725
433
  else
726
434
  return des_hash
727
435
  end
728
436
 
729
- def rest_call(method: :get, body: nil, headers: {}, url: rest_endpoint("catalog/products?pageSize=4"), debug: false, errors: [ZuoraAPI::Exceptions::ZuoraAPISessionError, ZuoraAPI::Exceptions::ZuoraAPIError, ZuoraAPI::Exceptions::ZuoraAPIRequestLimit, ZuoraAPI::Exceptions::ZuoraAPILockCompetition], z_session: true, session_type: :basic, timeout_retry: false, timeout: 120, **keyword_args)
437
+ def rest_call(method: :get, body: nil,headers: {}, url: rest_endpoint("catalog/products?pageSize=4"), debug: false, errors: [ZuoraAPI::Exceptions::ZuoraAPISessionError, ZuoraAPI::Exceptions::ZuoraAPIError, ZuoraAPI::Exceptions::ZuoraAPIRequestLimit, ZuoraAPI::Exceptions::ZuoraAPILockCompetition], z_session: true, session_type: :basic, timeout_retry: false, timeout: 120, **keyword_args)
730
438
  tries ||= 2
731
-
732
- if self.entity_id.present?
733
- headers["Zuora-Entity-Ids"] = self.entity_id if headers.dig("Zuora-Entity-Ids").nil?
734
- headers.delete_if { |key, value| ["entityId", "entityName"].include?(key.to_s) }
735
- end
736
-
439
+ headers["entityId"] = self.entity_id if !self.entity_id.blank?
737
440
  raise "Method not supported, supported methods include: :get, :post, :put, :delete, :patch, :head, :options" if ![:get, :post, :put, :delete, :patch, :head, :options].include?(method)
738
-
441
+
739
442
  authentication_headers = z_session ? {"Authorization" => self.get_session(prefix: true, auth_type: session_type) } : {}
740
443
  headers = {'Content-Type' => "application/json; charset=utf-8"}.merge(headers).merge(authentication_headers)
741
444
 
@@ -752,7 +455,7 @@ module ZuoraAPI
752
455
  rescue ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError => ex
753
456
  if self.class.to_s == 'ZuoraAPI::Oauth'
754
457
  self.rest_call(method: method.to_sym, url: url, debug: debug, errors: errors, z_session: z_session, session_type: :bearer, timeout_retry: timeout_retry, timeout: timeout)
755
- else
458
+ else
756
459
  Rails.logger.debug("Rest Call - Session Bad Auth type")
757
460
  raise ex
758
461
  end
@@ -776,15 +479,7 @@ module ZuoraAPI
776
479
  end
777
480
  rescue ZuoraAPI::Exceptions::BadEntityError => ex
778
481
  raise ex
779
- rescue *CONNECTION_EXCEPTIONS => ex
780
- if !(tries -= 1).zero?
781
- Rails.logger.info("Rest Call - #{ex.class} Timed out will retry after 5 seconds")
782
- sleep(self.timeout_sleep)
783
- retry
784
- else
785
- raise ex
786
- end
787
- rescue *CONNECTION_READ_EXCEPTIONS => ex
482
+ rescue Net::OpenTimeout, Errno::ECONNRESET, OpenSSL::SSL::SSLError, Errno::ECONNREFUSED, SocketError => ex
788
483
  if !(tries -= 1).zero? && timeout_retry
789
484
  Rails.logger.info("Rest Call - #{ex.class} Timed out will retry after 5 seconds")
790
485
  sleep(self.timeout_sleep)
@@ -844,7 +539,7 @@ module ZuoraAPI
844
539
  return products, catalog_map
845
540
  end
846
541
 
847
- def get_file(url: nil, headers: {}, count: 3, 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: 2, timeout: 120, session_type: :basic, force_encoding: true, **execute_params)
542
+ def get_file(url: nil, headers: {}, count: 3, z_session: true, tempfile: true, file_path: defined?(Rails.root.join('tmp')) ? Rails.root.join('tmp') : Pathname.new(Dir.pwd), timeout_retries: 2, timeout: 120, **execute_params)
848
543
  raise "file_path must be of class Pathname" if file_path.class != Pathname
849
544
 
850
545
  #Make sure directory exists
@@ -857,126 +552,100 @@ module ZuoraAPI
857
552
  http = Net::HTTP.new(uri.host, uri.port)
858
553
  http.read_timeout = timeout #Seconds
859
554
  http.use_ssl = true if uri.scheme.downcase == 'https'
860
- if z_session
861
- headers = headers.merge({"Authorization" => self.get_session(prefix: true)})
862
- headers = headers.merge({"Zuora-Entity-Ids" => self.entity_id}) if !self.entity_id.blank?
863
- end
555
+ headers = headers.merge({"Authorization" => self.get_session(prefix: true)}) if z_session
864
556
 
865
557
  response_save = nil
866
- begin
867
- http.request_get(uri.request_uri, headers) do |response|
868
- response_save = response
869
- status_code = response.code if response
870
-
871
- case response
872
- when Net::HTTPNotFound
873
- Rails.logger.fatal("404 - Not Found")
874
- raise
875
-
876
- when Net::HTTPUnauthorized
877
- if count <= 0
878
- if z_session
879
- raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error)
880
- else
881
- raise
882
- end
883
- end
884
- Rails.logger.fatal("Unauthorized: Retry")
885
- self.new_session if z_session
886
- return get_file(:url => url, :headers => headers, :count => count - 1, :z_session => z_session, :tempfile => tempfile, :file_path => file_path, :timeout_retries => timeout_retries, :timeout => timeout, :force_encoding => force_encoding)
887
-
888
- when Net::HTTPClientError
889
- raise
890
-
891
- when Net::HTTPOK
892
- headers = {}
893
- response.each_header do |k,v|
894
- headers[k] = v
895
- end
896
- Rails.logger.debug("Headers: #{headers.to_s}")
897
- if output_file_name.present?
898
- file_ending ||= output_file_name.end_with?(".csv.zip") ? ".csv.zip" : File.extname(output_file_name)
899
- filename ||= File.basename(output_file_name, file_ending)
900
- end
901
-
902
- size, export_progress = [0, 0]
903
- encoding, type, full_filename = [nil, nil, nil]
904
- if response.header["Content-Disposition"].present?
905
- case response.header["Content-Disposition"]
906
- when /.*; filename\*=.*/
907
- full_filename ||= /.*; filename\*=(.*)''(.*)/.match(response.header["Content-Disposition"])[2].strip
908
- encoding = /.*; filename\*=(.*)''(.*)/.match(response.header["Content-Disposition"])[1].strip
909
- when /.*; filename=/
910
- full_filename ||= /.*; filename=(.*)/.match(response.header["Content-Disposition"])[1].strip
911
- else
912
- raise "Can't parse Content-Disposition header: #{response.header["Content-Disposition"]}"
913
- end
914
- file_ending ||= full_filename.end_with?(".csv.zip") ? ".csv.zip" : File.extname(full_filename)
915
- filename ||= File.basename(full_filename, file_ending)
916
- end
917
-
918
- #If user supplied a filename use it, else default to content header filename, else default to uri pattern
919
- file_ending ||= uri.path.end_with?(".csv.zip") ? ".csv.zip" : File.extname(uri.path)
920
- filename ||= File.basename(uri.path, file_ending)
921
-
922
- if response.header["Content-Type"].present?
923
- case response.header["Content-Type"]
924
- when /.*;charset=.*/
925
- type = /(.*);charset=(.*)/.match(response.header["Content-Type"])[1]
926
- encoding = /(.*);charset=(.*)/.match(response.header["Content-Type"])[2]
927
- else
928
- type = response.header["Content-Type"]
929
- encoding ||= 'UTF-8'
930
- end
558
+ http.request_get(uri.path, headers) do |response|
559
+ response_save = response
560
+ status_code = response.code if response
561
+
562
+ case response
563
+ when Net::HTTPNotFound
564
+ Rails.logger.fatal("404 - Not Found")
565
+ raise response
566
+
567
+ when Net::HTTPUnauthorized
568
+ raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error) if count <= 0
569
+ Rails.logger.fatal("Unauthorized: Retry")
570
+ self.new_session
571
+ return get_file(:url => url, :headers => headers, :count => count - 1, :z_session => z_session, :tempfile => tempfile, :file_path => file_path, :timeout_retries => timeout_retries, :timeout => timeout)
572
+
573
+ when Net::ReadTimeout, Net::OpenTimeout, Errno::EPIPE, Errno::ECONNRESET, OpenSSL::SSL::SSLError, Errno::ECONNREFUSED, SocketError
574
+ Rails.logger.fatal("#{response.class} timeout - retry")
575
+ return get_file(:url => url, :headers => headers, :count => count, :z_session => z_session, :tempfile => tempfile, :file_path => file_path, :timeout_retries => timeout_retries - 1, :timeout => timeout)
576
+
577
+ when Net::HTTPClientError
578
+ Rails.logger.fatal("Login: #{self.username} Export")
579
+ raise response
580
+
581
+ when Net::HTTPOK
582
+ headers = {}
583
+ response.each_header do |k,v|
584
+ headers[k] = v
585
+ end
586
+ Rails.logger.debug("Headers: #{headers.to_s}")
587
+
588
+ size, export_progress = [0, 0]
589
+ encoding, type, full_filename = [nil, nil, nil]
590
+ if response.header["Content-Disposition"].present?
591
+ case response.header["Content-Disposition"]
592
+ when /.*; filename\*=.*/
593
+ full_filename = /.*; filename\*=(.*)''(.*)/.match(response.header["Content-Disposition"])[2].strip
594
+ encoding = /.*; filename\*=(.*)''(.*)/.match(response.header["Content-Disposition"])[1].strip
595
+ when /.*; filename=/
596
+ full_filename = /.*; filename=(.*)/.match(response.header["Content-Disposition"])[1].strip
931
597
  end
932
-
933
- if response.header["Content-Length"].present?
934
- export_size = response.header["Content-Length"].to_i
935
- elsif response.header["ContentLength"].present?
936
- export_size = response.header["ContentLength"].to_i
598
+ file_ending = ".#{full_filename.partition(".").last}"
599
+ end
600
+ #If user supplied a filename use it, else default to content header filename, else default to uri pattern
601
+ filename = full_filename.present? ? full_filename.split(file_ending).first : File.basename(uri.path).rpartition('.').first
602
+
603
+ if response.header["Content-Type"].present?
604
+ case response.header["Content-Type"]
605
+ when /.*;charset=.*/
606
+ type = /(.*);charset=(.*)/.match(response.header["Content-Type"])[1]
607
+ encoding = /(.*);charset=(.*)/.match(response.header["Content-Type"])[2]
608
+ else
609
+ type = response.header["Content-Type"]
610
+ encoding ||= 'UTF-8'
937
611
  end
612
+ end
613
+ Rails.logger.info("File: #{filename}#{file_ending} #{encoding} #{type}")
938
614
 
939
- Rails.logger.info("File: #{filename}#{file_ending} #{encoding} #{type} #{export_size}")
615
+ if response.header["Content-Length"].present?
616
+ export_size = response.header["Content-Length"].to_i
617
+ elsif response.header["ContentLength"].present?
618
+ export_size = response.header["ContentLength"].to_i
619
+ end
940
620
 
941
- file_prefix = add_timestamp ? "#{filename}_#{Time.now.to_i}" : filename
942
- if tempfile
943
- require 'tempfile'
944
- file_handle = ::Tempfile.new([file_prefix, "#{file_ending}"], file_path)
945
- else
946
- file_handle = File.new(file_path.join("#{file_prefix}#{file_ending}"), "w+")
947
- end
621
+ file_handle = nil
622
+ timestamp = Time.now.to_i
623
+ if tempfile
624
+ require 'tempfile'
625
+ file_handle = ::Tempfile.new(["#{filename}_#{timestamp}", "#{file_ending}"], file_path)
626
+ file_handle.binmode
627
+ else
628
+ file_handle = File.new(file_path.join("#{filename}_#{timestamp}#{file_ending}"), "w+")
948
629
  file_handle.binmode
630
+ end
949
631
 
950
- response.read_body do |chunk|
951
- if force_encoding
952
- file_handle << chunk.force_encoding(encoding)
953
- else
954
- file_handle << chunk
955
- end
632
+ response.read_body do |chunk|
633
+ file_handle << chunk.force_encoding(encoding)
956
634
 
957
- if defined?(export_size) && export_size != 0 && export_size.class == Integer
958
- size += chunk.size
959
- new_progress = (size * 100) / export_size
960
- unless new_progress == export_progress
961
- Rails.logger.debug("Login: Export Downloading %s (%3d%%)" % [filename, new_progress])
962
- end
963
- export_progress = new_progress
635
+ if defined?(export_size) && export_size != 0 && export_size.class == Integer
636
+ size += chunk.size
637
+ new_progress = (size * 100) / export_size
638
+ unless new_progress == export_progress
639
+ Rails.logger.debug("Login: #{self.username} Export Downloading %s (%3d%%)" % [filename, new_progress])
964
640
  end
641
+ export_progress = new_progress
965
642
  end
643
+ end
966
644
 
967
- file_handle.close
968
- Rails.logger.debug("Filepath: #{file_handle.path} Size: #{File.size(file_handle.path).to_f/1000000} mb")
645
+ file_handle.close
646
+ Rails.logger.debug("Filepath: #{file_handle.path} Size: #{File.size(file_handle.path).to_f/1000000} mb")
969
647
 
970
- return file_handle
971
- end
972
- end
973
- rescue *(CONNECTION_EXCEPTIONS).concat(CONNECTION_READ_EXCEPTIONS).concat([Net::HTTPBadResponse]) => e
974
- sleep(5)
975
- if (timeout_retries -= 1) >= 0
976
- Rails.logger.warn("Download Failed: #{e.class} : #{e.message}")
977
- retry
978
- else
979
- raise
648
+ return file_handle
980
649
  end
981
650
  end
982
651
  rescue Exception => e
@@ -987,6 +656,8 @@ module ZuoraAPI
987
656
  end
988
657
 
989
658
  def getDataSourceExport(query, extract: true, encrypted: false, zip: true)
659
+ Rails.logger.debug("Build export")
660
+ Rails.logger.debug("#{query}")
990
661
  request = Nokogiri::XML::Builder.new do |xml|
991
662
  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
992
663
  xml['SOAP-ENV'].Header do
@@ -1009,7 +680,7 @@ module ZuoraAPI
1009
680
  end
1010
681
 
1011
682
  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)
1012
-
683
+
1013
684
  output_xml = Nokogiri::XML(response_query.body)
1014
685
  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"
1015
686
  id = output_xml.xpath('//ns1:Id', 'ns1' =>'http://api.zuora.com/').text
@@ -1033,7 +704,7 @@ module ZuoraAPI
1033
704
  while result != "Completed"
1034
705
  sleep 3
1035
706
  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)
1036
-
707
+
1037
708
  output_xml = Nokogiri::XML(response_query.body)
1038
709
  result = output_xml.xpath('//ns2:Status', 'ns2' =>'http://object.api.zuora.com/').text
1039
710
  status_code = response_query.code if response_query
@@ -1041,6 +712,7 @@ module ZuoraAPI
1041
712
  end
1042
713
 
1043
714
  file_id = output_xml.xpath('//ns2:FileId', 'ns2' =>'http://object.api.zuora.com/').text
715
+ Rails.logger.debug('=====> Export finished')
1044
716
  export_file = get_file(:url => self.fileURL(file_id))
1045
717
  export_file_path = export_file.path
1046
718
  Rails.logger.debug("=====> Export path #{export_file.path}")
@@ -1059,6 +731,7 @@ module ZuoraAPI
1059
731
  end
1060
732
 
1061
733
  def query(query, parse = false)
734
+ Rails.logger.debug("Querying Zuora for #{query}")
1062
735
  output_xml, input_xml = self.soap_call({:debug => false, :timeout_retry => true}) do |xml|
1063
736
  xml['ns1'].query do
1064
737
  xml['ns1'].queryString query
@@ -1083,7 +756,7 @@ module ZuoraAPI
1083
756
  response = Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
1084
757
  http.request req
1085
758
  end
1086
-
759
+
1087
760
  Rails.logger.debug("Response #{response.code} #{response.message}: #{response.body}")
1088
761
 
1089
762
  result = JSON.parse(response.body)
@@ -27,11 +27,11 @@ module ZuoraAPI
27
27
 
28
28
  input_xml = Nokogiri::XML(request.to_xml(:save_with => XML_SAVE_OPTIONS).strip)
29
29
  input_xml.xpath('//ns1:session', 'ns1' =>'http://api.zuora.com/').children.remove
30
- Rails.logger.debug('Connect') {"Request Code: #{@response_query.code} SOAP XML: #{input_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}"} if debug
30
+ Rails.logger.debug('Connect') {"Request SOAP XML: #{input_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}"} if debug
31
31
 
32
32
  @response_query = HTTParty.post(self.url,:body => request.to_xml(:save_with => XML_SAVE_OPTIONS).strip, :headers => {'Content-Type' => "text/xml; charset=utf-8"}, :timeout => 10)
33
33
  @output_xml = Nokogiri::XML(@response_query.body)
34
- Rails.logger.debug('Connect') {"Response Code: #{@response_query.code} SOAP XML: #{@output_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}"} if debug
34
+ Rails.logger.debug('Connect') {"Response SOAP XML: #{@output_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}"} if debug
35
35
 
36
36
  if !@response_query.success?
37
37
  self.current_session = nil
@@ -70,9 +70,6 @@ module ZuoraAPI
70
70
  self.status = 'Locked'
71
71
  self.current_error = 'Locked user login, please wait or navigate to Zuora to unlock user'
72
72
  self.errors[:username] = self.current_error
73
- elsif self.current_error.include?('Entity not exist:')
74
- self.status = 'Entity Missing'
75
- self.errors[:base] = self.current_error
76
73
  else
77
74
  self.status = 'Unknown'
78
75
  self.current_error = @output_xml.xpath('//faultstring').text if self.current_error.blank?
@@ -88,11 +85,10 @@ module ZuoraAPI
88
85
  #Username & password combo
89
86
  retrieved_session = @output_xml.xpath('//ns1:Session', 'ns1' =>'http://api.zuora.com/').text
90
87
  raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("No session found for api call.") if retrieved_session.blank?
91
- self.status = 'Active'
92
88
  self.current_session = retrieved_session
93
89
  end
94
90
  return self.status
95
- rescue *(CONNECTION_EXCEPTIONS).concat(CONNECTION_READ_EXCEPTIONS) => ex
91
+ rescue Net::ReadTimeout, Net::OpenTimeout, Errno::EPIPE, Errno::ECONNRESET, Errno::ECONNREFUSED, SocketError => ex
96
92
  if !(tries -= 1).zero?
97
93
  Rails.logger.info {"#{ex.class} Timed out will retry after 5 seconds"}
98
94
  sleep(self.timeout_sleep)
@@ -102,12 +98,6 @@ module ZuoraAPI
102
98
  self.status = 'Timeout'
103
99
  return self.status
104
100
  end
105
- rescue EOFError
106
- if self.url.match?(/.*services\d{1,}.zuora.com*/)
107
- self.current_error = "Services tenant '#{self.url.scan(/.*\/\/(services\d{1,}).zuora.com*/).last.first}' is no longer available."
108
- self.status = 'Not Available'
109
- return self.status
110
- end
111
101
  end
112
102
  end
113
103
  end
@@ -24,14 +24,9 @@ module ZuoraAPI
24
24
  return self.status
25
25
  end
26
26
 
27
- def get_active_bearer_token
28
- self.get_bearer_token if self.oauth_expired?
29
- return self.bearer_token
30
- end
31
-
32
27
  def get_z_session(debug: false)
33
28
  tries ||= 2
34
- headers = self.entity_id.present? ? {"Zuora-Entity-Ids" => self.entity_id } : {}
29
+ headers = self.entity_id.present? ? {:entityId => self.entity_id } : {}
35
30
  output_json, response = self.rest_call(:url => self.rest_endpoint("connections"), :session_type => :bearer, :headers => headers)
36
31
  self.current_session = response.headers.to_h['set-cookie'][0].split(';')[0].split('=',2)[1].gsub('%3D', '=')
37
32
  rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
@@ -52,7 +47,7 @@ module ZuoraAPI
52
47
  else
53
48
  return [output_json, response]
54
49
  end
55
- rescue *(CONNECTION_EXCEPTIONS).concat(CONNECTION_READ_EXCEPTIONS) => ex
50
+ rescue Net::ReadTimeout, Net::OpenTimeout, Errno::EPIPE, Errno::ECONNRESET, Errno::ECONNREFUSED, SocketError => ex
56
51
  if !(tries -= 1).zero?
57
52
  Rails.logger.info {"#{ex.class} Timed out will retry after 5 seconds"}
58
53
  sleep(self.timeout_sleep)
@@ -92,7 +87,7 @@ module ZuoraAPI
92
87
  else
93
88
  return [output_json, response]
94
89
  end
95
- rescue *(CONNECTION_EXCEPTIONS).concat(CONNECTION_READ_EXCEPTIONS) => ex
90
+ rescue Net::ReadTimeout, Net::OpenTimeout, Errno::EPIPE, Errno::ECONNRESET, Errno::ECONNREFUSED, SocketError => ex
96
91
  if !(tries -= 1).zero?
97
92
  Rails.logger.info {"#{ex.class} Timed out will retry after 5 seconds"}
98
93
  sleep(self.timeout_sleep)
@@ -1,3 +1,3 @@
1
1
  module ZuoraAPI
2
- VERSION = "1.6.3b"
2
+ VERSION = "1.6.03"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zuora_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.3b
4
+ version: 1.6.03
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zuora Strategic Solutions Group
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-05-04 00:00:00.000000000 Z
11
+ date: 2018-09-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -153,7 +153,6 @@ files:
153
153
  - ".gitlab-ci.yml"
154
154
  - ".rspec"
155
155
  - ".travis.yml"
156
- - CHANGELOG.md
157
156
  - Gemfile
158
157
  - Gemfile.lock
159
158
  - README.md
@@ -182,11 +181,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
182
181
  version: '0'
183
182
  required_rubygems_version: !ruby/object:Gem::Requirement
184
183
  requirements:
185
- - - ">"
184
+ - - ">="
186
185
  - !ruby/object:Gem::Version
187
- version: 1.3.1
186
+ version: '0'
188
187
  requirements: []
189
- rubygems_version: 3.0.3
188
+ rubyforge_project:
189
+ rubygems_version: 2.6.8
190
190
  signing_key:
191
191
  specification_version: 4
192
192
  summary: Gem that provides easy integration to Zuora
data/CHANGELOG.md DELETED
@@ -1,26 +0,0 @@
1
- # Changelog
2
- All notable changes to this project will be documented in this file.
3
-
4
- ## [1.6.28] - 2018-3-12
5
- ### Added
6
- - Way to avoid force encoding for filedownload
7
-
8
- ## [1.6.22] - 2019-01-03
9
- ### Changed
10
- - get_identity method - supports ZSession auth now
11
- - updated rspecs accordingly
12
-
13
- ## [1.6.18] - 2018-12-06
14
- ### Added
15
- - zconnect_provider attribute accessor for identifying ZConnect cookies
16
- - Methods for Hallway integration:
17
- - get_identity
18
- - get_full_nav
19
- - set_nav
20
- - refresh_nav
21
- - get_oauth_client
22
-
23
- ### Changed
24
- - The way environment and region are set
25
-
26
-