zuora_api 1.6.3b → 1.6.03

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 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
-