google-ads-common 0.6.4 → 0.7.0
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.
- data/ChangeLog +4 -0
- data/README +1 -1
- data/lib/ads_common/api.rb +66 -86
- data/lib/ads_common/api_config.rb +37 -64
- data/lib/ads_common/auth/base_handler.rb +9 -19
- data/lib/ads_common/auth/client_login_handler.rb +43 -44
- data/lib/ads_common/auth/oauth_handler.rb +63 -77
- data/lib/ads_common/build/savon_generator.rb +1 -5
- data/lib/ads_common/build/savon_service_generator.rb +3 -16
- data/lib/ads_common/credential_handler.rb +31 -9
- data/lib/ads_common/http.rb +20 -21
- data/lib/ads_common/parameters_validator.rb +2 -1
- data/lib/ads_common/results_extractor.rb +183 -0
- data/lib/ads_common/savon_headers/base_header_handler.rb +26 -21
- data/lib/ads_common/savon_headers/oauth_header_handler.rb +4 -29
- data/lib/ads_common/savon_service.rb +28 -174
- data/lib/ads_common/version.rb +1 -1
- data/test/coverage.rb +35 -0
- data/test/suite_unittests.rb +30 -0
- data/test/test_client_login_handler.rb +41 -8
- data/test/test_config.rb +3 -4
- data/test/test_credential_handler.rb +55 -0
- data/test/test_parameters_validator.rb +24 -1
- data/test/test_results_extractor.rb +165 -0
- data/test/test_savon_service.rb +14 -167
- metadata +38 -25
- data/lib/ads_common/savon_headers/simple_header_handler.rb +0 -63
data/ChangeLog
CHANGED
data/README
CHANGED
data/lib/ads_common/api.rb
CHANGED
@@ -52,8 +52,8 @@ module AdsCommon
|
|
52
52
|
end
|
53
53
|
|
54
54
|
# Getter for the API service configurations.
|
55
|
-
def api_config
|
56
|
-
AdsCommon::ApiConfig
|
55
|
+
def api_config()
|
56
|
+
return AdsCommon::ApiConfig
|
57
57
|
end
|
58
58
|
|
59
59
|
# Obtain an API service, given a version and its name.
|
@@ -68,31 +68,10 @@ module AdsCommon
|
|
68
68
|
def service(name, version = nil)
|
69
69
|
name = name.to_sym
|
70
70
|
version = (version.nil?) ? api_config.default_version : version.to_sym
|
71
|
-
|
72
|
-
# Check if version exists.
|
73
|
-
if !api_config.versions.include?(version)
|
74
|
-
raise AdsCommon::Errors::Error, "Unknown version '%s'" % version
|
75
|
-
end
|
76
|
-
|
77
|
-
# Check if the current environment supports the requested version.
|
78
71
|
environment = @config.read('service.environment')
|
79
72
|
|
80
|
-
if
|
81
|
-
|
82
|
-
"Unknown or unspecified environment: '%s'" % environment
|
83
|
-
end
|
84
|
-
|
85
|
-
if !api_config.environment_has_version(environment, version)
|
86
|
-
raise AdsCommon::Errors::Error,
|
87
|
-
"Environment '%s' does not support version '%s'" %
|
88
|
-
[environment, version]
|
89
|
-
end
|
90
|
-
|
91
|
-
# Check if the specified version has the requested service.
|
92
|
-
if !api_config.version_has_service(version, name)
|
93
|
-
raise AdsCommon::Errors::Error,
|
94
|
-
"Version '%s' does not contain service '%s'" % [version, name]
|
95
|
-
end
|
73
|
+
# Check if the combination is available.
|
74
|
+
validate_service_request(environment, version, name)
|
96
75
|
|
97
76
|
# Try to re-use the service for this version if it was requested before.
|
98
77
|
wrapper = if @wrappers.include?(version) && @wrappers[version][name]
|
@@ -121,12 +100,15 @@ module AdsCommon
|
|
121
100
|
parameters.each_pair do |key, value|
|
122
101
|
@credential_handler.set_credential(key, value)
|
123
102
|
end
|
124
|
-
@auth_handler = get_auth_handler(@config.read('service.environment'))
|
125
103
|
|
126
|
-
|
127
|
-
token =
|
104
|
+
auth_handler = get_auth_handler()
|
105
|
+
token = auth_handler.get_token()
|
106
|
+
|
107
|
+
# If token is invalid ask for a new one.
|
108
|
+
if token.nil?
|
128
109
|
begin
|
129
|
-
@
|
110
|
+
credentials = @credential_handler.credentials
|
111
|
+
token = @auth_handler.get_token(credentials)
|
130
112
|
rescue AdsCommon::Errors::OAuthVerificationRequired => e
|
131
113
|
verification_code = (block_given?) ? yield(e.oauth_url) : nil
|
132
114
|
# Retry with verification code if one provided.
|
@@ -138,63 +120,78 @@ module AdsCommon
|
|
138
120
|
raise e
|
139
121
|
end
|
140
122
|
end
|
123
|
+
end
|
141
124
|
return token
|
142
125
|
end
|
143
126
|
|
127
|
+
# Auxiliary method to get an authentication handler. Creates a new one if
|
128
|
+
# the handler has not been initialized yet.
|
129
|
+
#
|
130
|
+
# Returns:
|
131
|
+
# - auth handler
|
132
|
+
#
|
133
|
+
def get_auth_handler()
|
134
|
+
@auth_handler ||= create_auth_handler()
|
135
|
+
return @auth_handler
|
136
|
+
end
|
137
|
+
|
144
138
|
private
|
145
139
|
|
146
|
-
#
|
147
|
-
|
148
|
-
|
140
|
+
# Auxiliary method to test parameters correctness for the service request.
|
141
|
+
def validate_service_request(environment, version, service)
|
142
|
+
# Check if the current environment supports the requested version.
|
143
|
+
unless api_config.environment_has_version(environment, version)
|
144
|
+
raise AdsCommon::Errors::Error,
|
145
|
+
"Environment '%s' does not support version '%s'" %
|
146
|
+
[environment.to_s, version.to_s]
|
147
|
+
end
|
148
|
+
|
149
|
+
# Check if the specified version has the requested service.
|
150
|
+
unless api_config.version_has_service(version, service)
|
151
|
+
raise AdsCommon::Errors::Error,
|
152
|
+
"Version '%s' does not contain service '%s'" %
|
153
|
+
[version.to_s, name.to_s]
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# Retrieve the SOAP header handler to generate headers based on the
|
158
|
+
# configuration. Needs to be implemented on the specific API, because of
|
159
|
+
# the different types of SOAP headers.
|
149
160
|
#
|
150
161
|
# Args:
|
151
162
|
# - auth_handler: instance of an AdsCommon::Auth::BaseHandler subclass to
|
152
163
|
# handle authentication
|
153
|
-
# - header_list: the list of headers to be handled
|
154
164
|
# - version: intended API version
|
155
165
|
# - wrapper: wrapper object for the service being handled
|
156
166
|
#
|
157
167
|
# Returns:
|
158
168
|
# - a list of SOAP header handlers; one per provided header
|
159
169
|
#
|
160
|
-
def
|
161
|
-
raise NotImplementedError, '
|
162
|
-
end
|
163
|
-
|
164
|
-
# Auxiliary method to get an authentication handler. Creates a new one if
|
165
|
-
# the handler has not been initialized yet.
|
166
|
-
#
|
167
|
-
# Args:
|
168
|
-
# - environment: the current working environment (production, sandbox, etc.)
|
169
|
-
# - version: intended API version, must be a symbol, optional
|
170
|
-
#
|
171
|
-
# Returns:
|
172
|
-
# - auth handler
|
173
|
-
#
|
174
|
-
def get_auth_handler(environment, version = nil)
|
175
|
-
@auth_handler ||= create_auth_handler(environment, version)
|
176
|
-
return @auth_handler
|
170
|
+
def soap_header_handler(auth_handler, version, wrapper)
|
171
|
+
raise NotImplementedError, 'soap_header_handler not overridden.'
|
177
172
|
end
|
178
173
|
|
179
174
|
# Auxiliary method to create an authentication handler.
|
180
175
|
#
|
181
|
-
# Args:
|
182
|
-
# - environment: the current working environment (production, sandbox, etc.)
|
183
|
-
# - version: intended API version, must be a symbol, optional
|
184
|
-
#
|
185
176
|
# Returns:
|
186
177
|
# - auth handler
|
187
178
|
#
|
188
|
-
def create_auth_handler(
|
179
|
+
def create_auth_handler()
|
189
180
|
auth_method = @config.read('authentication.method', :CLIENTLOGIN)
|
190
181
|
return case auth_method
|
191
182
|
when :CLIENTLOGIN
|
192
|
-
|
193
|
-
|
194
|
-
api_config.
|
183
|
+
AdsCommon::Auth::ClientLoginHandler.new(
|
184
|
+
@config,
|
185
|
+
api_config.client_login_config(:AUTH_SERVER),
|
186
|
+
api_config.client_login_config(:LOGIN_SERVICE_NAME)
|
187
|
+
)
|
195
188
|
when :OAUTH
|
196
|
-
|
197
|
-
|
189
|
+
environment = @config.read('service.environment',
|
190
|
+
api_config.default_environment())
|
191
|
+
AdsCommon::Auth::OAuthHandler.new(
|
192
|
+
@config,
|
193
|
+
api_config.environment_config(environment, :oauth_scope)
|
194
|
+
)
|
198
195
|
else
|
199
196
|
raise AdsCommon::Errors::Error,
|
200
197
|
"Unknown authentication method '%s'" % auth_method
|
@@ -202,33 +199,26 @@ module AdsCommon
|
|
202
199
|
end
|
203
200
|
|
204
201
|
# Handle loading of a single service.
|
205
|
-
# Creates the
|
206
|
-
# class and creates an instance of it.
|
202
|
+
# Creates the wrapper, sets up handlers and creates an instance of it.
|
207
203
|
#
|
208
204
|
# Args:
|
209
205
|
# - version: intended API version, must be a symbol
|
210
206
|
# - service: name for the intended service
|
211
207
|
#
|
212
208
|
# Returns:
|
213
|
-
# - a simplified wrapper generated for the
|
209
|
+
# - a simplified wrapper generated for the service
|
214
210
|
#
|
215
211
|
def prepare_wrapper(version, service)
|
216
212
|
environment = config.read('service.environment')
|
217
213
|
api_config.do_require(version, service)
|
218
214
|
endpoint = api_config.endpoint(environment, version, service)
|
219
215
|
interface_class_name = api_config.interface_name(version, service)
|
220
|
-
endpoint_url = endpoint.nil? ? nil : endpoint + service.to_s
|
221
|
-
wrapper = class_for_path(interface_class_name).new(self, endpoint_url)
|
222
|
-
|
223
|
-
auth_handler = get_auth_handler(environment, version)
|
224
|
-
header_list =
|
225
|
-
auth_handler.header_list(@credential_handler.credentials(version))
|
226
216
|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
217
|
+
wrapper = class_for_path(interface_class_name).new(@config, endpoint)
|
218
|
+
auth_handler = get_auth_handler()
|
219
|
+
soap_handler =
|
220
|
+
soap_header_handler(auth_handler, version, wrapper.namespace)
|
221
|
+
wrapper.header_handler = soap_handler
|
232
222
|
|
233
223
|
return wrapper
|
234
224
|
end
|
@@ -237,7 +227,7 @@ module AdsCommon
|
|
237
227
|
def create_default_logger()
|
238
228
|
logger = Logger.new(STDOUT)
|
239
229
|
logger.level = get_log_level_for_string(
|
240
|
-
@config.read('library.log_level',
|
230
|
+
@config.read('library.log_level', 'INFO'))
|
241
231
|
return logger
|
242
232
|
end
|
243
233
|
|
@@ -274,17 +264,7 @@ module AdsCommon
|
|
274
264
|
|
275
265
|
# Converts log level string (from config) to Logger value.
|
276
266
|
def get_log_level_for_string(log_level)
|
277
|
-
|
278
|
-
if log_level.is_a?(String)
|
279
|
-
result = case log_level.upcase
|
280
|
-
when 'FATAL' then Logger::FATAL
|
281
|
-
when 'ERROR' then Logger::ERROR
|
282
|
-
when 'WARN' then Logger::WARN
|
283
|
-
when 'INFO' then Logger::INFO
|
284
|
-
when 'DEBUG' then Logger::DEBUG
|
285
|
-
end
|
286
|
-
end
|
287
|
-
return result
|
267
|
+
return Logger.const_get(log_level)
|
288
268
|
end
|
289
269
|
|
290
270
|
# Converts complete class path into class object.
|
@@ -24,14 +24,13 @@
|
|
24
24
|
require 'ads_common/version.rb'
|
25
25
|
|
26
26
|
module AdsCommon
|
27
|
-
|
28
27
|
# Contains helper methods for loading and managing the available services.
|
29
28
|
# This module is meant to be imported into API-specific modules.
|
30
29
|
module ApiConfig
|
31
30
|
# Get the available API versions.
|
32
31
|
#
|
33
32
|
# Returns:
|
34
|
-
# List of versions available
|
33
|
+
# List of versions available
|
35
34
|
#
|
36
35
|
def versions
|
37
36
|
service_config.keys
|
@@ -40,7 +39,7 @@ module AdsCommon
|
|
40
39
|
# Get the latest API version.
|
41
40
|
#
|
42
41
|
# Returns:
|
43
|
-
# Latest version
|
42
|
+
# Latest version
|
44
43
|
#
|
45
44
|
def latest_version
|
46
45
|
service_config.keys.select { |service| service.is_a? Integer }.max
|
@@ -53,8 +52,7 @@ module AdsCommon
|
|
53
52
|
# given version
|
54
53
|
#
|
55
54
|
def environment_has_version(environment, version)
|
56
|
-
return environment_config
|
57
|
-
environment_config[environment].include?(version)
|
55
|
+
return !environment_config(environment, version).nil?
|
58
56
|
end
|
59
57
|
|
60
58
|
# Does the given version exist and contain the given service?
|
@@ -71,7 +69,7 @@ module AdsCommon
|
|
71
69
|
# Get the default API version.
|
72
70
|
#
|
73
71
|
# Returns:
|
74
|
-
# Default version
|
72
|
+
# Default version
|
75
73
|
#
|
76
74
|
def default_version
|
77
75
|
nil
|
@@ -83,21 +81,12 @@ module AdsCommon
|
|
83
81
|
# - version: the API version (as an integer)
|
84
82
|
#
|
85
83
|
# Returns:
|
86
|
-
# List of names of services
|
84
|
+
# List of names of services available for given version
|
87
85
|
#
|
88
86
|
def services(version)
|
89
87
|
service_config[version]
|
90
88
|
end
|
91
89
|
|
92
|
-
# Get the available environments.
|
93
|
-
#
|
94
|
-
# Returns:
|
95
|
-
# List of available environments (as strings)
|
96
|
-
#
|
97
|
-
def environments
|
98
|
-
environment_config.keys
|
99
|
-
end
|
100
|
-
|
101
90
|
# Get the API name.
|
102
91
|
def api_name
|
103
92
|
raise NotImplementedError, 'api_name not overriden.'
|
@@ -111,7 +100,7 @@ module AdsCommon
|
|
111
100
|
# Get the default environment.
|
112
101
|
#
|
113
102
|
# Returns:
|
114
|
-
# Default environment
|
103
|
+
# Default environment
|
115
104
|
#
|
116
105
|
def default_environment
|
117
106
|
raise NotImplementedError, 'default_environment not overriden.'
|
@@ -125,32 +114,34 @@ module AdsCommon
|
|
125
114
|
# Get the endpoint for a service on a given environment and API version.
|
126
115
|
#
|
127
116
|
# Args:
|
128
|
-
# - environment: the service environment to be used
|
129
|
-
# - version: the API version
|
130
|
-
# - service: the name of the API service
|
117
|
+
# - environment: the service environment to be used
|
118
|
+
# - version: the API version
|
119
|
+
# - service: the name of the API service
|
131
120
|
#
|
132
121
|
# Returns:
|
133
|
-
# The endpoint URL
|
122
|
+
# The endpoint URL
|
134
123
|
#
|
135
124
|
def endpoint(environment, version, service)
|
136
125
|
base = get_wsdl_base(environment, version)
|
126
|
+
# TODO(dklimkin): Unflatten subdir constants. Cross-API refactor 0.7.0.
|
137
127
|
if !subdir_config().nil?
|
138
128
|
base = base.to_s + subdir_config()[[version, service]].to_s
|
139
129
|
end
|
140
|
-
return base.to_s + version.to_s + '/'
|
130
|
+
return base.to_s + version.to_s + '/' + service.to_s
|
141
131
|
end
|
142
132
|
|
143
133
|
# Get the subdirectory for a service, for a given API version.
|
144
134
|
#
|
145
135
|
# Args:
|
146
|
-
# - version: the API version
|
147
|
-
# - service: the name of the API service
|
136
|
+
# - version: the API version
|
137
|
+
# - service: the name of the API service
|
148
138
|
#
|
149
139
|
# Returns:
|
150
|
-
# The
|
140
|
+
# The subdir infix
|
151
141
|
#
|
152
142
|
def subdir(version, service)
|
153
143
|
return nil if subdir_config().nil?
|
144
|
+
# TODO(dklimkin): Unflatten subdir constants. Cross-API refactor 0.7.0.
|
154
145
|
subdir_config()[[version, service]]
|
155
146
|
end
|
156
147
|
|
@@ -158,30 +149,26 @@ module AdsCommon
|
|
158
149
|
# override the auth URL via environmental variable.
|
159
150
|
#
|
160
151
|
# Args:
|
161
|
-
# - environment: the service environment to be used
|
152
|
+
# - environment: the service environment to be used
|
162
153
|
#
|
163
154
|
# Returns:
|
164
|
-
# The full URL for the auth server
|
155
|
+
# The full URL for the auth server
|
165
156
|
#
|
166
157
|
def auth_server(environment)
|
167
|
-
|
168
|
-
ENV['ADSAPI_AUTH_URL'] ||
|
169
|
-
auth_server_config[environment]
|
170
|
-
return auth_server_url
|
158
|
+
return ENV['ADSAPI_AUTH_URL'] || auth_server_config[environment]
|
171
159
|
end
|
172
160
|
|
173
161
|
# Perform the loading of the necessary source files for a version.
|
174
162
|
#
|
175
163
|
# Args:
|
176
|
-
# - version: the API version
|
177
|
-
# - service: service name
|
164
|
+
# - version: the API version
|
165
|
+
# - service: service name
|
178
166
|
#
|
179
167
|
# Returns:
|
180
|
-
# The filename that was loaded
|
168
|
+
# The filename that was loaded
|
181
169
|
#
|
182
170
|
def do_require(version, service)
|
183
|
-
filename =
|
184
|
-
[api_path, version.to_s, service.to_s.snakecase]
|
171
|
+
filename = [api_path, version.to_s, service.to_s.snakecase].join('/')
|
185
172
|
require filename
|
186
173
|
return filename
|
187
174
|
end
|
@@ -189,41 +176,27 @@ module AdsCommon
|
|
189
176
|
# Returns the full module name for a given service.
|
190
177
|
#
|
191
178
|
# Args:
|
192
|
-
# - version: the API version
|
193
|
-
# - service: the service name
|
179
|
+
# - version: the API version
|
180
|
+
# - service: the service name
|
194
181
|
#
|
195
182
|
# Returns:
|
196
|
-
# The full module name for the given service
|
183
|
+
# The full module name for the given service
|
197
184
|
#
|
198
185
|
def module_name(version, service)
|
199
|
-
return
|
200
|
-
[api_name, version.to_s.upcase, service.to_s]
|
186
|
+
return [api_name, version.to_s.upcase, service.to_s].join('::')
|
201
187
|
end
|
202
188
|
|
203
189
|
# Returns the full interface class name for a given service.
|
204
190
|
#
|
205
191
|
# Args:
|
206
|
-
# - version: the API version
|
207
|
-
# - service: the service name
|
192
|
+
# - version: the API version
|
193
|
+
# - service: the service name
|
208
194
|
#
|
209
195
|
# Returns:
|
210
|
-
# The full interface class name for the given service
|
196
|
+
# The full interface class name for the given service
|
211
197
|
#
|
212
198
|
def interface_name(version, service)
|
213
|
-
return module_name(version, service)
|
214
|
-
end
|
215
|
-
|
216
|
-
# Returns the full wrapper class name for a given service
|
217
|
-
#
|
218
|
-
# Args:
|
219
|
-
# - version: the API version (as an integer)
|
220
|
-
# - service: the service name (as a string)
|
221
|
-
#
|
222
|
-
# Returns:
|
223
|
-
# The full wrapper class name for the given service (as a string)
|
224
|
-
#
|
225
|
-
def wrapper_name(version, service)
|
226
|
-
return module_name(version, service) + "::#{service}Wrapper"
|
199
|
+
return [module_name(version, service), service.to_s].join('::')
|
227
200
|
end
|
228
201
|
|
229
202
|
# Generates an array of WSDL URLs based on defined Services and version
|
@@ -234,7 +207,7 @@ module AdsCommon
|
|
234
207
|
# - version: the API version.
|
235
208
|
#
|
236
209
|
# Returns
|
237
|
-
# hash of pairs Service => WSDL URL
|
210
|
+
# hash of pairs Service => WSDL URL
|
238
211
|
#
|
239
212
|
def get_wsdls(version)
|
240
213
|
res = {}
|
@@ -256,14 +229,14 @@ module AdsCommon
|
|
256
229
|
#
|
257
230
|
# Args:
|
258
231
|
# - environment: environment to use like :SANDBOX or :PRODUCTION
|
259
|
-
# - version: the API version
|
232
|
+
# - version: the API version
|
260
233
|
#
|
261
234
|
# Returns:
|
262
|
-
# String containing base URL
|
235
|
+
# String containing base URL
|
236
|
+
#
|
263
237
|
def get_wsdl_base(environment, version)
|
264
|
-
|
265
|
-
|
266
|
-
return wsdl_base
|
238
|
+
return ENV['ADSAPI_BASE_URL'] ||
|
239
|
+
environment_config(environment, version)
|
267
240
|
end
|
268
241
|
end
|
269
242
|
end
|