zuora_api 1.7.7f → 1.7.07
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 +4 -4
- data/.gitignore +0 -2
- data/.gitlab-ci.yml +19 -19
- data/CHANGELOG.md +0 -17
- data/Gemfile +1 -1
- data/README.md +1 -1
- data/lib/insights_api/login.rb +6 -5
- data/lib/zuora_api/exceptions.rb +29 -118
- data/lib/zuora_api/login.rb +337 -719
- data/lib/zuora_api/logins/basic.rb +93 -11
- data/lib/zuora_api/logins/oauth.rb +76 -38
- data/lib/zuora_api/version.rb +1 -1
- data/zuora_api.gemspec +3 -4
- metadata +12 -30
- data/gemfiles/Gemfile-rails.5.0.x +0 -5
- data/gemfiles/Gemfile-rails.5.1.x +0 -5
- data/gemfiles/Gemfile-rails.5.2.x +0 -5
- data/gemfiles/Gemfile-rails.6.0.x +0 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: db58b1a6236a7237cc3ac29b7c5b9ac172f12f8d66e017105a200e7e1d040d71
|
|
4
|
+
data.tar.gz: 83104f05aa4bb4f885bc8e85bb8daa742c051bce07b605d680af64c215fdc230
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9afe3a53deb1c2bb87d46842c5fdc5129fe2ac3f0c08ac6fe20461ca4a29ddb5c1d49e57802042b31f87eb4487ca88ade14a803afb83fa63a746ace6df36d5a9
|
|
7
|
+
data.tar.gz: 2a550f3e7b3da631f1996e0ac07eb41c58631ac1f8404039671a3ff14d14b5f931ef3eaed3afdd5726283a22266cc5015c60d7060465a1c8301b1349a0fdbfa3
|
data/.gitignore
CHANGED
data/.gitlab-ci.yml
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
|
-
image: ruby:2.
|
|
1
|
+
image: ruby:2.6
|
|
2
2
|
stages:
|
|
3
|
+
- setup
|
|
3
4
|
- test
|
|
4
5
|
- deploy
|
|
5
6
|
|
|
7
|
+
setup:
|
|
8
|
+
stage: setup
|
|
9
|
+
allow_failure: true
|
|
10
|
+
cache:
|
|
11
|
+
key: gems
|
|
12
|
+
paths:
|
|
13
|
+
- vendor/bundle
|
|
14
|
+
script:
|
|
15
|
+
- apt-get update -qy
|
|
16
|
+
- apt-get install -y nodejs
|
|
17
|
+
- bundle install
|
|
18
|
+
|
|
6
19
|
rubocop-testing:
|
|
7
20
|
stage: test
|
|
8
21
|
allow_failure: true
|
|
@@ -17,24 +30,11 @@ security-testing:
|
|
|
17
30
|
- gem install brakeman
|
|
18
31
|
- brakeman
|
|
19
32
|
|
|
20
|
-
|
|
33
|
+
rspec-testing:
|
|
21
34
|
stage: test
|
|
22
|
-
cache:
|
|
23
|
-
key: ruby:$RUBY_VERSION-rails:$RAILS_VERSION
|
|
24
|
-
paths:
|
|
25
|
-
- vendor/ruby
|
|
26
|
-
parallel:
|
|
27
|
-
matrix:
|
|
28
|
-
- RUBY_VERSION: "2.7"
|
|
29
|
-
RAILS_VERSION: ["5.0", "5.1", "5.2", "6.0"]
|
|
30
|
-
before_script:
|
|
31
|
-
- bundle config set path 'vendor/ruby'
|
|
32
|
-
- bundle config --global gemfile "gemfiles/Gemfile-rails.$RAILS_VERSION.x"
|
|
33
|
-
- bundle install
|
|
34
35
|
script:
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
coverage: '/\(\d+.\d+\%\) covered/'
|
|
36
|
+
- bundle install
|
|
37
|
+
- rspec
|
|
38
38
|
|
|
39
39
|
rubygems-deploy:
|
|
40
40
|
stage: deploy
|
|
@@ -48,8 +48,8 @@ rubygems-deploy:
|
|
|
48
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
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
50
|
- echo $VERSION
|
|
51
|
-
- sed -i "s/0.0.1/$VERSION/" lib/zuora_api/version.rb
|
|
52
|
-
- git add lib/zuora_api/version.rb
|
|
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
53
|
- git config --global user.email "connect@zuora.com"
|
|
54
54
|
- git config --global user.name "Connect Automation"
|
|
55
55
|
- git commit -m "Automated Version Update $VERSION"
|
data/CHANGELOG.md
CHANGED
|
@@ -1,23 +1,6 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
All notable changes to this project will be documented in this file.
|
|
3
3
|
|
|
4
|
-
## [1.7.07] - 2018-9-10
|
|
5
|
-
### Changed
|
|
6
|
-
- Cookie name for service endpoint integration
|
|
7
|
-
|
|
8
|
-
## [1.7.06] - 2018-8-25
|
|
9
|
-
### Added
|
|
10
|
-
- Retry for 502/503
|
|
11
|
-
- Standard exception for 504
|
|
12
|
-
|
|
13
|
-
## [1.7.05] - 2018-8-25
|
|
14
|
-
### Added
|
|
15
|
-
- Added support for oauth token forbidden
|
|
16
|
-
|
|
17
|
-
## [1.7.02] - 2018-8-23
|
|
18
|
-
### Added
|
|
19
|
-
- Added mulit part support for rest call
|
|
20
|
-
|
|
21
4
|
## [1.7.01] - 2018-8-06
|
|
22
5
|
### Changed
|
|
23
6
|
- Changed library used to determine host
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Zuora Gem
|
|
2
2
|
|
|
3
|
-
[](https://badge.fury.io/rb/zuora_api) [](https://badge.fury.io/rb/zuora_api) [](https://gitlab.zuora.com/Connect/zuora-gem/commits/master)
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
Add this line to your application's Gemfile:
|
data/lib/insights_api/login.rb
CHANGED
|
@@ -190,11 +190,12 @@ module InsightsAPI
|
|
|
190
190
|
end
|
|
191
191
|
|
|
192
192
|
rescue => ex
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
193
|
+
if !(tries -= 1).zero?
|
|
194
|
+
sleep 3
|
|
195
|
+
retry
|
|
196
|
+
else
|
|
197
|
+
raise ex
|
|
198
|
+
end
|
|
198
199
|
else
|
|
199
200
|
return temp_file
|
|
200
201
|
end
|
data/lib/zuora_api/exceptions.rb
CHANGED
|
@@ -1,38 +1,14 @@
|
|
|
1
1
|
module ZuoraAPI
|
|
2
2
|
module Exceptions
|
|
3
|
-
class Error < StandardError;
|
|
4
|
-
def parse_message(message)
|
|
5
|
-
case message
|
|
6
|
-
when /^Payment status should be Processed. Invalid payment is P-\d*./
|
|
7
|
-
@message = "Payment status should be Processed."
|
|
8
|
-
when /^Adjustment cannot be created for invoice(.*) with a zero balance./
|
|
9
|
-
@message = "Adjustment cannot be created for invoice with a zero balance."
|
|
10
|
-
when /^The balance of all the invoice items and tax items is 0. No write-off is needed for the invoice .*./
|
|
11
|
-
@message = "The balance of all the invoice items and tax items is 0. No write-off is needed for the invoice."
|
|
12
|
-
when /^Json input does not match schema. Error(s): string ".*" is too long .*/
|
|
13
|
-
@message = "Json input does not match schema. Error(s): String is too long."
|
|
14
|
-
when /^Query failed \(#[\d\w_]*\): line [0-9]+:[0-9]+: (.*)$/
|
|
15
|
-
@message = "Query failed: #{$1}"
|
|
16
|
-
when /^Query failed \(#[\d\w_]*\): (.*)$/
|
|
17
|
-
@message = "Query failed: #{$1}"
|
|
18
|
-
when /^Could not find [\w\d]{32}.$/
|
|
19
|
-
@message = "Could not find object."
|
|
20
|
-
when /^Subscription [\w\d]{32} is in expired status. It is not supported to generate billing documents for expired subscriptions./
|
|
21
|
-
@message = "Subscription is in expired status. It is not supported to generate billing documents for expired subscriptions."
|
|
22
|
-
else
|
|
23
|
-
@message = message
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
class FileDownloadError < StandardError; end
|
|
3
|
+
class Error < StandardError; end
|
|
28
4
|
class AuthorizationNotPerformed < Error; end
|
|
29
5
|
class ZuoraAPISessionError < Error
|
|
30
6
|
attr_reader :code, :response
|
|
31
7
|
attr_writer :default_message
|
|
32
8
|
|
|
33
|
-
def initialize(message = nil,response=nil
|
|
34
|
-
@code = response.class.to_s == "HTTParty::Response" ? response.code : nil
|
|
35
|
-
@message =
|
|
9
|
+
def initialize(message = nil,response=nil)
|
|
10
|
+
@code = response.present? && response.class.to_s == "HTTParty::Response" ? response.code : nil
|
|
11
|
+
@message = message
|
|
36
12
|
@response = response
|
|
37
13
|
@default_message = "Error with Zuora Session."
|
|
38
14
|
end
|
|
@@ -40,19 +16,6 @@ module ZuoraAPI
|
|
|
40
16
|
def to_s
|
|
41
17
|
@message || @default_message
|
|
42
18
|
end
|
|
43
|
-
|
|
44
|
-
def parse_message(message)
|
|
45
|
-
case message
|
|
46
|
-
when /^Invalid Oauth Client Id$/, /^Unable to generate token.$/
|
|
47
|
-
@message = "Invalid login, please check client ID and Client Secret or URL endpoint"
|
|
48
|
-
when /^Forbidden$/
|
|
49
|
-
@message = "The user associated to OAuth credential set has been deactivated."
|
|
50
|
-
when /^Invalid login. User name and password do not match.$/
|
|
51
|
-
@message = "Invalid login, please check username and password or URL endpoint"
|
|
52
|
-
else
|
|
53
|
-
@message = message
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
19
|
end
|
|
57
20
|
|
|
58
21
|
class BadEntityError < Error
|
|
@@ -60,8 +23,8 @@ module ZuoraAPI
|
|
|
60
23
|
attr_writer :default_message
|
|
61
24
|
|
|
62
25
|
def initialize(message = nil,response=nil, errors = [], successes = [], *args)
|
|
63
|
-
@code = response.class.to_s == "HTTParty::Response" ? response.code : nil
|
|
64
|
-
@message =
|
|
26
|
+
@code = response.present? && response.class.to_s == "HTTParty::Response" ? response.code : nil
|
|
27
|
+
@message = message
|
|
65
28
|
@response = response
|
|
66
29
|
@default_message = "Error with Zuora Entity"
|
|
67
30
|
@errors = errors
|
|
@@ -78,8 +41,8 @@ module ZuoraAPI
|
|
|
78
41
|
attr_writer :default_message
|
|
79
42
|
|
|
80
43
|
def initialize(message = nil,response=nil, errors = [], successes = [], *args)
|
|
81
|
-
@code = response.class.to_s == "HTTParty::Response" ? response.code : nil
|
|
82
|
-
@message =
|
|
44
|
+
@code = response.present? && response.class.to_s == "HTTParty::Response" ? response.code : nil
|
|
45
|
+
@message = message
|
|
83
46
|
@response = response
|
|
84
47
|
@default_message = "Error communicating with Zuora."
|
|
85
48
|
@errors = errors
|
|
@@ -91,31 +54,13 @@ module ZuoraAPI
|
|
|
91
54
|
end
|
|
92
55
|
end
|
|
93
56
|
|
|
94
|
-
class ZuoraAPIInternalServerError < Error
|
|
95
|
-
attr_reader :code, :response, :errors, :successes
|
|
96
|
-
attr_writer :default_message
|
|
97
|
-
|
|
98
|
-
def initialize(message = nil,response = nil, errors = [], successes = [], *args)
|
|
99
|
-
@code = response.class.to_s == "HTTParty::Response" ? response.code : nil
|
|
100
|
-
@message = parse_message(message)
|
|
101
|
-
@response = response
|
|
102
|
-
@default_message = "Zuora Internal Server Error."
|
|
103
|
-
@errors = errors
|
|
104
|
-
@successes = successes
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def to_s
|
|
108
|
-
@message || @default_message
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
|
|
112
57
|
class ZuoraAPIRequestLimit < Error
|
|
113
58
|
attr_reader :code, :response
|
|
114
59
|
attr_writer :default_message
|
|
115
60
|
|
|
116
|
-
def initialize(message = nil,response=nil,
|
|
117
|
-
@code = response.class.to_s == "HTTParty::Response" ? response.code : nil
|
|
118
|
-
@message =
|
|
61
|
+
def initialize(message = nil,response=nil, *args)
|
|
62
|
+
@code = response.present? && response.class.to_s == "HTTParty::Response" ? response.code : nil
|
|
63
|
+
@message = message
|
|
119
64
|
@response = response
|
|
120
65
|
@default_message = "Your request limit has been exceeded for zuora."
|
|
121
66
|
end
|
|
@@ -125,29 +70,13 @@ module ZuoraAPI
|
|
|
125
70
|
end
|
|
126
71
|
end
|
|
127
72
|
|
|
128
|
-
class ZuoraAPIUnkownError < Error
|
|
129
|
-
attr_reader :code, :response
|
|
130
|
-
attr_writer :default_message
|
|
131
|
-
|
|
132
|
-
def initialize(message = nil,response=nil, errors = [], successes = [], *args)
|
|
133
|
-
@code = response.class.to_s == "HTTParty::Response" ? response.code : nil
|
|
134
|
-
@message = parse_message(message)
|
|
135
|
-
@response = response
|
|
136
|
-
@default_message = "An unkown error occured. Workflow is not responsible. Please contact Support."
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
def to_s
|
|
140
|
-
@message || @default_message
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
|
|
144
73
|
class ZuoraAPILockCompetition < Error
|
|
145
74
|
attr_reader :code, :response
|
|
146
75
|
attr_writer :default_message
|
|
147
76
|
|
|
148
|
-
def initialize(message = nil,response=nil,
|
|
149
|
-
@code = response.class.to_s == "HTTParty::Response" ? response.code : nil
|
|
150
|
-
@message =
|
|
77
|
+
def initialize(message = nil,response=nil, *args)
|
|
78
|
+
@code = response.present? && response.class.to_s == "HTTParty::Response" ? response.code : nil
|
|
79
|
+
@message = message
|
|
151
80
|
@response = response
|
|
152
81
|
@default_message = "Operation failed due to lock competition. Please retry"
|
|
153
82
|
end
|
|
@@ -161,9 +90,9 @@ module ZuoraAPI
|
|
|
161
90
|
attr_reader :code, :response
|
|
162
91
|
attr_writer :default_message
|
|
163
92
|
|
|
164
|
-
def initialize(message = nil,response=nil,
|
|
165
|
-
@code = response.class.to_s == "HTTParty::Response" ? response.code : nil
|
|
166
|
-
@message =
|
|
93
|
+
def initialize(message = nil,response=nil, *args)
|
|
94
|
+
@code = response.present? && response.class.to_s == "HTTParty::Response" ? response.code : nil
|
|
95
|
+
@message = message
|
|
167
96
|
@response = response
|
|
168
97
|
@default_message = "Operation failed due to lock competition. Please retry"
|
|
169
98
|
end
|
|
@@ -173,32 +102,15 @@ module ZuoraAPI
|
|
|
173
102
|
end
|
|
174
103
|
end
|
|
175
104
|
|
|
176
|
-
class ZuoraUnexpectedError < Error
|
|
177
|
-
attr_reader :code, :response
|
|
178
|
-
attr_writer :default_message
|
|
179
|
-
|
|
180
|
-
def initialize(message = nil, response=nil, errors = [], successes = [], *args)
|
|
181
|
-
@code = response.class.to_s == "HTTParty::Response" ? response.code : nil
|
|
182
|
-
@message = parse_message(message)
|
|
183
|
-
@response = response
|
|
184
|
-
@default_message = "An unexpected error occurred"
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
def to_s
|
|
188
|
-
@message || @default_message
|
|
189
|
-
end
|
|
190
|
-
end
|
|
191
|
-
|
|
192
105
|
class ZuoraAPITemporaryError < Error
|
|
193
|
-
attr_reader :code, :response
|
|
106
|
+
attr_reader :code, :response
|
|
194
107
|
attr_writer :default_message
|
|
195
108
|
|
|
196
|
-
def initialize(message = nil,
|
|
197
|
-
@code = response.class.to_s == "HTTParty::Response" ? response.code : nil
|
|
198
|
-
@message =
|
|
109
|
+
def initialize(message = nil,response=nil, *args)
|
|
110
|
+
@code = response.present? && response.class.to_s == "HTTParty::Response" ? response.code : nil
|
|
111
|
+
@message = message
|
|
199
112
|
@response = response
|
|
200
113
|
@default_message = "There is a temporary error with zuora system."
|
|
201
|
-
@errors = errors
|
|
202
114
|
end
|
|
203
115
|
|
|
204
116
|
def to_s
|
|
@@ -210,9 +122,9 @@ module ZuoraAPI
|
|
|
210
122
|
attr_reader :code, :response
|
|
211
123
|
attr_writer :default_message
|
|
212
124
|
|
|
213
|
-
def initialize(message = nil,response=nil,
|
|
214
|
-
@code = response.class.to_s == "HTTParty::Response" ? response.code : nil
|
|
215
|
-
@message =
|
|
125
|
+
def initialize(message = nil,response=nil, *args)
|
|
126
|
+
@code = response.present? && response.class.to_s == "HTTParty::Response" ? response.code : nil
|
|
127
|
+
@message = message
|
|
216
128
|
@response = response
|
|
217
129
|
@default_message = "Authentication type is not supported by this Login"
|
|
218
130
|
end
|
|
@@ -226,8 +138,8 @@ module ZuoraAPI
|
|
|
226
138
|
attr_reader :code, :response
|
|
227
139
|
attr_writer :default_message
|
|
228
140
|
|
|
229
|
-
def initialize(message = nil,response=nil,
|
|
230
|
-
@code = response.class.to_s == "HTTParty::Response" ? response.code : nil
|
|
141
|
+
def initialize(message = nil,response=nil, *args)
|
|
142
|
+
@code = response.present? && response.class.to_s == "HTTParty::Response" ? response.code : nil
|
|
231
143
|
@message = message
|
|
232
144
|
@response = response
|
|
233
145
|
@default_message = "Authentication type is not supported by this Login"
|
|
@@ -239,14 +151,13 @@ module ZuoraAPI
|
|
|
239
151
|
end
|
|
240
152
|
|
|
241
153
|
class ZuoraAPIReadTimeout < Net::ReadTimeout
|
|
242
|
-
attr_reader :code, :response
|
|
154
|
+
attr_reader :code, :response
|
|
243
155
|
attr_writer :default_message
|
|
244
156
|
|
|
245
|
-
def initialize(message = nil,
|
|
246
|
-
@code = response.class.to_s == "HTTParty::Response" ? response.code : nil
|
|
157
|
+
def initialize(message = nil,response=nil, *args)
|
|
158
|
+
@code = response.present? && response.class.to_s == "HTTParty::Response" ? response.code : nil
|
|
247
159
|
@message = message
|
|
248
160
|
@response = response
|
|
249
|
-
@request = request
|
|
250
161
|
@default_message = "Authentication type is not supported by this Login"
|
|
251
162
|
end
|
|
252
163
|
|
data/lib/zuora_api/login.rb
CHANGED
|
@@ -5,9 +5,9 @@ require 'zuora_api/exceptions'
|
|
|
5
5
|
|
|
6
6
|
module ZuoraAPI
|
|
7
7
|
class Login
|
|
8
|
-
ENVIRONMENTS = [
|
|
8
|
+
ENVIRONMENTS = [SANDBOX = 'Sandbox', PRODUCTION = 'Production', PREFORMANCE = 'Preformance', SERVICES = 'Services', UNKNOWN = 'Unknown', STAGING = 'Staging' ]
|
|
9
9
|
REGIONS = [EU = 'EU', US = 'US', NA = 'NA' ]
|
|
10
|
-
|
|
10
|
+
MIN_Endpoint = '96.0'
|
|
11
11
|
XML_SAVE_OPTIONS = Nokogiri::XML::Node::SaveOptions::AS_XML | Nokogiri::XML::Node::SaveOptions::NO_DECLARATION
|
|
12
12
|
|
|
13
13
|
CONNECTION_EXCEPTIONS = [
|
|
@@ -16,8 +16,7 @@ module ZuoraAPI
|
|
|
16
16
|
Errno::ECONNREFUSED,
|
|
17
17
|
SocketError,
|
|
18
18
|
Errno::EHOSTUNREACH,
|
|
19
|
-
Errno::EADDRNOTAVAIL
|
|
20
|
-
Errno::ETIMEDOUT,
|
|
19
|
+
Errno::EADDRNOTAVAIL
|
|
21
20
|
].freeze
|
|
22
21
|
|
|
23
22
|
CONNECTION_READ_EXCEPTIONS = [
|
|
@@ -31,17 +30,7 @@ module ZuoraAPI
|
|
|
31
30
|
ZuoraAPI::Exceptions::ZuoraAPIRequestLimit,
|
|
32
31
|
ZuoraAPI::Exceptions::ZuoraAPILockCompetition,
|
|
33
32
|
ZuoraAPI::Exceptions::ZuoraAPITemporaryError,
|
|
34
|
-
ZuoraAPI::Exceptions::ZuoraDataIntegrity
|
|
35
|
-
ZuoraAPI::Exceptions::ZuoraAPIInternalServerError,
|
|
36
|
-
ZuoraAPI::Exceptions::ZuoraUnexpectedError,
|
|
37
|
-
ZuoraAPI::Exceptions::ZuoraAPIUnkownError
|
|
38
|
-
].freeze
|
|
39
|
-
|
|
40
|
-
ZUORA_SERVER_ERRORS = [
|
|
41
|
-
ZuoraAPI::Exceptions::ZuoraAPIInternalServerError,
|
|
42
|
-
ZuoraAPI::Exceptions::ZuoraAPIConnectionTimeout,
|
|
43
|
-
ZuoraAPI::Exceptions::ZuoraAPIReadTimeout,
|
|
44
|
-
ZuoraAPI::Exceptions::ZuoraUnexpectedError
|
|
33
|
+
ZuoraAPI::Exceptions::ZuoraDataIntegrity
|
|
45
34
|
].freeze
|
|
46
35
|
|
|
47
36
|
attr_accessor :region, :url, :wsdl_number, :current_session, :bearer_token, :oauth_session_expires_at, :environment, :status, :errors, :current_error, :user_info, :tenant_id, :tenant_name, :entity_id, :timeout_sleep, :hostname, :zconnect_provider
|
|
@@ -50,12 +39,10 @@ module ZuoraAPI
|
|
|
50
39
|
raise "URL is nil or empty, but URL is required" if url.nil? || url.empty?
|
|
51
40
|
# raise "URL is improper. URL must contain zuora.com, zuora.eu, or zuora.na" if /zuora.com|zuora.eu|zuora.na/ === url
|
|
52
41
|
self.hostname = /(?<=https:\/\/|http:\/\/)(.*?)(?=\/|$)/.match(url)[0] if !/(?<=https:\/\/|http:\/\/)(.*?)(?=\/|$)/.match(url).nil?
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
self.url =
|
|
57
|
-
elsif min_endpoint.to_f > url.scan(/(\d+\.\d)$/).dig(0,0).to_f
|
|
58
|
-
self.url = url.gsub(/(\d+\.\d)$/, min_endpoint)
|
|
42
|
+
if !/apps\/services\/a\/\d{2}\.\d$/.match(url.strip)
|
|
43
|
+
self.url = "https://#{hostname}/apps/services/a/#{MIN_Endpoint}"
|
|
44
|
+
elsif MIN_Endpoint.to_f > url.scan(/(\d{2}\.\d)$/).dig(0,0).to_f
|
|
45
|
+
self.url = url.gsub(/(\d{2}\.\d)$/, MIN_Endpoint)
|
|
59
46
|
else
|
|
60
47
|
self.url = url
|
|
61
48
|
end
|
|
@@ -67,18 +54,34 @@ module ZuoraAPI
|
|
|
67
54
|
self.status = status.blank? ? "Active" : status
|
|
68
55
|
self.user_info = Hash.new
|
|
69
56
|
self.update_region
|
|
57
|
+
self.update_environment
|
|
70
58
|
self.update_zconnect_provider
|
|
71
59
|
@timeout_sleep = 5
|
|
72
60
|
end
|
|
73
61
|
|
|
74
62
|
def get_identity(cookies)
|
|
75
63
|
zsession = cookies["ZSession"]
|
|
64
|
+
zconnect_accesstoken = get_zconnect_accesstoken(cookies)
|
|
76
65
|
begin
|
|
77
66
|
if !zsession.blank?
|
|
78
67
|
response = HTTParty.get("https://#{self.hostname}/apps/v1/identity", :headers => {'Cookie' => "ZSession=#{zsession}", 'Content-Type' => 'application/json'})
|
|
79
68
|
output_json = JSON.parse(response.body)
|
|
69
|
+
elsif zconnect_accesstoken.present?
|
|
70
|
+
begin
|
|
71
|
+
code = zconnect_accesstoken.split("#!").last
|
|
72
|
+
encrypted_token, tenant_id = Base64.decode64(code).split(":")
|
|
73
|
+
body = {'token' => encrypted_token}.to_json
|
|
74
|
+
rescue => ex
|
|
75
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Invalid ZConnect Cookie")
|
|
76
|
+
end
|
|
77
|
+
response = HTTParty.post("https://#{self.hostname}/apps/zconnectsession/identity", :body => body, :headers => { 'Content-Type' => 'application/json' })
|
|
78
|
+
output_json = JSON.parse(response.body)
|
|
80
79
|
else
|
|
81
|
-
|
|
80
|
+
if zconnect_accesstoken.blank? && cookies.keys.any? { |x| x.include? "ZConnect"}
|
|
81
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZConnect cookie present matching #{self.hostname}")
|
|
82
|
+
else
|
|
83
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present")
|
|
84
|
+
end
|
|
82
85
|
end
|
|
83
86
|
rescue JSON::ParserError => ex
|
|
84
87
|
output_json = {}
|
|
@@ -89,12 +92,20 @@ module ZuoraAPI
|
|
|
89
92
|
|
|
90
93
|
def get_full_nav(cookies)
|
|
91
94
|
zsession = cookies["ZSession"]
|
|
95
|
+
zconnect_accesstoken = get_zconnect_accesstoken(cookies)
|
|
92
96
|
begin
|
|
93
97
|
if zsession.present?
|
|
94
98
|
response = HTTParty.get("https://#{self.hostname}/apps/v1/navigation", :headers => {'Cookie' => "ZSession=#{zsession}", 'Content-Type' => 'application/json'})
|
|
95
99
|
output_json = JSON.parse(response.body)
|
|
100
|
+
elsif zconnect_accesstoken.present?
|
|
101
|
+
response = HTTParty.get("https://#{self.hostname}/apps/zconnectsession/navigation", :headers => {'Cookie' => "#{self.zconnect_provider}=#{zconnect_accesstoken}",'Content-Type' => 'application/json'})
|
|
102
|
+
output_json = JSON.parse(response.body)
|
|
96
103
|
else
|
|
97
|
-
|
|
104
|
+
if zconnect_accesstoken.blank? && cookies.keys.any? { |x| x.include? "ZConnect"}
|
|
105
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZConnect cookie present matching #{self.hostname}")
|
|
106
|
+
else
|
|
107
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present")
|
|
108
|
+
end
|
|
98
109
|
end
|
|
99
110
|
rescue JSON::ParserError => ex
|
|
100
111
|
output_json = {}
|
|
@@ -105,12 +116,20 @@ module ZuoraAPI
|
|
|
105
116
|
|
|
106
117
|
def set_nav(state, cookies)
|
|
107
118
|
zsession = cookies["ZSession"]
|
|
119
|
+
zconnect_accesstoken = get_zconnect_accesstoken(cookies)
|
|
108
120
|
begin
|
|
109
121
|
if !zsession.blank?
|
|
110
122
|
response = HTTParty.put("https://#{self.hostname}/apps/v1/preference/navigation", :body => state.to_json, :headers => {'Cookie' => "ZSession=#{zsession}", 'Content-Type' => 'application/json'})
|
|
111
123
|
output_json = JSON.parse(response.body)
|
|
124
|
+
elsif !zconnect_accesstoken.blank?
|
|
125
|
+
response = HTTParty.post("https://#{self.hostname}/apps/zconnectsession/navigationstate", :body => state.to_json, :headers => {'Cookie' => "#{self.zconnect_provider}=#{zconnect_accesstoken}", 'Content-Type' => 'application/json'})
|
|
126
|
+
output_json = JSON.parse(response.body)
|
|
112
127
|
else
|
|
113
|
-
|
|
128
|
+
if zconnect_accesstoken.blank? && cookies.keys.any? { |x| x.include? "ZConnect"}
|
|
129
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZConnect cookie present matching #{self.hostname}")
|
|
130
|
+
else
|
|
131
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present")
|
|
132
|
+
end
|
|
114
133
|
end
|
|
115
134
|
rescue JSON::ParserError => ex
|
|
116
135
|
output_json = {}
|
|
@@ -121,12 +140,20 @@ module ZuoraAPI
|
|
|
121
140
|
|
|
122
141
|
def refresh_nav(cookies)
|
|
123
142
|
zsession = cookies["ZSession"]
|
|
143
|
+
zconnect_accesstoken = get_zconnect_accesstoken(cookies)
|
|
124
144
|
begin
|
|
125
145
|
if !zsession.blank?
|
|
126
146
|
response = HTTParty.post("https://#{self.hostname}/apps/v1/navigation/fetch", :headers => {'Cookie' => "ZSession=#{zsession}", 'Content-Type' => 'application/json'})
|
|
127
147
|
output_json = JSON.parse(response.body)
|
|
148
|
+
elsif !zconnect_accesstoken.blank?
|
|
149
|
+
response = HTTParty.post("https://#{self.hostname}/apps/zconnectsession/refresh-navbarcache", :headers => {'Cookie' => "#{self.zconnect_provider}=#{zconnect_accesstoken}", 'Content-Type' => 'application/json'})
|
|
150
|
+
output_json = JSON.parse(response.body)
|
|
128
151
|
else
|
|
129
|
-
|
|
152
|
+
if zconnect_accesstoken.blank? && cookies.keys.any? { |x| x.include? "ZConnect"}
|
|
153
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZConnect cookie present matching #{self.hostname}")
|
|
154
|
+
else
|
|
155
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIError.new("No ZSession cookie present")
|
|
156
|
+
end
|
|
130
157
|
end
|
|
131
158
|
rescue JSON::ParserError => ex
|
|
132
159
|
output_json = {}
|
|
@@ -135,21 +162,27 @@ module ZuoraAPI
|
|
|
135
162
|
return output_json
|
|
136
163
|
end
|
|
137
164
|
|
|
165
|
+
def get_zconnect_accesstoken(cookies)
|
|
166
|
+
accesstoken = nil
|
|
167
|
+
self.update_zconnect_provider
|
|
168
|
+
if !cookies[self.zconnect_provider].nil? && !cookies[self.zconnect_provider].empty?
|
|
169
|
+
accesstoken = cookies[self.zconnect_provider]
|
|
170
|
+
end
|
|
171
|
+
return accesstoken
|
|
172
|
+
end
|
|
173
|
+
|
|
138
174
|
def reporting_url(path)
|
|
139
175
|
map = {"US" => {"Sandbox" => "https://zconnectsandbox.zuora.com/api/rest/v1/",
|
|
140
176
|
"Production" => "https://zconnect.zuora.com/api/rest/v1/",
|
|
141
|
-
"
|
|
142
|
-
"Staging" => "https://reporting-stg11.zan.svc.auw2.zuora.com/api/rest/v1/",
|
|
143
|
-
"Performance" => "https://zconnectpt1.zuora.com/api/rest/v1/",
|
|
144
|
-
"Services" => "https://reporting-svc08.svc.auw2.zuora.com/api/rest/v1/"},
|
|
177
|
+
"Services"=> ""},
|
|
145
178
|
"EU" => {"Sandbox" => "https://zconnect.sandbox.eu.zuora.com/api/rest/v1/",
|
|
146
179
|
"Production" => "https://zconnect.eu.zuora.com/api/rest/v1/",
|
|
147
|
-
"Services"=> "
|
|
180
|
+
"Services"=> ""},
|
|
148
181
|
"NA" => {"Sandbox" => "https://zconnect.sandbox.na.zuora.com/api/rest/v1/",
|
|
149
182
|
"Production" => "https://zconnect.na.zuora.com/api/rest/v1/",
|
|
150
183
|
"Services"=> ""}
|
|
151
184
|
}
|
|
152
|
-
return map[
|
|
185
|
+
return map[zuora_client.region][zuora_client.environment].insert(-1, path)
|
|
153
186
|
end
|
|
154
187
|
|
|
155
188
|
# There are two ways to call this method. The first way is best.
|
|
@@ -199,7 +232,7 @@ module ZuoraAPI
|
|
|
199
232
|
end
|
|
200
233
|
|
|
201
234
|
def self.environments
|
|
202
|
-
%w(Sandbox Production Services Performance Staging
|
|
235
|
+
%w(Sandbox Production Services Performance Staging)
|
|
203
236
|
end
|
|
204
237
|
|
|
205
238
|
def self.regions
|
|
@@ -211,13 +244,11 @@ module ZuoraAPI
|
|
|
211
244
|
"Production" => "https://www.zuora.com/apps/services/a/",
|
|
212
245
|
"Performance" => "https://pt1.zuora.com/apps/services/a/",
|
|
213
246
|
"Services" => "https://services347.zuora.com/apps/services/a/",
|
|
214
|
-
"Staging" => "https://staging2.zuora.com/apps/services/a/",
|
|
215
|
-
"Test" => "https://test.zuora.com/apps/services/a/"},
|
|
247
|
+
"Staging" => "https://staging2.zuora.com/apps/services/a/"},
|
|
216
248
|
"EU" => {"Sandbox" => "https://sandbox.eu.zuora.com/apps/services/a/",
|
|
217
249
|
"Production" => "https://eu.zuora.com/apps/services/a/",
|
|
218
250
|
"Performance" => "https://pt1.eu.zuora.com/apps/services/a/",
|
|
219
|
-
"Services" => "https://services347.eu.zuora.com/apps/services/a/",
|
|
220
|
-
"Test" => "https://test.eu.zuora.com/apps/services/a/"},
|
|
251
|
+
"Services" => "https://services347.eu.zuora.com/apps/services/a/"},
|
|
221
252
|
"NA" => {"Sandbox" => "https://sandbox.na.zuora.com/apps/services/a/",
|
|
222
253
|
"Production" => "https://na.zuora.com/apps/services/a/",
|
|
223
254
|
"Performance" => "https://pt1.na.zuora.com/apps/services/a/",
|
|
@@ -253,19 +284,16 @@ module ZuoraAPI
|
|
|
253
284
|
end
|
|
254
285
|
|
|
255
286
|
def update_environment
|
|
256
|
-
if !self.
|
|
257
|
-
|
|
258
|
-
when /(?<=\.|\/|-|^)(apisandbox|sandbox)(?=\.|\/|-|$)/
|
|
287
|
+
if !self.url.blank?
|
|
288
|
+
if /(?<=\.|\/|-|^)(apisandbox|sandbox)(?=\.|\/|-|$)/ === self.hostname
|
|
259
289
|
self.environment = 'Sandbox'
|
|
260
|
-
|
|
290
|
+
elsif /(?<=\.|\/|^)(service[\d]*|services[\d]*|ep-edge)(?=\.|\/|$)/ === self.hostname
|
|
261
291
|
self.environment = 'Services'
|
|
262
|
-
|
|
292
|
+
elsif /(?<=\.|\/|-|^)(pt[\d]*)(?=\.|\/|-|$)/ === self.hostname
|
|
263
293
|
self.environment = 'Performance'
|
|
264
|
-
|
|
294
|
+
elsif /(?<=\.|\/|^)(staging1|staging2|stg)(?=\.|\/|$)/ === self.hostname
|
|
265
295
|
self.environment = 'Staging'
|
|
266
|
-
|
|
267
|
-
self.environment = 'Test'
|
|
268
|
-
when /(?<=\.|\/|^)(www|api)(?=\.|\/|$)/, /(^|tls10\.|origin-www\.|zforsf\.|eu\.|na\.)(zuora\.com)/
|
|
296
|
+
elsif is_prod_env
|
|
269
297
|
self.environment = 'Production'
|
|
270
298
|
else
|
|
271
299
|
self.environment = 'Unknown'
|
|
@@ -275,14 +303,24 @@ module ZuoraAPI
|
|
|
275
303
|
end
|
|
276
304
|
end
|
|
277
305
|
|
|
306
|
+
def is_prod_env
|
|
307
|
+
is_prod = false
|
|
308
|
+
www_or_api = /(?<=\.|\/|^)(www|api)(?=\.|\/|$)/ === self.hostname
|
|
309
|
+
host_prefix_match = /(^|tls10\.|origin-www\.|zforsf\.|eu\.|na\.)(zuora\.com)/ === self.hostname
|
|
310
|
+
if www_or_api || host_prefix_match
|
|
311
|
+
is_prod = true
|
|
312
|
+
end
|
|
313
|
+
return is_prod
|
|
314
|
+
end
|
|
315
|
+
|
|
278
316
|
def update_zconnect_provider
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
mappings = {"US" => {"Sandbox" => "ZConnectSbx",
|
|
317
|
+
region = update_region
|
|
318
|
+
environment = update_environment
|
|
319
|
+
mappings = {"US" => {"Sandbox" => "ZConnectSbx", "KubeSTG" => "ZConnectDev", "KubeDEV" => "ZConnectDev", "KubePROD" => "ZConnectDev", "Services" => "ZConnectSvcUS", "Production" => "ZConnectProd", "Performance" => "ZConnectPT1", "Staging" => "ZConnectQA"},
|
|
282
320
|
"NA" => {"Sandbox" => "ZConnectSbxNA", "Services" => "ZConnectSvcNA", "Production" => "ZConnectProdNA", "Performance" => "ZConnectPT1NA"},
|
|
283
|
-
"EU" => {"Sandbox" => "ZConnectSbxEU", "Services" => "ZConnectSvcEU", "Production" => "ZConnectProdEU", "Performance" => "ZConnectPT1EU"
|
|
321
|
+
"EU" => {"Sandbox" => "ZConnectSbxEU", "Services" => "ZConnectSvcEU", "Production" => "ZConnectProdEU", "Performance" => "ZConnectPT1EU"},
|
|
284
322
|
"Unknown" => {"Unknown" => "Unknown"}}
|
|
285
|
-
self.zconnect_provider = mappings[
|
|
323
|
+
self.zconnect_provider = mappings[region][environment]
|
|
286
324
|
end
|
|
287
325
|
|
|
288
326
|
def aqua_endpoint(url="")
|
|
@@ -295,35 +333,45 @@ module ZuoraAPI
|
|
|
295
333
|
return "#{url_slash_apps_slash}api/#{url}"
|
|
296
334
|
end
|
|
297
335
|
|
|
298
|
-
def rest_endpoint(url=""
|
|
336
|
+
def rest_endpoint(url="")
|
|
299
337
|
update_environment
|
|
300
338
|
endpoint = url
|
|
301
|
-
|
|
302
|
-
|
|
339
|
+
|
|
303
340
|
case self.environment
|
|
304
|
-
when 'Test'
|
|
305
|
-
endpoint = "https://rest.test#{url_postfix}zuora.com"
|
|
306
341
|
when 'Sandbox'
|
|
307
|
-
|
|
308
|
-
|
|
342
|
+
case self.region
|
|
343
|
+
when 'US'
|
|
344
|
+
endpoint = "https://rest.apisandbox.zuora.com/v1/".concat(url)
|
|
345
|
+
when 'EU'
|
|
346
|
+
endpoint = "https://rest.sandbox.eu.zuora.com/v1/".concat(url)
|
|
347
|
+
when 'NA'
|
|
348
|
+
endpoint = "https://rest.sandbox.na.zuora.com/v1/".concat(url)
|
|
349
|
+
end
|
|
309
350
|
when 'Production'
|
|
310
|
-
|
|
351
|
+
case self.region
|
|
352
|
+
when 'US'
|
|
353
|
+
endpoint = "https://rest.zuora.com/v1/".concat(url)
|
|
354
|
+
when 'EU'
|
|
355
|
+
endpoint = "https://rest.eu.zuora.com/v1/".concat(url)
|
|
356
|
+
when 'NA'
|
|
357
|
+
endpoint = "https://rest.na.zuora.com/v1/".concat(url)
|
|
358
|
+
end
|
|
311
359
|
when 'Performance'
|
|
312
|
-
endpoint = "https://rest.pt1.zuora.com"
|
|
360
|
+
endpoint = "https://rest.pt1.zuora.com/v1/".concat(url)
|
|
313
361
|
when 'Services'
|
|
314
362
|
https = /https:\/\/|http:\/\//.match(self.url)[0]
|
|
315
363
|
host = self.hostname
|
|
316
|
-
endpoint = "#{https}rest#{host}"
|
|
364
|
+
endpoint = "#{https}rest#{host}/v1/#{url}"
|
|
317
365
|
when 'Staging'
|
|
318
|
-
endpoint = "https://rest-staging2.zuora.com"
|
|
366
|
+
endpoint = "https://rest-staging2.zuora.com/v1/".concat(url)
|
|
319
367
|
when 'Unknown'
|
|
320
368
|
raise "Environment unknown, returning passed in parameter unaltered"
|
|
321
369
|
end
|
|
322
|
-
return
|
|
370
|
+
return endpoint
|
|
323
371
|
end
|
|
324
372
|
|
|
325
|
-
def rest_domain
|
|
326
|
-
return URI(
|
|
373
|
+
def rest_domain
|
|
374
|
+
return URI(self.rest_endpoint).host
|
|
327
375
|
end
|
|
328
376
|
|
|
329
377
|
def fileURL(url="")
|
|
@@ -334,89 +382,43 @@ module ZuoraAPI
|
|
|
334
382
|
return self.wsdl_number > 68 ? '%Y-%m-%d' : '%Y-%m-%dT%H:%M:%S'
|
|
335
383
|
end
|
|
336
384
|
|
|
337
|
-
def new_session(auth_type: :basic, debug: false
|
|
338
|
-
retries ||= 2
|
|
339
|
-
yield
|
|
340
|
-
|
|
341
|
-
rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
|
|
342
|
-
self.status = 'Invalid'
|
|
343
|
-
self.current_error = ex.message
|
|
344
|
-
raise
|
|
345
|
-
rescue ZuoraAPI::Exceptions::ZuoraAPIError => ex
|
|
346
|
-
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(ex.message, ex.response)
|
|
347
|
-
|
|
348
|
-
rescue ZuoraAPI::Exceptions::ZuoraAPIInternalServerError => ex
|
|
349
|
-
raise ex if retries.zero?
|
|
350
|
-
|
|
351
|
-
retries -= 1
|
|
352
|
-
sleep(self.timeout_sleep)
|
|
353
|
-
retry
|
|
354
|
-
|
|
355
|
-
rescue *(CONNECTION_EXCEPTIONS + CONNECTION_READ_EXCEPTIONS) => ex
|
|
356
|
-
self.log(location: "BasicLogin", exception: ex, message: "Timed out", level: :error)
|
|
357
|
-
|
|
358
|
-
self.current_error = "Request timed out. Try again"
|
|
359
|
-
self.status = 'Timeout'
|
|
360
|
-
|
|
361
|
-
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error)
|
|
362
|
-
|
|
363
|
-
rescue EOFError
|
|
364
|
-
if self.url.match?(/.*services\d{1,}.zuora.com*/)
|
|
365
|
-
self.current_error = "Services tenant '#{self.url.scan(/.*\/\/(services\d{1,}).zuora.com*/).last.first}' is no longer available."
|
|
366
|
-
self.status = 'Not Available'
|
|
367
|
-
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error)
|
|
368
|
-
end
|
|
369
|
-
|
|
385
|
+
def new_session(auth_type: :basic, debug: false)
|
|
370
386
|
end
|
|
371
387
|
|
|
372
|
-
def get_session(prefix: false, auth_type: :basic
|
|
388
|
+
def get_session(prefix: false, auth_type: :basic)
|
|
389
|
+
Rails.logger.debug("Get session for #{auth_type} - #{self.class.to_s}") if Rails.env.to_s == 'development'
|
|
373
390
|
case auth_type
|
|
374
391
|
when :basic
|
|
375
392
|
if self.current_session.blank?
|
|
376
393
|
case self.class.to_s
|
|
377
394
|
when 'ZuoraAPI::Oauth'
|
|
378
395
|
if self.bearer_token.blank? || self.oauth_expired?
|
|
379
|
-
self.new_session(auth_type: :bearer
|
|
396
|
+
self.new_session(auth_type: :bearer)
|
|
380
397
|
end
|
|
381
|
-
self.get_z_session
|
|
398
|
+
self.get_z_session if self.status == 'Active'
|
|
382
399
|
when 'ZuoraAPI::Basic'
|
|
383
|
-
self.new_session(auth_type: :basic
|
|
400
|
+
self.new_session(auth_type: :basic)
|
|
384
401
|
else
|
|
385
|
-
|
|
402
|
+
raise "No Zuora Login Specified"
|
|
386
403
|
end
|
|
387
404
|
end
|
|
405
|
+
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error) if self.status != 'Active'
|
|
388
406
|
return prefix ? "ZSession #{self.current_session}" : self.current_session.to_s
|
|
389
407
|
when :bearer
|
|
390
408
|
case self.class.to_s
|
|
391
409
|
when 'ZuoraAPI::Oauth'
|
|
392
410
|
if self.bearer_token.blank? || self.oauth_expired?
|
|
393
|
-
self.new_session(auth_type: :bearer
|
|
411
|
+
self.new_session(auth_type: :bearer)
|
|
394
412
|
end
|
|
395
413
|
when 'ZuoraAPI::Basic'
|
|
396
414
|
raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Basic Login, does not support Authentication of Type: #{auth_type}")
|
|
397
|
-
else
|
|
398
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Unknown Login, does not support Authentication of Type: #{auth_type}")
|
|
399
415
|
end
|
|
416
|
+
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error) if self.status != 'Active'
|
|
400
417
|
return prefix ? "Bearer #{self.bearer_token}" : self.bearer_token.to_s
|
|
401
418
|
end
|
|
402
419
|
end
|
|
403
420
|
|
|
404
|
-
def soap_call(
|
|
405
|
-
ns1: 'ns1',
|
|
406
|
-
ns2: 'ns2',
|
|
407
|
-
batch_size: nil,
|
|
408
|
-
headers: {},
|
|
409
|
-
single_transaction: false,
|
|
410
|
-
debug: false,
|
|
411
|
-
zuora_track_id: nil,
|
|
412
|
-
errors: [ZuoraAPI::Exceptions::ZuoraAPISessionError].concat(ZUORA_API_ERRORS),
|
|
413
|
-
z_session: true,
|
|
414
|
-
timeout_retry: false,
|
|
415
|
-
timeout: 130,
|
|
416
|
-
timeout_sleep_interval: self.timeout_sleep,
|
|
417
|
-
output_exception_messages: true,
|
|
418
|
-
skip_session: false,
|
|
419
|
-
**keyword_args)
|
|
421
|
+
def soap_call(ns1: 'ns1', ns2: 'ns2', batch_size: nil, single_transaction: false, debug: false, errors: [ZuoraAPI::Exceptions::ZuoraAPISessionError].concat(ZUORA_API_ERRORS), z_session: true, timeout_retry: false, timeout: 120,**keyword_args)
|
|
420
422
|
tries ||= 2
|
|
421
423
|
xml = Nokogiri::XML::Builder.new do |xml|
|
|
422
424
|
xml['SOAP-ENV'].Envelope('xmlns:SOAP-ENV' => "http://schemas.xmlsoap.org/soap/envelope/",
|
|
@@ -425,10 +427,8 @@ module ZuoraAPI
|
|
|
425
427
|
'xmlns:api' => "http://api.zuora.com/",
|
|
426
428
|
"xmlns:#{ns1}" => "http://api.zuora.com/") do
|
|
427
429
|
xml['SOAP-ENV'].Header do
|
|
428
|
-
|
|
429
|
-
xml["#{ns1}"].
|
|
430
|
-
xml["#{ns1}"].session self.get_session(prefix: false, auth_type: :basic, zuora_track_id: zuora_track_id)
|
|
431
|
-
end
|
|
430
|
+
xml["#{ns1}"].SessionHeader do
|
|
431
|
+
xml["#{ns1}"].session self.get_session(prefix: false, auth_type: :basic)
|
|
432
432
|
end
|
|
433
433
|
if single_transaction
|
|
434
434
|
xml["#{ns1}"].CallOptions do
|
|
@@ -446,212 +446,96 @@ module ZuoraAPI
|
|
|
446
446
|
end
|
|
447
447
|
end
|
|
448
448
|
end
|
|
449
|
+
|
|
449
450
|
input_xml = Nokogiri::XML(xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip)
|
|
450
451
|
input_xml.xpath('//ns1:session', 'ns1' =>'http://api.zuora.com/').children.remove
|
|
451
452
|
Rails.logger.debug("Request SOAP XML: #{input_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}") if debug
|
|
452
453
|
|
|
453
|
-
|
|
454
|
-
headers['Zuora-Track-Id'] = zuora_track_id if zuora_track_id.present?
|
|
455
|
-
|
|
456
|
-
request = HTTParty::Request.new(
|
|
457
|
-
Net::HTTP::Post,
|
|
458
|
-
self.url,
|
|
459
|
-
body: xml.doc.to_xml(:save_with => XML_SAVE_OPTIONS).strip,
|
|
460
|
-
headers: headers,
|
|
461
|
-
timeout: timeout,
|
|
462
|
-
)
|
|
463
|
-
|
|
464
|
-
response = request.perform
|
|
465
|
-
|
|
454
|
+
response = HTTParty.post(self.url,:body => xml.doc.to_xml(:save_with => XML_SAVE_OPTIONS).strip, :headers => {'Content-Type' => "text/xml; charset=utf-8"}, :timeout => timeout)
|
|
466
455
|
output_xml = Nokogiri::XML(response.body)
|
|
467
456
|
Rails.logger.debug("Response SOAP XML: #{output_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}") if debug
|
|
468
457
|
|
|
469
458
|
raise_errors(type: :SOAP, body: output_xml, response: response)
|
|
470
|
-
|
|
471
|
-
return output_xml, input_xml, response
|
|
472
|
-
|
|
473
459
|
rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
|
|
474
|
-
|
|
475
|
-
if !tries.zero? && z_session
|
|
476
|
-
tries -= 1
|
|
460
|
+
if !(tries -= 1).zero? && z_session
|
|
477
461
|
Rails.logger.debug("SOAP Call - Session Invalid")
|
|
478
|
-
|
|
479
|
-
begin
|
|
480
|
-
self.new_session(auth_type: :basic, zuora_track_id: zuora_track_id)
|
|
481
|
-
rescue *ZUORA_API_ERRORS => ex
|
|
482
|
-
return output_xml, input_xml, ex.response
|
|
483
|
-
end
|
|
484
|
-
|
|
462
|
+
self.new_session(auth_type: :basic)
|
|
485
463
|
retry
|
|
464
|
+
else
|
|
465
|
+
if errors.include?(ex.class)
|
|
466
|
+
raise ex
|
|
467
|
+
else
|
|
468
|
+
return output_xml, input_xml, response
|
|
469
|
+
end
|
|
486
470
|
end
|
|
487
|
-
|
|
488
|
-
raise ex if errors.include?(ex.class)
|
|
489
|
-
|
|
490
|
-
return output_xml, input_xml, response
|
|
491
|
-
|
|
492
471
|
rescue *ZUORA_API_ERRORS => ex
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
472
|
+
if errors.include?(ex.class)
|
|
473
|
+
raise ex
|
|
474
|
+
else
|
|
475
|
+
return output_xml, input_xml, response
|
|
476
|
+
end
|
|
498
477
|
rescue *CONNECTION_EXCEPTIONS => ex
|
|
499
|
-
if !tries.zero?
|
|
500
|
-
|
|
501
|
-
self.
|
|
502
|
-
sleep(timeout_sleep_interval)
|
|
478
|
+
if !(tries -= 1).zero?
|
|
479
|
+
Rails.logger.info("SOAP Call - #{ex.class} Timed out will retry after 5 seconds")
|
|
480
|
+
sleep(self.timeout_sleep)
|
|
503
481
|
retry
|
|
482
|
+
else
|
|
483
|
+
raise ex
|
|
504
484
|
end
|
|
505
|
-
|
|
506
|
-
self.log(location: "SOAP Call", exception: ex, message: "Timed out", level: :error) if output_exception_messages
|
|
507
|
-
raise ex
|
|
508
|
-
|
|
509
485
|
rescue *CONNECTION_READ_EXCEPTIONS => ex
|
|
510
|
-
if !tries.zero?
|
|
511
|
-
|
|
512
|
-
self.
|
|
513
|
-
|
|
514
|
-
retry
|
|
515
|
-
elsif timeout_retry
|
|
516
|
-
sleep(timeout_sleep_interval)
|
|
517
|
-
retry
|
|
518
|
-
end
|
|
519
|
-
end
|
|
520
|
-
|
|
521
|
-
self.log(location: "SOAP Call", exception: ex, message: "Timed out", level: :error) if output_exception_messages
|
|
522
|
-
ex = ZuoraAPI::Exceptions::ZuoraAPIReadTimeout.new("Received read timeout from 'https://#{rest_domain(endpoint: url)}'", nil, request) if ex.instance_of?(Net::ReadTimeout)
|
|
523
|
-
raise ex
|
|
524
|
-
|
|
525
|
-
rescue => ex
|
|
526
|
-
raise ex
|
|
527
|
-
ensure
|
|
528
|
-
self.error_logger(ex) if defined?(ex) && Rails.logger.class.to_s == "Ougai::Logger"
|
|
529
|
-
end
|
|
530
|
-
|
|
531
|
-
def error_logger(ex)
|
|
532
|
-
exception_args = Rails.logger.with_fields.merge(self.exception_args(ex))
|
|
533
|
-
case ex
|
|
534
|
-
when ZuoraAPI::Exceptions::ZuoraAPIUnkownError, ZuoraAPI::Exceptions::ZuoraDataIntegrity
|
|
535
|
-
Rails.logger.error('Zuora Unknown/Integrity Error', ex, exception_args)
|
|
536
|
-
when ZuoraAPI::Exceptions::ZuoraAPIRequestLimit
|
|
537
|
-
Rails.logger.info('Zuora APILimit Reached', exception_args)
|
|
538
|
-
when *(ZuoraAPI::Login::ZUORA_API_ERRORS-ZuoraAPI::Login::ZUORA_SERVER_ERRORS)
|
|
539
|
-
#Rails.logger.debug('Zuora API Error', ex, self.exception_args(ex))
|
|
540
|
-
when *ZuoraAPI::Login::ZUORA_SERVER_ERRORS
|
|
541
|
-
Rails.logger.error('Zuora Server Error', ex, exception_args)
|
|
542
|
-
end
|
|
543
|
-
end
|
|
544
|
-
|
|
545
|
-
def log(location: "Rest Call", exception: nil, message: "Timed out will retry after #{self.timeout_sleep} seconds", level: :info )
|
|
546
|
-
level = :debug if ![:debug, :info, :warn, :error, :fatal].include?(level)
|
|
547
|
-
if Rails.logger.class.to_s == "Ougai::Logger"
|
|
548
|
-
Rails.logger.send(level.to_sym, "#{location} - #{message}", exception)
|
|
486
|
+
if !(tries -= 1).zero? && timeout_retry
|
|
487
|
+
Rails.logger.info("SOAP Call - #{ex.class} Timed out will retry after 5 seconds")
|
|
488
|
+
sleep(self.timeout_sleep)
|
|
489
|
+
retry
|
|
549
490
|
else
|
|
550
|
-
|
|
491
|
+
raise ex
|
|
551
492
|
end
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
args.merge!({
|
|
558
|
-
zuora_trace_id: ex.response.headers["zuora-request-id"],
|
|
559
|
-
zuora_track_id: ex.response.request.options[:headers]["Zuora-Track-Id"]
|
|
560
|
-
})
|
|
561
|
-
elsif defined?(ex.response) && ex.response.present?
|
|
562
|
-
args.merge!({
|
|
563
|
-
request: {
|
|
564
|
-
path: ex.response.request.path.to_s,
|
|
565
|
-
method: ex.response.request.http_method.to_s.split("Net::HTTP::").last.upcase,
|
|
566
|
-
params: ex.response.request.raw_body.to_s,
|
|
567
|
-
headers: ex.response.request.options[:headers].map{|k,v| [k.to_s, k.to_s.downcase.strip == "authorization" ? "VALUE FILTERED" : v]}.to_h.to_s,
|
|
568
|
-
},
|
|
569
|
-
response: {
|
|
570
|
-
status: ex.response.code,
|
|
571
|
-
params: ex.response.body.to_s,
|
|
572
|
-
headers: ex.response.headers.to_s,
|
|
573
|
-
},
|
|
574
|
-
zuora_trace_id: ex.response.headers["zuora-request-id"],
|
|
575
|
-
zuora_track_id: ex.response.request.options[:headers]["Zuora-Track-Id"],
|
|
576
|
-
})
|
|
577
|
-
elsif defined?(ex.request) && ex.request.present?
|
|
578
|
-
args.merge!({
|
|
579
|
-
request: {
|
|
580
|
-
path: ex.request.path.to_s,
|
|
581
|
-
method: ex.request.http_method.to_s.split("Net::HTTP::").last.upcase,
|
|
582
|
-
params: ex.request.options[:body],
|
|
583
|
-
headers: ex.request.options[:headers].map{|k,v| [k.to_s, k.to_s.downcase.strip == "authorization" ? "VALUE FILTERED" : v]}.to_h.to_s
|
|
584
|
-
}
|
|
585
|
-
})
|
|
586
|
-
args.merge!({
|
|
587
|
-
zuora_track_id: ex.request.options[:headers]["Zuora-Track-Id"]
|
|
588
|
-
}) if ex.request.options[:headers]["Zuora-Track-Id"].present?
|
|
493
|
+
rescue Errno::ECONNRESET => ex
|
|
494
|
+
if !(tries -= 1).zero? && ex.message.include?('SSL_connect')
|
|
495
|
+
retry
|
|
496
|
+
else
|
|
497
|
+
raise ex
|
|
589
498
|
end
|
|
590
499
|
rescue => ex
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
return
|
|
500
|
+
raise ex
|
|
501
|
+
else
|
|
502
|
+
return output_xml, input_xml, response
|
|
594
503
|
end
|
|
595
504
|
|
|
596
505
|
def raise_errors(type: :SOAP, body: nil, response: nil)
|
|
597
|
-
request_uri, request_path, match_string = "", "", ""
|
|
598
|
-
if response.class.to_s == "HTTP::Message"
|
|
599
|
-
request_uri = response.http_header.request_uri.to_s
|
|
600
|
-
request_path = response.http_header.request_uri.path
|
|
601
|
-
match_string = "#{response.http_header.request_method}::#{response.code}::#{request_uri}"
|
|
602
|
-
else
|
|
603
|
-
request = response.request
|
|
604
|
-
request_uri = response.request.uri
|
|
605
|
-
request_path = request.path.path
|
|
606
|
-
match_string = "#{request.http_method.to_s.split("Net::HTTP::").last.upcase}::#{response.code}::#{request_path}"
|
|
607
|
-
end
|
|
608
|
-
|
|
609
506
|
if [502,503].include?(response.code)
|
|
610
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIConnectionTimeout.new("Received #{response.code} from
|
|
507
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIConnectionTimeout.new("Received #{response.code} from downstream host", response)
|
|
611
508
|
end
|
|
612
509
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
when 504
|
|
616
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIReadTimeout.new("Received 504 from 'https://#{rest_domain(endpoint: request_uri)}'", response)
|
|
617
|
-
when 429
|
|
618
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new("The total number of concurrent requests has exceeded the limit allowed by the system. Please resubmit your request later.", response)
|
|
619
|
-
when 401
|
|
620
|
-
|
|
621
|
-
else
|
|
622
|
-
if body.class == Hash
|
|
623
|
-
case request_path
|
|
624
|
-
when /^\/v1\/connections$/
|
|
625
|
-
response_headers = response.headers.to_h
|
|
626
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new("Missing cookies for authentication call", response) if response_headers['set-cookie'].blank?
|
|
627
|
-
z_session_cookie = response_headers.fetch('set-cookie', []).select{|x| x.match(/^ZSession=.*/) }.first
|
|
628
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new("Missing ZSession cookie for authentication call", response) if z_session_cookie.blank?
|
|
629
|
-
end
|
|
630
|
-
end
|
|
510
|
+
if response.code == 504
|
|
511
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIReadTimeout.new("Received 504 from downstream host", response)
|
|
631
512
|
end
|
|
632
513
|
|
|
633
514
|
case type
|
|
634
515
|
when :SOAP
|
|
635
|
-
error
|
|
516
|
+
error = body.xpath('//fns:FaultCode', 'fns' =>'http://fault.api.zuora.com/').text
|
|
517
|
+
message = body.xpath('//fns:FaultMessage', 'fns' =>'http://fault.api.zuora.com/').text
|
|
518
|
+
|
|
519
|
+
if error.blank? || message.blank?
|
|
520
|
+
error = body.xpath('//faultcode').text
|
|
521
|
+
message = body.xpath('//faultstring').text
|
|
522
|
+
end
|
|
636
523
|
|
|
637
|
-
if
|
|
638
|
-
|
|
524
|
+
if error.blank? || message.blank?
|
|
525
|
+
error = body.xpath('//ns1:Code', 'ns1' =>'http://api.zuora.com/').text
|
|
526
|
+
message = body.xpath('//ns1:Message', 'ns1' =>'http://api.zuora.com/').text
|
|
639
527
|
end
|
|
640
528
|
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
error = 'FATAL_ERROR'
|
|
650
|
-
if message.present?
|
|
651
|
-
identifier, new_message = message.scan(/^([\w\d]{16})\: (.*)/).first
|
|
652
|
-
error, message = ['UNEXPECTED_ERROR', new_message] if new_message.present?
|
|
529
|
+
#Update/Create/Delete Calls with multiple requests and responses
|
|
530
|
+
if body.xpath('//ns1:result', 'ns1' =>'http://api.zuora.com/').size > 0 && body.xpath('//ns1:Errors', 'ns1' =>'http://api.zuora.com/').size > 0
|
|
531
|
+
error = []
|
|
532
|
+
success = []
|
|
533
|
+
body.xpath('//ns1:result', 'ns1' =>'http://api.zuora.com/').each_with_index do |call, object_index|
|
|
534
|
+
if call.xpath('./ns1:Success', 'ns1' =>'http://api.zuora.com/').text == 'false' && call.xpath('./ns1:Errors', 'ns1' =>'http://api.zuora.com/').size > 0
|
|
535
|
+
message = "#{call.xpath('./*/ns1:Code', 'ns1' =>'http://api.zuora.com/').text}::#{call.xpath('./*/ns1:Message', 'ns1' =>'http://api.zuora.com/').text}"
|
|
536
|
+
error.push(message)
|
|
653
537
|
else
|
|
654
|
-
|
|
538
|
+
success.push(call.xpath('./ns1:Id', 'ns1' =>'http://api.zuora.com/').text)
|
|
655
539
|
end
|
|
656
540
|
end
|
|
657
541
|
end
|
|
@@ -659,79 +543,50 @@ module ZuoraAPI
|
|
|
659
543
|
#By default response if not passed in for SOAP as all SOAP is 200
|
|
660
544
|
if error.present?
|
|
661
545
|
if error.class == String
|
|
662
|
-
|
|
546
|
+
case error
|
|
547
|
+
when "INVALID_SESSION"
|
|
548
|
+
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{error}::#{message}", response)
|
|
549
|
+
when "REQUEST_EXCEEDED_LIMIT"
|
|
550
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new("#{error}::#{message}", response)
|
|
551
|
+
when "LOCK_COMPETITION"
|
|
552
|
+
raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("#{error}::#{message}", response)
|
|
553
|
+
when "BATCH_FAIL_ERROR"
|
|
554
|
+
if message.include?("optimistic locking failed")
|
|
555
|
+
raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("#{error}::#{message}", response)
|
|
556
|
+
else
|
|
557
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{error}::#{message}", response)
|
|
558
|
+
end
|
|
559
|
+
when "TEMPORARY_ERROR"
|
|
560
|
+
raise ZuoraAPI::Exceptions::ZuoraAPITemporaryError.new("#{error}::#{message}", response)
|
|
561
|
+
when "INVALID_VALUE"
|
|
562
|
+
if message.include?("data integrity violation")
|
|
563
|
+
raise ZuoraAPI::Exceptions::ZuoraDataIntegrity.new("Data Integrity Violation", response)
|
|
564
|
+
else
|
|
565
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{error}::#{message}", response)
|
|
566
|
+
end
|
|
567
|
+
else
|
|
568
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{error}::#{message}", response) if error.present?
|
|
569
|
+
end
|
|
663
570
|
elsif error.class == Array
|
|
664
|
-
if error.
|
|
665
|
-
|
|
666
|
-
raise_errors_helper(error: err, message: msg, response: response, errors: error, success: success)
|
|
571
|
+
if error[0].include?("LOCK_COMPETITION") && error.count == 1
|
|
572
|
+
raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new(error.group_by {|v| v}.map {|k,v| "(#{v.size}x) - #{k == "::" ? 'UNKNOWN::No error provided' : k}"}.join(', '), response)
|
|
667
573
|
else
|
|
668
574
|
raise ZuoraAPI::Exceptions::ZuoraAPIError.new(error.group_by {|v| v}.map {|k,v| "(#{v.size}x) - #{k == "::" ? 'UNKNOWN::No error provided' : k}"}.join(', '), response, error, success)
|
|
669
575
|
end
|
|
670
576
|
end
|
|
671
577
|
end
|
|
672
|
-
|
|
673
|
-
self.errors_via_content_type(response: response, type: :xml)
|
|
674
578
|
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
when /^\/query\/jobs.*/ #DataQuery Paths
|
|
678
|
-
return if body.class != Hash
|
|
679
|
-
case match_string
|
|
680
|
-
when /^GET::200::\/query\/jobs\/([a-zA-Z0-9\-_]+)$/ #Get DQ job, Capture of the id is present if needed in future error responses.
|
|
681
|
-
if body.dig('data', "errorCode") == "LINK_10000005"
|
|
682
|
-
raise ZuoraAPI::Exceptions::ZuoraAPITemporaryError.new(body.dig('data', "errorMessage"), response)
|
|
683
|
-
elsif (body.dig('data', "errorMessage").present? || body.dig('data', "queryStatus") == "failed")
|
|
684
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIError.new(body.dig('data', "errorMessage"), response)
|
|
685
|
-
end
|
|
686
|
-
when /^GET::404::\/query\/jobs\/([a-zA-Z0-9\-_]+)$/ #Get DQ job not found, capture of the id is present if needed in future error responses.
|
|
687
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIError.new(body.dig('message'), response) if body.dig('message').present?
|
|
688
|
-
when /^POST::400::\/query\/jobs$/ #Create DQ job
|
|
689
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIError.new(body.dig('message'), response) if body.dig('message').present?
|
|
690
|
-
end
|
|
691
|
-
when /^\/api\/rest\/v1\/reports.*/ #Reporting Paths
|
|
692
|
-
reporting_message = response.parsed_response.dig("ZanResponse", "response", "message") || body.dig("message")
|
|
693
|
-
if reporting_message&.include?("com.zuora.rest.RestUsageException: The user does not have permissions for this API.")
|
|
694
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIError.new(reporting_message, response)
|
|
695
|
-
elsif reporting_message&.include?("500 Internal Server Error")
|
|
696
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new("Internal Server Error. The Reporting API is down. Contact Support.", response)
|
|
697
|
-
end
|
|
698
|
-
case match_string
|
|
699
|
-
when /^GET::400::\/api\/rest\/v1\/reports\/(reportlabels\/)?([a-zA-Z0-9\-_]+)\/report-details$/ # Get report, capture of the id is present if needed in future error responses.
|
|
700
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIError.new(reporting_message, response) if reporting_message.present?
|
|
701
|
-
end
|
|
702
|
-
when /\/objects\/batch\//
|
|
703
|
-
if body['code'].present? && /61$/.match(body['code'].to_s).present? # if last 2 digits of code are 61
|
|
704
|
-
raise ZuoraAPI::Exceptions::ZuoraAPITemporaryError.new(body['message'], nil, body['details'])
|
|
705
|
-
end
|
|
706
|
-
when /^\/api\/v1\/payment_plans.*/
|
|
707
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIError.new(body['error'], response) if body['error']
|
|
579
|
+
if response.code == 429
|
|
580
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new("The total number of concurrent requests has exceeded the limit allowed by the system. Please resubmit your request later.", response)
|
|
708
581
|
end
|
|
709
582
|
|
|
583
|
+
when :JSON
|
|
710
584
|
body = body.dig("results").present? ? body["results"] : body if body.class == Hash
|
|
711
585
|
if body.class == Hash && (!body["success"] || !body["Success"] || response.code != 200)
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
message_keys.each do |msg_key|
|
|
717
|
-
messages_array = body.fetch(rsn_key, []).map {|error| error[msg_key]}.compact
|
|
718
|
-
break if messages_array.present?
|
|
719
|
-
end
|
|
720
|
-
codes_array = body.fetch(rsn_key, []).map {|error| error['code']}.compact
|
|
721
|
-
break if messages_array.present? && codes_array.present?
|
|
722
|
-
end
|
|
723
|
-
if body.dig('error').class == Hash
|
|
724
|
-
messages_array = messages_array.push(body.dig("error", 'message')).compact
|
|
725
|
-
codes_array = codes_array.push(body.dig("error", 'code')).compact
|
|
726
|
-
end
|
|
727
|
-
|
|
728
|
-
if body['message'] == 'request exceeded limit'
|
|
729
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new("The total number of concurrent requests has exceeded the limit allowed by the system. Please resubmit your request later.", response)
|
|
730
|
-
end
|
|
731
|
-
|
|
732
|
-
if (body.dig('message') || '').downcase.include?('unexpected error') && response.code != 500
|
|
733
|
-
raise ZuoraAPI::Exceptions::ZuoraUnexpectedError.new(body['message'], response)
|
|
734
|
-
end
|
|
586
|
+
messages_array = body.fetch("reasons", []).map {|error| error['message']}.compact
|
|
587
|
+
messages_array = messages_array.push(body.dig("error", 'message')).compact if body.dig('error').class == Hash
|
|
588
|
+
codes_array = body.fetch("reasons", []).map {|error| error['code']}.compact
|
|
589
|
+
codes_array = codes_array.push(body.dig("error", 'code')).compact if body.dig('error').class == Hash
|
|
735
590
|
|
|
736
591
|
if body['message'] == "No bearer token" && response.code == 400
|
|
737
592
|
raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Authentication type is not supported by this Login", response)
|
|
@@ -746,29 +601,16 @@ module ZuoraAPI
|
|
|
746
601
|
end
|
|
747
602
|
|
|
748
603
|
#Oauth Tokens - User deactivated
|
|
749
|
-
if body['
|
|
750
|
-
|
|
751
|
-
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("Forbidden", response)
|
|
752
|
-
elsif body['status'] == 400 && response.code == 400 && body['message'].include?("Invalid client id")
|
|
753
|
-
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("Invalid Oauth Client Id", response)
|
|
754
|
-
end
|
|
604
|
+
if body['reason'] == 'Forbidden' && body['status'] == 403 && response.code == 403
|
|
605
|
+
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("Forbidden", response)
|
|
755
606
|
end
|
|
756
607
|
|
|
757
608
|
if body['error'] == 'Unauthorized' && body['status'] == 401
|
|
758
|
-
|
|
759
|
-
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(body['message'], response)
|
|
760
|
-
else
|
|
761
|
-
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{messages_array.join(', ')}", response)
|
|
762
|
-
end
|
|
609
|
+
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{messages_array.join(', ')}", response)
|
|
763
610
|
end
|
|
764
611
|
#Authentication failed
|
|
765
612
|
if (codes_array.map{|code| code.to_s.slice(6,7).to_i}.include?(11) || response.code == 401) && !codes_array.include?(422)
|
|
766
|
-
|
|
767
|
-
if new_message.present?
|
|
768
|
-
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(new_message, response)
|
|
769
|
-
else
|
|
770
|
-
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(body['message'], response)
|
|
771
|
-
end
|
|
613
|
+
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{messages_array.join(', ')}", response)
|
|
772
614
|
end
|
|
773
615
|
|
|
774
616
|
#Zuora REST Create Amendment error #Authentication failed
|
|
@@ -776,30 +618,16 @@ module ZuoraAPI
|
|
|
776
618
|
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{body['faultstring']}", response)
|
|
777
619
|
end
|
|
778
620
|
|
|
779
|
-
#Locking contention
|
|
780
|
-
if codes_array.map{|code| code.to_s.slice(6,7).to_i}.include?(50)
|
|
781
|
-
raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("#{messages_array.join(', ')}", response)
|
|
782
|
-
end
|
|
783
|
-
#Internal Server Error
|
|
784
|
-
if codes_array.map{|code| code.to_s.slice(6,7).to_i}.include?(60)
|
|
785
|
-
if messages_array.uniq.size == 1
|
|
786
|
-
if messages_array.first.match(/^Transaction declined.*|^There is an invoice pending tax.*|^The Zuora GetTax call to Avalara.*|^The tax calculation call to Zuora Connect returned the following error: Status Code: 4.*/)
|
|
787
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIError.new(messages_array.first, response)
|
|
788
|
-
end
|
|
789
|
-
end
|
|
790
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new("#{messages_array.join(', ')}", response)
|
|
791
|
-
end
|
|
792
|
-
|
|
793
|
-
#Retryiable Service Error
|
|
794
|
-
if codes_array.map{|code| code.to_s.slice(6,7).to_i}.include?(61)
|
|
795
|
-
raise ZuoraAPI::Exceptions::ZuoraAPITemporaryError.new("#{messages_array.join(', ')}", response)
|
|
796
|
-
end
|
|
797
|
-
|
|
798
621
|
#Request exceeded limit
|
|
799
622
|
if codes_array.map{|code| code.to_s.slice(6,7).to_i}.include?(70)
|
|
800
623
|
raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new("#{messages_array.join(', ')}", response)
|
|
801
624
|
end
|
|
802
625
|
|
|
626
|
+
#Locking contention
|
|
627
|
+
if codes_array.map{|code| code.to_s.slice(6,7).to_i}.include?(50)
|
|
628
|
+
raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("#{messages_array.join(', ')}", response)
|
|
629
|
+
end
|
|
630
|
+
|
|
803
631
|
#All Errors catch
|
|
804
632
|
if codes_array.size > 0
|
|
805
633
|
raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{messages_array.join(', ')}", response)
|
|
@@ -807,20 +635,26 @@ module ZuoraAPI
|
|
|
807
635
|
|
|
808
636
|
#Zuora REST Query Errors
|
|
809
637
|
if body["faultcode"].present?
|
|
810
|
-
|
|
638
|
+
case body["faultcode"]
|
|
639
|
+
when "fns:MALFORMED_QUERY"
|
|
640
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{body["faultcode"]}::#{body["faultstring"]}", response)
|
|
641
|
+
when "fns:REQUEST_EXCEEDED_LIMIT"
|
|
642
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new("#{body["faultcode"]}::#{body["faultstring"]}", response)
|
|
643
|
+
when "fns:LOCK_COMPETITION"
|
|
644
|
+
raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("#{body["faultcode"]}::#{body["faultstring"]}", response)
|
|
645
|
+
when "INVALID_SESSION"
|
|
646
|
+
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("#{body["faultcode"]}::#{body["faultstring"]}", response)
|
|
647
|
+
else
|
|
648
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{body["faultcode"]}::#{body["faultstring"]}", response)
|
|
649
|
+
end
|
|
811
650
|
end
|
|
812
651
|
|
|
813
652
|
if body["Errors"].present? || body["errors"].present?
|
|
814
|
-
|
|
815
|
-
body
|
|
816
|
-
body
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
if codes.size == 1
|
|
820
|
-
raise_errors_helper(error: codes.first, message: messages.first, response: response, errors: messages)
|
|
821
|
-
else
|
|
822
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{messages.join(", ")}", response, messages)
|
|
823
|
-
end
|
|
653
|
+
errors = []
|
|
654
|
+
(body["Errors"] || []).select { |obj| errors.push(obj["Message"]) }.compact
|
|
655
|
+
(body["errors"] || []).select { |obj| errors.push(obj["Message"]) }.compact
|
|
656
|
+
if errors.size > 0
|
|
657
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{errors.join(", ")}", response, errors)
|
|
824
658
|
end
|
|
825
659
|
end
|
|
826
660
|
end
|
|
@@ -838,7 +672,7 @@ module ZuoraAPI
|
|
|
838
672
|
raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new("Retry Lock Competition", response)
|
|
839
673
|
elsif error_messages.first.include?("data integrity violation")
|
|
840
674
|
raise ZuoraAPI::Exceptions::ZuoraDataIntegrity.new("Data Integrity Violation", response)
|
|
841
|
-
end
|
|
675
|
+
end
|
|
842
676
|
end
|
|
843
677
|
end
|
|
844
678
|
|
|
@@ -847,140 +681,15 @@ module ZuoraAPI
|
|
|
847
681
|
end
|
|
848
682
|
end
|
|
849
683
|
|
|
850
|
-
if body.class == Hash && body['message'].present?
|
|
851
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new(body['message'], response) if response.code == 500
|
|
852
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIError.new(body['message'], response) if ![200,201].include?(response.code)
|
|
853
|
-
end
|
|
854
|
-
|
|
855
|
-
self.errors_via_content_type(response: response, type: :json)
|
|
856
|
-
|
|
857
684
|
#All other errors
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
def errors_via_content_type(response: nil, type: :xml)
|
|
863
|
-
response_content_types = response.headers.transform_keys(&:downcase).fetch('content-type', []).first || ""
|
|
864
|
-
|
|
865
|
-
if response_content_types.include?('application/json') && type != :json
|
|
866
|
-
output_json = JSON.parse(response.body)
|
|
867
|
-
self.raise_errors(type: :JSON, body: output_json, response: response)
|
|
868
|
-
|
|
869
|
-
elsif (response_content_types.include?('application/xml') || response_content_types.include?('text/xml') || response_content_types.include?('application/soap+xml')) and type != :xml
|
|
870
|
-
output_xml = Nokogiri::XML(response.body)
|
|
871
|
-
self.raise_errors(type: :SOAP, body: output_xml, response: response)
|
|
872
|
-
|
|
873
|
-
elsif response_content_types.include?('text/html')
|
|
874
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new("Akamai Error", response) if response.headers.fetch('server', '') == 'AkamaiGHost'
|
|
875
|
-
|
|
876
|
-
parse_body = Nokogiri::HTML(response.body)
|
|
877
|
-
error_title = parse_body.xpath('//h2').text
|
|
878
|
-
error_title = parse_body.xpath('//h1').text if error_title.blank?
|
|
879
|
-
error_message = parse_body.xpath('//p').text
|
|
880
|
-
|
|
881
|
-
error_message = error_title if error_message.blank?
|
|
882
|
-
|
|
883
|
-
if error_title.present?
|
|
884
|
-
case error_title
|
|
885
|
-
when /Service Unavailable/
|
|
886
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIConnectionTimeout.new(error_message, response)
|
|
887
|
-
when /Client sent a bad request./, /Bad Request/, /403 Forbidden/
|
|
888
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new(error_message, response)
|
|
889
|
-
when /414 Request-URI Too Large/
|
|
890
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Request URL is too long", response)
|
|
891
|
-
else
|
|
892
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new(error_message, response)
|
|
893
|
-
end
|
|
894
|
-
end
|
|
895
|
-
|
|
896
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new("Http response body is missing", response) if response.body.blank?
|
|
897
|
-
end
|
|
898
|
-
|
|
899
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new(response.body, response) if response.code == 500
|
|
900
|
-
end
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
def get_soap_error_and_message(body)
|
|
904
|
-
error = body.xpath('//fns:FaultCode', 'fns' =>'http://fault.api.zuora.com/').text
|
|
905
|
-
message = body.xpath('//fns:FaultMessage', 'fns' =>'http://fault.api.zuora.com/').text
|
|
906
|
-
|
|
907
|
-
if error.blank? || message.blank?
|
|
908
|
-
error = body.xpath('//faultcode').text
|
|
909
|
-
message = body.xpath('//faultstring').text
|
|
910
|
-
end
|
|
911
|
-
|
|
912
|
-
if error.blank? || message.blank?
|
|
913
|
-
error = body.xpath('//ns1:Code', 'ns1' =>'http://api.zuora.com/').text
|
|
914
|
-
message = body.xpath('//ns1:Message', 'ns1' =>'http://api.zuora.com/').text
|
|
915
|
-
end
|
|
916
|
-
|
|
917
|
-
if error.blank? || message.blank?
|
|
918
|
-
error = body.xpath('//soapenv:Value', 'soapenv'=>'http://www.w3.org/2003/05/soap-envelope').text
|
|
919
|
-
message = body.xpath('//soapenv:Text', 'soapenv'=>'http://www.w3.org/2003/05/soap-envelope').text
|
|
920
|
-
end
|
|
921
|
-
|
|
922
|
-
#Update/Create/Delete Calls with multiple requests and responses
|
|
923
|
-
if body.xpath('//ns1:result', 'ns1' =>'http://api.zuora.com/').size > 0 && body.xpath('//ns1:Errors', 'ns1' =>'http://api.zuora.com/').size > 0
|
|
924
|
-
error = []
|
|
925
|
-
success = []
|
|
926
|
-
body.xpath('//ns1:result', 'ns1' =>'http://api.zuora.com/').each_with_index do |call, object_index|
|
|
927
|
-
if call.xpath('./ns1:Success', 'ns1' =>'http://api.zuora.com/').text == 'false' && call.xpath('./ns1:Errors', 'ns1' =>'http://api.zuora.com/').size > 0
|
|
928
|
-
message = "#{call.xpath('./*/ns1:Code', 'ns1' =>'http://api.zuora.com/').text}::#{call.xpath('./*/ns1:Message', 'ns1' =>'http://api.zuora.com/').text}"
|
|
929
|
-
error.push(message)
|
|
685
|
+
if ![200,201].include?(response.code)
|
|
686
|
+
if response.code == 429
|
|
687
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new("The total number of concurrent requests has exceeded the limit allowed by the system. Please resubmit your request later.", response)
|
|
930
688
|
else
|
|
931
|
-
|
|
689
|
+
raise ZuoraAPI::Exceptions::ZuoraAPIError.new("#{response.message}", response)
|
|
932
690
|
end
|
|
933
691
|
end
|
|
934
692
|
end
|
|
935
|
-
return error, success, message
|
|
936
|
-
end
|
|
937
|
-
|
|
938
|
-
def raise_errors_helper(error: nil, message: nil, response: nil, errors: [], success: [])
|
|
939
|
-
case error
|
|
940
|
-
when /.*INVALID_SESSION/
|
|
941
|
-
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(message, response, errors, success)
|
|
942
|
-
when /.*REQUEST_EXCEEDED_LIMIT/
|
|
943
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIRequestLimit.new(message, response, errors, success)
|
|
944
|
-
when /.*LOCK_COMPETITION/
|
|
945
|
-
raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new(message, response, errors, success)
|
|
946
|
-
when /.*BATCH_FAIL_ERROR/
|
|
947
|
-
if message.include?("optimistic locking failed") || message.include?("Operation failed due to a lock competition, please retry later.")
|
|
948
|
-
raise ZuoraAPI::Exceptions::ZuoraAPILockCompetition.new(message, response, errors, success)
|
|
949
|
-
elsif message.include?("org.hibernate.exception.ConstraintViolationException")
|
|
950
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new(message, response, errors, success)
|
|
951
|
-
end
|
|
952
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIError.new(message, response, errors, success)
|
|
953
|
-
when /.*TEMPORARY_ERROR/, /.*TRANSACTION_TIMEOUT/
|
|
954
|
-
raise ZuoraAPI::Exceptions::ZuoraAPITemporaryError.new(message, response, errors, success)
|
|
955
|
-
when /.*INVALID_VALUE/
|
|
956
|
-
if message.include?("data integrity violation")
|
|
957
|
-
raise ZuoraAPI::Exceptions::ZuoraDataIntegrity.new("Data Integrity Violation", response, errors), success
|
|
958
|
-
end
|
|
959
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIError.new(message, response, errors, success)
|
|
960
|
-
when /.*UNKNOWN_ERROR/
|
|
961
|
-
if /payment\/refund|Credit Balance Adjustment|Payment Gateway|ARSettlement permission/.match(message).nil?
|
|
962
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIUnkownError.new(message, response, errors, success)
|
|
963
|
-
end
|
|
964
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIError.new(message, response, errors, success)
|
|
965
|
-
when /^INVALID_VERSION/, /invalid/, /^DUPLICATE_VALUE/, /^REQUEST_REJECTED/, /INVALID_ID/, /MAX_RECORDS_EXCEEDED/, /INVALID_FIELD/, /MALFORMED_QUERY/, /NO_PERMISSION/, /PDF_QUERY_ERROR/, /MISSING_REQUIRED_VALUE/, /INVALID_TYPE/, /TRANSACTION_FAILED/, /API_DISABLED/, /CANNOT_DELETE/, /ACCOUNTING_PERIOD_CLOSED/
|
|
966
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIError.new(message, response, errors, success)
|
|
967
|
-
when /.*UNEXPECTED_ERROR/
|
|
968
|
-
raise ZuoraAPI::Exceptions::ZuoraUnexpectedError.new(message, response, errors, success)
|
|
969
|
-
when /.*soapenv:Server.*/
|
|
970
|
-
if /^Invalid value.*for type.*|^Id is invalid|^date string can not be less than 19 charactors$/.match(message).present?
|
|
971
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIError.new(message, response, errors, success)
|
|
972
|
-
elsif /^unknown$|^Invalid white space character \(.*\) in text to output$|^Invalid null character in text to output$/.match(message).present?
|
|
973
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIUnkownError.new(message, response, errors, success)
|
|
974
|
-
end
|
|
975
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new(message, response, errors, success)
|
|
976
|
-
when /soapenv:Receiver/
|
|
977
|
-
if /^com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character.*$/.match(message).present?
|
|
978
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIError.new(message, response, errors, success)
|
|
979
|
-
end
|
|
980
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new(message, response, errors, success)
|
|
981
|
-
else
|
|
982
|
-
raise ZuoraAPI::Exceptions::ZuoraAPIInternalServerError.new("Z:#{error}::#{message}", response, errors, success)
|
|
983
|
-
end
|
|
984
693
|
end
|
|
985
694
|
|
|
986
695
|
def aqua_query(queryName: '', query: '', version: '1.2', jobName: 'Aqua',partner: '', project: '')
|
|
@@ -1027,7 +736,7 @@ module ZuoraAPI
|
|
|
1027
736
|
base = self.url.include?(".com") ? self.url.split(".com")[0].concat(".com") : self.url.split(".eu")[0].concat(".eu")
|
|
1028
737
|
url = object ? "#{base}/apps/api/describe/#{object}" : "#{base}/apps/api/describe/"
|
|
1029
738
|
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"}
|
|
1030
|
-
response = HTTParty.get(url, headers: {"Authorization" => self.get_session(prefix: true, auth_type: :basic)}.merge(headers), :timeout =>
|
|
739
|
+
response = HTTParty.get(url, headers: {"Authorization" => self.get_session(prefix: true, auth_type: :basic)}.merge(headers), :timeout => 120)
|
|
1031
740
|
|
|
1032
741
|
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error.present? ? self.current_error : 'Describe call 401', response) if response.code == 401
|
|
1033
742
|
|
|
@@ -1060,31 +769,27 @@ module ZuoraAPI
|
|
|
1060
769
|
end
|
|
1061
770
|
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
|
|
1062
771
|
end
|
|
1063
|
-
|
|
1064
|
-
return des_hash
|
|
1065
772
|
rescue *(CONNECTION_EXCEPTIONS + CONNECTION_READ_EXCEPTIONS) => ex
|
|
1066
|
-
if !tries.zero?
|
|
1067
|
-
|
|
1068
|
-
self.log(location: "Describe", exception: ex, message: "Timed out will retry after #{self.timeout_sleep} seconds", level: :debug)
|
|
773
|
+
if !(tries -= 1).zero?
|
|
774
|
+
Rails.logger.info("Describe - #{ex.class} Timed out will retry after 5 seconds")
|
|
1069
775
|
sleep(self.timeout_sleep)
|
|
1070
776
|
retry
|
|
777
|
+
else
|
|
778
|
+
raise ex
|
|
1071
779
|
end
|
|
1072
|
-
|
|
1073
|
-
self.log(location: "Describe", exception: ex, message: "Timed out", level: :error) if log_errors
|
|
1074
|
-
raise ex
|
|
1075
|
-
|
|
1076
780
|
rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
|
|
1077
|
-
if !tries.zero? && self.status == 'Active'
|
|
1078
|
-
tries -= 1
|
|
781
|
+
if !(tries -= 1).zero? && self.status == 'Active'
|
|
1079
782
|
Rails.logger.debug("Describe session expired. Starting new session.")
|
|
1080
783
|
self.new_session
|
|
1081
784
|
retry
|
|
785
|
+
else
|
|
786
|
+
Rails.logger.error("Describe session expired. Starting new session.") if log_errors
|
|
787
|
+
raise ex
|
|
1082
788
|
end
|
|
1083
|
-
|
|
1084
|
-
Rails.logger.error("Describe session expired. Starting new session.") if log_errors
|
|
1085
|
-
raise ex
|
|
1086
789
|
rescue => ex
|
|
1087
790
|
raise ex
|
|
791
|
+
else
|
|
792
|
+
return des_hash
|
|
1088
793
|
end
|
|
1089
794
|
|
|
1090
795
|
def rest_call(
|
|
@@ -1097,124 +802,93 @@ module ZuoraAPI
|
|
|
1097
802
|
z_session: true,
|
|
1098
803
|
session_type: :basic,
|
|
1099
804
|
timeout_retry: false,
|
|
1100
|
-
timeout:
|
|
1101
|
-
timeout_sleep_interval: self.timeout_sleep,
|
|
805
|
+
timeout: 120,
|
|
1102
806
|
multipart: false,
|
|
1103
|
-
|
|
1104
|
-
output_exception_messages: true,
|
|
1105
|
-
zuora_track_id: nil,
|
|
1106
|
-
**keyword_args,
|
|
1107
|
-
&block
|
|
807
|
+
**keyword_args
|
|
1108
808
|
)
|
|
1109
809
|
tries ||= 2
|
|
1110
810
|
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
if z_session
|
|
1115
|
-
authentication_headers = {"Authorization" => self.get_session(prefix: true, auth_type: session_type, zuora_track_id: zuora_track_id) }
|
|
1116
|
-
if self.entity_id.present?
|
|
1117
|
-
authentication_headers["Zuora-Entity-Ids"] = self.entity_id if headers.dig("Zuora-Entity-Ids").nil?
|
|
1118
|
-
authentication_headers.delete_if { |key, value| ["entityId", "entityName"].include?(key.to_s) }
|
|
1119
|
-
end
|
|
811
|
+
if self.entity_id.present?
|
|
812
|
+
headers["Zuora-Entity-Ids"] = self.entity_id if headers.dig("Zuora-Entity-Ids").nil?
|
|
813
|
+
headers.delete_if { |key, value| ["entityId", "entityName"].include?(key.to_s) }
|
|
1120
814
|
end
|
|
1121
|
-
headers['Zuora-Track-Id'] = zuora_track_id if zuora_track_id.present?
|
|
1122
815
|
|
|
816
|
+
raise "Method not supported, supported methods include: :get, :post, :put, :delete, :patch, :head, :options" if ![:get, :post, :put, :delete, :patch, :head, :options].include?(method)
|
|
817
|
+
|
|
818
|
+
authentication_headers = z_session ? {"Authorization" => self.get_session(prefix: true, auth_type: session_type) } : {}
|
|
1123
819
|
modified_headers = {'Content-Type' => "application/json; charset=utf-8"}.merge(authentication_headers).merge(headers)
|
|
1124
820
|
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
stream_body: stream_body
|
|
1134
|
-
)
|
|
1135
|
-
|
|
1136
|
-
response = request.perform(&block)
|
|
1137
|
-
|
|
1138
|
-
Rails.logger.debug("Response Code: #{response.code}") if debug
|
|
1139
|
-
begin
|
|
1140
|
-
output_json = JSON.parse(response.body)
|
|
1141
|
-
rescue JSON::ParserError => ex
|
|
1142
|
-
output_json = {}
|
|
1143
|
-
end
|
|
1144
|
-
Rails.logger.debug("Response JSON: #{output_json}") if debug && output_json.present?
|
|
821
|
+
response = HTTParty::Request.new(
|
|
822
|
+
"Net::HTTP::#{method.to_s.capitalize}".constantize,
|
|
823
|
+
url,
|
|
824
|
+
body: body,
|
|
825
|
+
headers: modified_headers,
|
|
826
|
+
timeout: timeout,
|
|
827
|
+
multipart: multipart,
|
|
828
|
+
).perform
|
|
1145
829
|
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
830
|
+
Rails.logger.debug("Response Code: #{response.code}") if debug
|
|
831
|
+
begin
|
|
832
|
+
output_json = JSON.parse(response.body)
|
|
833
|
+
rescue JSON::ParserError => ex
|
|
834
|
+
output_json = {}
|
|
1150
835
|
end
|
|
836
|
+
Rails.logger.debug("Response JSON: #{output_json}") if debug && output_json.present?
|
|
1151
837
|
|
|
1152
|
-
|
|
838
|
+
raise_errors(type: :JSON, body: output_json, response: response)
|
|
1153
839
|
rescue ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError => ex
|
|
1154
840
|
if self.class.to_s == 'ZuoraAPI::Oauth' && ex.message.include?("Authentication type is not supported by this Login")
|
|
1155
|
-
session_type
|
|
1156
|
-
|
|
841
|
+
self.rest_call(method: method.to_sym, url: url, body: body, debug: debug, errors: errors, z_session: z_session, session_type: :bearer, timeout_retry: timeout_retry, timeout: timeout)
|
|
842
|
+
else
|
|
843
|
+
Rails.logger.debug("Rest Call - Session Bad Auth type")
|
|
844
|
+
raise ex
|
|
1157
845
|
end
|
|
1158
|
-
Rails.logger.debug("Rest Call - Session Bad Auth type")
|
|
1159
|
-
raise ex
|
|
1160
|
-
|
|
1161
846
|
rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
|
|
1162
|
-
if !tries.zero? && z_session
|
|
1163
|
-
tries -= 1
|
|
847
|
+
if !(tries -= 1).zero? && z_session
|
|
1164
848
|
Rails.logger.debug("Rest Call - Session Invalid #{session_type}")
|
|
1165
|
-
|
|
1166
|
-
begin
|
|
1167
|
-
self.new_session(auth_type: session_type)
|
|
1168
|
-
rescue *ZUORA_API_ERRORS => ex
|
|
1169
|
-
return [output_json, ex.response]
|
|
1170
|
-
end
|
|
1171
|
-
|
|
849
|
+
self.new_session(auth_type: session_type)
|
|
1172
850
|
retry
|
|
851
|
+
else
|
|
852
|
+
if errors.include?(ex.class)
|
|
853
|
+
raise ex
|
|
854
|
+
else
|
|
855
|
+
return [output_json, response]
|
|
856
|
+
end
|
|
1173
857
|
end
|
|
1174
|
-
|
|
1175
|
-
raise ex if errors.include?(ex.class)
|
|
1176
|
-
return [output_json, response]
|
|
1177
|
-
|
|
1178
858
|
rescue *ZUORA_API_ERRORS => ex
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
859
|
+
if errors.include?(ex.class)
|
|
860
|
+
raise ex
|
|
861
|
+
else
|
|
862
|
+
return [output_json, response]
|
|
863
|
+
end
|
|
1184
864
|
rescue ZuoraAPI::Exceptions::BadEntityError => ex
|
|
1185
865
|
raise ex
|
|
1186
866
|
rescue *CONNECTION_EXCEPTIONS => ex
|
|
1187
|
-
if !tries.zero?
|
|
1188
|
-
|
|
1189
|
-
self.
|
|
1190
|
-
sleep(timeout_sleep_interval)
|
|
867
|
+
if !(tries -= 1).zero?
|
|
868
|
+
Rails.logger.info("Rest Call - #{ex.class} Timed out will retry after 5 seconds")
|
|
869
|
+
sleep(self.timeout_sleep)
|
|
1191
870
|
retry
|
|
871
|
+
else
|
|
872
|
+
raise ex
|
|
1192
873
|
end
|
|
1193
|
-
|
|
1194
|
-
self.log(location: "Rest Call", exception: ex, message: "Timed out", level: :error) if output_exception_messages
|
|
1195
|
-
raise ex
|
|
1196
|
-
|
|
1197
874
|
rescue *CONNECTION_READ_EXCEPTIONS => ex
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
875
|
+
if !(tries -= 1).zero? && timeout_retry
|
|
876
|
+
Rails.logger.info("Rest Call - #{ex.class} Timed out will retry after 5 seconds")
|
|
877
|
+
sleep(self.timeout_sleep)
|
|
878
|
+
retry
|
|
879
|
+
else
|
|
880
|
+
raise ex
|
|
881
|
+
end
|
|
882
|
+
rescue Errno::ECONNRESET => ex
|
|
883
|
+
if !(tries -= 1).zero? && ex.message.include?('SSL_connect')
|
|
884
|
+
retry
|
|
885
|
+
else
|
|
886
|
+
raise ex
|
|
1208
887
|
end
|
|
1209
|
-
|
|
1210
|
-
self.log(location: "Rest Call", exception: ex, message: "Timed out", level: :error) if output_exception_messages
|
|
1211
|
-
ex = ZuoraAPI::Exceptions::ZuoraAPIReadTimeout.new("Received read timeout from 'https://#{rest_domain(endpoint: url)}'", nil, request) if ex.instance_of?(Net::ReadTimeout)
|
|
1212
|
-
raise ex
|
|
1213
|
-
|
|
1214
888
|
rescue => ex
|
|
1215
889
|
raise ex
|
|
1216
|
-
|
|
1217
|
-
|
|
890
|
+
else
|
|
891
|
+
return [output_json, response]
|
|
1218
892
|
end
|
|
1219
893
|
|
|
1220
894
|
def update_create_tenant
|
|
@@ -1236,9 +910,8 @@ module ZuoraAPI
|
|
|
1236
910
|
while !response["nextPage"].blank?
|
|
1237
911
|
url = self.rest_endpoint(response["nextPage"].split('/v1/').last)
|
|
1238
912
|
Rails.logger.debug("Fetch Catalog URL #{url}")
|
|
1239
|
-
output_json, response = self.rest_call(debug
|
|
1240
|
-
|
|
1241
|
-
if !/(true|t|yes|y|1)$/.match(output_json['success'].to_s) || output_json['success'].class != TrueClass
|
|
913
|
+
output_json, response = self.rest_call(:debug => false, :url => url, :errors => [ZuoraAPI::Exceptions::ZuoraAPISessionError], :timeout_retry => true )
|
|
914
|
+
if !output_json['success'] =~ (/(true|t|yes|y|1)$/i) || output_json['success'].class != TrueClass
|
|
1242
915
|
raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Error Getting Catalog: #{output_json}", response)
|
|
1243
916
|
end
|
|
1244
917
|
output_json["products"].each do |product|
|
|
@@ -1264,11 +937,9 @@ module ZuoraAPI
|
|
|
1264
937
|
return products, catalog_map
|
|
1265
938
|
end
|
|
1266
939
|
|
|
1267
|
-
def get_file(url: nil, headers: {}, z_session: true, tempfile: true, output_file_name: nil,
|
|
940
|
+
def get_file(url: nil, headers: {}, z_session: true, tempfile: true, output_file_name: nil, add_timestamp: true, file_path: defined?(Rails.root.join('tmp')) ? Rails.root.join('tmp') : Pathname.new(Dir.pwd), timeout_retries: 3, timeout: 120, session_type: :basic, **execute_params)
|
|
1268
941
|
raise "file_path must be of class Pathname" if file_path.class != Pathname
|
|
1269
942
|
|
|
1270
|
-
retry_count ||= timeout_retries
|
|
1271
|
-
|
|
1272
943
|
#Make sure directory exists
|
|
1273
944
|
require 'fileutils'
|
|
1274
945
|
FileUtils.mkdir_p(file_path) unless File.exists?(file_path)
|
|
@@ -1283,9 +954,8 @@ module ZuoraAPI
|
|
|
1283
954
|
headers = headers.merge({"Zuora-Entity-Ids" => self.entity_id}) if !self.entity_id.blank?
|
|
1284
955
|
end
|
|
1285
956
|
|
|
1286
|
-
headers['Zuora-Track-Id'] = zuora_track_id if zuora_track_id.present?
|
|
1287
|
-
|
|
1288
957
|
response_save = nil
|
|
958
|
+
retry_count ||= timeout_retries
|
|
1289
959
|
http.request_get(uri.request_uri, headers) do |response|
|
|
1290
960
|
response_save = response
|
|
1291
961
|
status_code = response.code if response
|
|
@@ -1369,42 +1039,36 @@ module ZuoraAPI
|
|
|
1369
1039
|
return file_handle
|
|
1370
1040
|
when Net::HTTPUnauthorized
|
|
1371
1041
|
if z_session
|
|
1372
|
-
|
|
1042
|
+
if !(retry_count -= 1).zero?
|
|
1373
1043
|
self.new_session
|
|
1374
|
-
raise
|
|
1044
|
+
raise response.class
|
|
1045
|
+
else
|
|
1046
|
+
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error)
|
|
1375
1047
|
end
|
|
1376
|
-
raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error)
|
|
1377
|
-
end
|
|
1378
|
-
raise
|
|
1379
|
-
when Net::HTTPNotFound
|
|
1380
|
-
if url.include?(self.fileURL)
|
|
1381
|
-
raise ZuoraAPI::Exceptions::FileDownloadError.new(
|
|
1382
|
-
"The current tenant does not have a file with id '#{url.split('/').last}'"
|
|
1383
|
-
)
|
|
1384
1048
|
else
|
|
1385
|
-
raise
|
|
1049
|
+
raise
|
|
1386
1050
|
end
|
|
1387
1051
|
else
|
|
1388
|
-
raise
|
|
1052
|
+
raise StandardError.new("File Download Failed #{response.class}")
|
|
1389
1053
|
end
|
|
1390
1054
|
end
|
|
1391
|
-
|
|
1392
|
-
rescue => ex
|
|
1055
|
+
|
|
1056
|
+
rescue => ex
|
|
1393
1057
|
sleep(5)
|
|
1394
1058
|
if (retry_count -= 1) >= 0
|
|
1395
1059
|
retry
|
|
1060
|
+
else
|
|
1061
|
+
Rails.logger.error("File Download Failed")
|
|
1062
|
+
raise
|
|
1396
1063
|
end
|
|
1397
|
-
Rails.logger.error("File Download Failed")
|
|
1398
|
-
raise
|
|
1399
1064
|
end
|
|
1400
1065
|
|
|
1401
|
-
def getDataSourceExport(query, extract: true, encrypted: false, zip: true
|
|
1402
|
-
tries ||= 3
|
|
1066
|
+
def getDataSourceExport(query, extract: true, encrypted: false, zip: true)
|
|
1403
1067
|
request = Nokogiri::XML::Builder.new do |xml|
|
|
1404
1068
|
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
|
|
1405
1069
|
xml['SOAP-ENV'].Header do
|
|
1406
1070
|
xml['ns1'].SessionHeader do
|
|
1407
|
-
xml['ns1'].session self.get_session(prefix: false, auth_type: :basic
|
|
1071
|
+
xml['ns1'].session self.get_session(prefix: false, auth_type: :basic)
|
|
1408
1072
|
end
|
|
1409
1073
|
end
|
|
1410
1074
|
xml['SOAP-ENV'].Body do
|
|
@@ -1421,20 +1085,17 @@ module ZuoraAPI
|
|
|
1421
1085
|
end
|
|
1422
1086
|
end
|
|
1423
1087
|
|
|
1424
|
-
response_query = HTTParty.post(self.url, body: request.to_xml(:save_with => XML_SAVE_OPTIONS).strip, headers: {'Content-Type' => "application/json; charset=utf-8"
|
|
1088
|
+
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)
|
|
1425
1089
|
|
|
1426
1090
|
output_xml = Nokogiri::XML(response_query.body)
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
# raise "Export Creation Unsuccessful : #{response_query.code}: #{response_query.parsed_response}" if output_xml.xpath('//ns1:Success', 'ns1' =>'http://api.zuora.com/').text != "true"
|
|
1430
|
-
|
|
1091
|
+
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"
|
|
1431
1092
|
id = output_xml.xpath('//ns1:Id', 'ns1' =>'http://api.zuora.com/').text
|
|
1432
1093
|
|
|
1433
1094
|
confirmRequest = Nokogiri::XML::Builder.new do |xml|
|
|
1434
1095
|
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
|
|
1435
1096
|
xml['SOAP-ENV'].Header do
|
|
1436
1097
|
xml['ns1'].SessionHeader do
|
|
1437
|
-
xml['ns1'].session self.get_session(prefix: false, auth_type: :basic
|
|
1098
|
+
xml['ns1'].session self.get_session(prefix: false, auth_type: :basic)
|
|
1438
1099
|
end
|
|
1439
1100
|
end
|
|
1440
1101
|
xml['SOAP-ENV'].Body do
|
|
@@ -1448,14 +1109,12 @@ module ZuoraAPI
|
|
|
1448
1109
|
|
|
1449
1110
|
while result != "Completed"
|
|
1450
1111
|
sleep 3
|
|
1451
|
-
response_query = HTTParty.post(self.url, body: confirmRequest.to_xml(:save_with => XML_SAVE_OPTIONS).strip, headers: {'Content-Type' => "application/json; charset=utf-8"
|
|
1112
|
+
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)
|
|
1452
1113
|
|
|
1453
1114
|
output_xml = Nokogiri::XML(response_query.body)
|
|
1454
1115
|
result = output_xml.xpath('//ns2:Status', 'ns2' =>'http://object.api.zuora.com/').text
|
|
1455
1116
|
status_code = response_query.code if response_query
|
|
1456
|
-
|
|
1457
|
-
raise_errors(type: :SOAP, body: output_xml, response: response_query) if result.blank? || result == "Failed"
|
|
1458
|
-
# raise "Export Creation Unsuccessful : #{response_query.code}: #{response_query.parsed_response}" if result.blank? || result == "Failed"
|
|
1117
|
+
raise "Export Creation Unsuccessful : #{output_xml.xpath('//ns1:Message', 'ns1' =>'http://api.zuora.com/').text}" if result.blank? || result == "Failed"
|
|
1459
1118
|
end
|
|
1460
1119
|
|
|
1461
1120
|
file_id = output_xml.xpath('//ns2:FileId', 'ns2' =>'http://object.api.zuora.com/').text
|
|
@@ -1474,39 +1133,10 @@ module ZuoraAPI
|
|
|
1474
1133
|
else
|
|
1475
1134
|
return export_file_path
|
|
1476
1135
|
end
|
|
1477
|
-
rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
|
|
1478
|
-
if !(tries -= 1).zero?
|
|
1479
|
-
Rails.logger.info("Export call failed - Trace ID: #{z_track_id}")
|
|
1480
|
-
self.new_session
|
|
1481
|
-
retry
|
|
1482
|
-
end
|
|
1483
|
-
raise ex
|
|
1484
|
-
|
|
1485
|
-
rescue ZuoraAPI::Exceptions::ZuoraUnexpectedError => ex
|
|
1486
|
-
if !(tries -= 1).zero?
|
|
1487
|
-
Rails.logger.info("Trace ID: #{z_track_id} UnexpectedError, will retry after 10 seconds")
|
|
1488
|
-
sleep 10
|
|
1489
|
-
retry
|
|
1490
|
-
end
|
|
1491
|
-
raise ex
|
|
1492
|
-
|
|
1493
|
-
rescue *ZUORA_API_ERRORS => ex
|
|
1494
|
-
raise ex
|
|
1495
|
-
|
|
1496
|
-
rescue *(CONNECTION_EXCEPTIONS + CONNECTION_READ_EXCEPTIONS) => ex
|
|
1497
|
-
if !(tries -= 1).zero?
|
|
1498
|
-
Rails.logger.info("Trace ID: #{z_track_id} Timed out will retry after 5 seconds")
|
|
1499
|
-
sleep 5
|
|
1500
|
-
retry
|
|
1501
|
-
end
|
|
1502
|
-
raise ex
|
|
1503
|
-
|
|
1504
|
-
rescue ZuoraAPI::Exceptions::BadEntityError => ex
|
|
1505
|
-
raise ex
|
|
1506
1136
|
end
|
|
1507
1137
|
|
|
1508
1138
|
def query(query, parse = false)
|
|
1509
|
-
output_xml, input_xml = self.soap_call(debug
|
|
1139
|
+
output_xml, input_xml = self.soap_call({:debug => false, :timeout_retry => true}) do |xml|
|
|
1510
1140
|
xml['ns1'].query do
|
|
1511
1141
|
xml['ns1'].queryString query
|
|
1512
1142
|
end
|
|
@@ -1568,17 +1198,5 @@ module ZuoraAPI
|
|
|
1568
1198
|
end
|
|
1569
1199
|
return "failure"
|
|
1570
1200
|
end
|
|
1571
|
-
|
|
1572
|
-
def reset_files(body)
|
|
1573
|
-
return unless body.is_a? Hash
|
|
1574
|
-
|
|
1575
|
-
body.transform_values! do |v|
|
|
1576
|
-
if v.is_a?(File)
|
|
1577
|
-
v.reopen(v.path)
|
|
1578
|
-
else
|
|
1579
|
-
v
|
|
1580
|
-
end
|
|
1581
|
-
end
|
|
1582
|
-
end
|
|
1583
1201
|
end
|
|
1584
1202
|
end
|