google-ads-common 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +5 -0
- data/README +1 -4
- data/Rakefile +2 -2
- data/lib/ads_common/api.rb +106 -16
- data/lib/ads_common/api_config.rb +2 -3
- data/lib/ads_common/auth/base_handler.rb +22 -3
- data/lib/ads_common/auth/client_login_handler.rb +27 -32
- data/lib/ads_common/auth/oauth_handler.rb +260 -0
- data/lib/ads_common/build/savon_abstract_generator.rb +12 -11
- data/lib/ads_common/build/savon_generator.rb +31 -27
- data/lib/ads_common/build/savon_registry.rb +46 -23
- data/lib/ads_common/build/savon_registry_generator.rb +23 -10
- data/lib/ads_common/build/savon_service_generator.rb +17 -3
- data/lib/ads_common/config.rb +1 -1
- data/lib/ads_common/credential_handler.rb +3 -7
- data/lib/ads_common/errors.rb +18 -6
- data/lib/ads_common/savon_headers/base_header_handler.rb +80 -0
- data/lib/ads_common/{soap4r_logger.rb → savon_headers/httpi_request_proxy.rb} +27 -20
- data/lib/ads_common/savon_headers/oauth_header_handler.rb +92 -0
- data/lib/ads_common/savon_headers/simple_header_handler.rb +17 -49
- data/lib/ads_common/savon_service.rb +129 -41
- data/test/test_savon_service.rb +9 -4
- metadata +39 -43
- data/lib/ads_common/build/rake_common.rb +0 -343
- data/lib/ads_common/build/soap4r_generator.rb +0 -565
- data/lib/ads_common/savon_headers/client_login_header_handler.rb +0 -60
- data/lib/ads_common/soap4r_headers/nested_header_handler.rb +0 -50
- data/lib/ads_common/soap4r_headers/single_header_handler.rb +0 -44
- data/lib/ads_common/soap4r_patches.rb +0 -210
- data/lib/ads_common/soap4r_response_handler.rb +0 -80
@@ -1,60 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
#
|
3
|
-
# Authors:: api.dklimkin@gmail.com (Danial Klimkin)
|
4
|
-
#
|
5
|
-
# Copyright:: Copyright 2011, Google Inc. All Rights Reserved.
|
6
|
-
#
|
7
|
-
# License:: Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
-
# you may not use this file except in compliance with the License.
|
9
|
-
# You may obtain a copy of the License at
|
10
|
-
#
|
11
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
-
#
|
13
|
-
# Unless required by applicable law or agreed to in writing, software
|
14
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
16
|
-
# implied.
|
17
|
-
# See the License for the specific language governing permissions and
|
18
|
-
# limitations under the License.
|
19
|
-
#
|
20
|
-
# Handles SOAP headers and namespaces definition for ClientLogin type header.
|
21
|
-
|
22
|
-
require 'ads_common/savon_headers/simple_header_handler'
|
23
|
-
|
24
|
-
module AdsCommon
|
25
|
-
module SavonHeaders
|
26
|
-
class ClientLoginHeaderHandler < SimpleHeaderHandler
|
27
|
-
private
|
28
|
-
|
29
|
-
# Generates SOAP request header with login credentials and namespace
|
30
|
-
# definition.
|
31
|
-
#
|
32
|
-
# Args:
|
33
|
-
# - None.
|
34
|
-
#
|
35
|
-
# Returns:
|
36
|
-
# - Hash containing a header with filled in credentials.
|
37
|
-
#
|
38
|
-
def generate_request_header()
|
39
|
-
request_header = {}
|
40
|
-
credentials = @credential_handler.credentials(@version)
|
41
|
-
headers = @auth_handler.headers(credentials)
|
42
|
-
headers.each do |header, value|
|
43
|
-
if header == :authToken
|
44
|
-
auth_header = prepend_namespace('authentication')
|
45
|
-
request_header[auth_header] = {
|
46
|
-
prepend_namespace('token') => value
|
47
|
-
}
|
48
|
-
request_header[:attributes!] ||= Hash.new
|
49
|
-
request_header[:attributes!][auth_header] = {
|
50
|
-
'xsi:type' => prepend_namespace('ClientLogin'),
|
51
|
-
}
|
52
|
-
else
|
53
|
-
request_header[prepend_namespace(header)] = value
|
54
|
-
end
|
55
|
-
end
|
56
|
-
return request_header
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
@@ -1,50 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
#
|
3
|
-
# Authors:: api.sgomes@gmail.com (Sérgio Gomes)
|
4
|
-
#
|
5
|
-
# Copyright:: Copyright 2010, Google Inc. All Rights Reserved.
|
6
|
-
#
|
7
|
-
# License:: Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
-
# you may not use this file except in compliance with the License.
|
9
|
-
# You may obtain a copy of the License at
|
10
|
-
#
|
11
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
-
#
|
13
|
-
# Unless required by applicable law or agreed to in writing, software
|
14
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
16
|
-
# implied.
|
17
|
-
# See the License for the specific language governing permissions and
|
18
|
-
# limitations under the License.
|
19
|
-
#
|
20
|
-
# Handles soap headers for AdWords v2009-style SOAP requests (nested headers).
|
21
|
-
|
22
|
-
require 'soap/header/simplehandler'
|
23
|
-
|
24
|
-
module AdsCommon
|
25
|
-
module Soap4rHeaders
|
26
|
-
|
27
|
-
class NestedHeaderHandler < SOAP::Header::SimpleHandler
|
28
|
-
|
29
|
-
def initialize(credential_handler, auth_handler, top_element_name,
|
30
|
-
top_namespace, inner_namespace, version = nil)
|
31
|
-
super(XSD::QName.new(top_namespace, top_element_name))
|
32
|
-
@credential_handler = credential_handler
|
33
|
-
@auth_handler = auth_handler
|
34
|
-
@ns = inner_namespace
|
35
|
-
@version = version
|
36
|
-
end
|
37
|
-
|
38
|
-
# Handles callback.
|
39
|
-
def on_simple_outbound
|
40
|
-
main_header = SOAP::SOAPElement.new(nil)
|
41
|
-
credentials = @credential_handler.credentials(@version)
|
42
|
-
@auth_handler.headers(credentials).each do |cred, value|
|
43
|
-
cred_header = SOAP::SOAPElement.new(XSD::QName.new(@ns, cred), value)
|
44
|
-
main_header.add(cred_header)
|
45
|
-
end
|
46
|
-
return main_header
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
#
|
3
|
-
# Authors:: api.sgomes@gmail.com (Sérgio Gomes)
|
4
|
-
#
|
5
|
-
# Copyright:: Copyright 2010, Google Inc. All Rights Reserved.
|
6
|
-
#
|
7
|
-
# License:: Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
-
# you may not use this file except in compliance with the License.
|
9
|
-
# You may obtain a copy of the License at
|
10
|
-
#
|
11
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
-
#
|
13
|
-
# Unless required by applicable law or agreed to in writing, software
|
14
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
16
|
-
# implied.
|
17
|
-
# See the License for the specific language governing permissions and
|
18
|
-
# limitations under the License.
|
19
|
-
#
|
20
|
-
# Handles soap headers for AdWords v13-style SOAP requests (flat headers).
|
21
|
-
|
22
|
-
require 'soap/header/simplehandler'
|
23
|
-
|
24
|
-
module AdsCommon
|
25
|
-
module Soap4rHeaders
|
26
|
-
|
27
|
-
class SingleHeaderHandler < SOAP::Header::SimpleHandler
|
28
|
-
|
29
|
-
def initialize(credential_handler, auth_handler,
|
30
|
-
element_name, element_namespace = nil, version = nil)
|
31
|
-
super(XSD::QName.new(element_namespace, element_name))
|
32
|
-
@credential_handler = credential_handler
|
33
|
-
@auth_handler = auth_handler
|
34
|
-
@element_name = element_name
|
35
|
-
@version = version
|
36
|
-
end
|
37
|
-
|
38
|
-
def on_simple_outbound
|
39
|
-
credentials = @credential_handler.credentials(@version)
|
40
|
-
return @auth_handler.headers(credentials)[@element_name]
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
@@ -1,210 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
#
|
3
|
-
# Authors:: api.sgomes@gmail.com (Sérgio Gomes)
|
4
|
-
# api.jeffy@gmail.com (Jeffrey Posnick)
|
5
|
-
#
|
6
|
-
# Copyright:: Copyright 2010, Google Inc. All Rights Reserved.
|
7
|
-
#
|
8
|
-
# License:: Licensed under the Apache License, Version 2.0 (the "License");
|
9
|
-
# you may not use this file except in compliance with the License.
|
10
|
-
# You may obtain a copy of the License at
|
11
|
-
#
|
12
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
13
|
-
#
|
14
|
-
# Unless required by applicable law or agreed to in writing, software
|
15
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
17
|
-
# implied.
|
18
|
-
# See the License for the specific language governing permissions and
|
19
|
-
# limitations under the License.
|
20
|
-
#
|
21
|
-
# Collection of small patches to soap4r, used in the client libraries.
|
22
|
-
|
23
|
-
require 'rubygems'
|
24
|
-
begin
|
25
|
-
gem 'soap4r', '=1.5.8'
|
26
|
-
rescue
|
27
|
-
require_gem 'soap4r', '=1.5.8'
|
28
|
-
end
|
29
|
-
require 'soap/soap'
|
30
|
-
require 'soap/rpc/driver'
|
31
|
-
|
32
|
-
|
33
|
-
# Fix an issue with code generation: the infamous "type collapse" bug. This
|
34
|
-
# should avoid objects with just one property, that happens to be an array, from
|
35
|
-
# being collapsed into a simple array.
|
36
|
-
module WSDL
|
37
|
-
module SOAP
|
38
|
-
class ClassDefCreator
|
39
|
-
def dump_complextype
|
40
|
-
definitions = sort_dependency(@complextypes).collect { |type|
|
41
|
-
c = create_complextypedef(@modulepath, type.name, type)
|
42
|
-
c ? c.dump : nil
|
43
|
-
}.compact.join("\n")
|
44
|
-
end
|
45
|
-
|
46
|
-
def create_complextypedef(mpath, qname, type, qualified = false)
|
47
|
-
case type.compoundtype
|
48
|
-
when :TYPE_STRUCT, :TYPE_EMPTY
|
49
|
-
create_structdef(mpath, qname, type, qualified)
|
50
|
-
when :TYPE_ARRAY
|
51
|
-
### Patch starts here ###
|
52
|
-
create_structdef(mpath, qname, type, qualified)
|
53
|
-
#create_arraydef(mpath, qname, type)
|
54
|
-
### Patch ends here ###
|
55
|
-
when :TYPE_SIMPLE
|
56
|
-
create_simpleclassdef(mpath, qname, type)
|
57
|
-
when :TYPE_MAP
|
58
|
-
# mapped as a general Hash
|
59
|
-
nil
|
60
|
-
else
|
61
|
-
raise RuntimeError.new(
|
62
|
-
"unknown kind of complexContent: #{type.compoundtype}")
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
module SOAP
|
70
|
-
|
71
|
-
# Fix an issue with SOAPDate. Google complains if the dates have any timezone
|
72
|
-
# info in them. There are probably better ways to fix this.
|
73
|
-
class SOAPDate
|
74
|
-
|
75
|
-
def of2tz(offset)
|
76
|
-
diffmin = offset * 24 * 60
|
77
|
-
if diffmin.zero?
|
78
|
-
''
|
79
|
-
else
|
80
|
-
((diffmin < 0) ? '-' : '+') << format('%02d:%02d',
|
81
|
-
(diffmin.abs / 60.0).to_i, (diffmin.abs % 60.0).to_i)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
# Fix an issue with base64 encoded items in responses, which causes them to
|
87
|
-
# be encoded twice
|
88
|
-
module Mapping
|
89
|
-
class LiteralRegistry
|
90
|
-
def base2obj(value, klass)
|
91
|
-
v = if value.respond_to?(:data)
|
92
|
-
value.data
|
93
|
-
elsif value.respond_to?(:text)
|
94
|
-
value.text
|
95
|
-
else
|
96
|
-
nil
|
97
|
-
end
|
98
|
-
### Patch starts here ###
|
99
|
-
if klass.to_s == 'SOAP::SOAPBase64'
|
100
|
-
v
|
101
|
-
### Patch ends here ###
|
102
|
-
elsif value.is_a?(klass)
|
103
|
-
v
|
104
|
-
else
|
105
|
-
klass.to_data(v)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
# Monkey-patching soap4r to add a callback at the Proxy level. Not exactly the
|
112
|
-
# prettiest way of doing things, but other callback levels in soap4r don't
|
113
|
-
# provide all the information we need to log.
|
114
|
-
module RPC
|
115
|
-
|
116
|
-
class CallbackHandler
|
117
|
-
|
118
|
-
# The callback handler takes a method name (the API method invoked), an
|
119
|
-
# endpoint and the message envelope. This method is meant to be overloaded
|
120
|
-
# in derived classes.
|
121
|
-
def on_callback(method_name, endpoint, envelope)
|
122
|
-
return nil
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
class Driver
|
127
|
-
# Use the Driver class's __attr_proxy method to declare getters and
|
128
|
-
# setters for "callbackhandler". These reference the getters and setters
|
129
|
-
# for the property with the same name in the Proxy object contained
|
130
|
-
# within driver (@proxy).
|
131
|
-
__attr_proxy :callbackhandler, true
|
132
|
-
|
133
|
-
end
|
134
|
-
|
135
|
-
class Proxy
|
136
|
-
|
137
|
-
attr_accessor :callbackhandler
|
138
|
-
|
139
|
-
# This method is a copy of the one included in soap4r, with the additions
|
140
|
-
# marked below, to enable the callback.
|
141
|
-
def call(name, *params)
|
142
|
-
# name must be used only for lookup
|
143
|
-
op_info = lookup_operation(name)
|
144
|
-
mapping_opt = create_mapping_opt
|
145
|
-
req_header = create_request_header
|
146
|
-
req_body = SOAPBody.new(
|
147
|
-
op_info.request_body(params, @mapping_registry,
|
148
|
-
@literal_mapping_registry, mapping_opt)
|
149
|
-
)
|
150
|
-
reqopt = create_encoding_opt(
|
151
|
-
:soapaction => op_info.soapaction || @soapaction,
|
152
|
-
:envelopenamespace => @options["soap.envelope.requestnamespace"],
|
153
|
-
:default_encodingstyle =>
|
154
|
-
@default_encodingstyle || op_info.request_default_encodingstyle,
|
155
|
-
:use_default_namespace =>
|
156
|
-
op_info.use_default_namespace || @use_default_namespace
|
157
|
-
)
|
158
|
-
resopt = create_encoding_opt(
|
159
|
-
:envelopenamespace => @options["soap.envelope.responsenamespace"],
|
160
|
-
:default_encodingstyle =>
|
161
|
-
@default_encodingstyle || op_info.response_default_encodingstyle
|
162
|
-
)
|
163
|
-
if reqopt[:generate_explicit_type].nil?
|
164
|
-
reqopt[:generate_explicit_type] = (op_info.request_use == :encoded)
|
165
|
-
end
|
166
|
-
if resopt[:generate_explicit_type].nil?
|
167
|
-
resopt[:generate_explicit_type] = (op_info.response_use == :encoded)
|
168
|
-
end
|
169
|
-
env = route(req_header, req_body, reqopt, resopt)
|
170
|
-
### Patch starts here ###
|
171
|
-
if op_info.response_use.nil?
|
172
|
-
unless callbackhandler.nil?
|
173
|
-
callbackhandler.on_callback(name, @endpoint_url, env, params)
|
174
|
-
end
|
175
|
-
return nil
|
176
|
-
end
|
177
|
-
fault = false
|
178
|
-
fault_message = nil
|
179
|
-
begin
|
180
|
-
unless env
|
181
|
-
fault = true
|
182
|
-
fault_message = 'Empty SOAP response'
|
183
|
-
raise EmptyResponseError
|
184
|
-
end
|
185
|
-
receive_headers(env.header)
|
186
|
-
begin
|
187
|
-
check_fault(env.body)
|
188
|
-
rescue ::SOAP::FaultError => e
|
189
|
-
fault = true
|
190
|
-
fault_message = e.to_s
|
191
|
-
op_info.raise_fault(e, @mapping_registry, @literal_mapping_registry)
|
192
|
-
end
|
193
|
-
ensure
|
194
|
-
unless callbackhandler.nil?
|
195
|
-
callbackhandler.on_callback(name, @endpoint_url, env, params, fault,
|
196
|
-
fault_message)
|
197
|
-
end
|
198
|
-
end
|
199
|
-
### Patch ends here ###
|
200
|
-
|
201
|
-
if @return_response_as_xml
|
202
|
-
resopt[:response_as_xml]
|
203
|
-
else
|
204
|
-
op_info.response_obj(env.body, @mapping_registry,
|
205
|
-
@literal_mapping_registry, mapping_opt)
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
209
|
-
end
|
210
|
-
end
|
@@ -1,80 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
#
|
3
|
-
# Authors:: api.sgomes@gmail.com (Sérgio Gomes)
|
4
|
-
#
|
5
|
-
# Copyright:: Copyright 2011, Google Inc. All Rights Reserved.
|
6
|
-
#
|
7
|
-
# License:: Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
-
# you may not use this file except in compliance with the License.
|
9
|
-
# You may obtain a copy of the License at
|
10
|
-
#
|
11
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
-
#
|
13
|
-
# Unless required by applicable law or agreed to in writing, software
|
14
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
16
|
-
# implied.
|
17
|
-
# See the License for the specific language governing permissions and
|
18
|
-
# limitations under the License.
|
19
|
-
#
|
20
|
-
# Generic callback handling class, to be inherited from and extended for
|
21
|
-
# specific APIs.
|
22
|
-
|
23
|
-
require 'ads_common/soap4r_patches'
|
24
|
-
|
25
|
-
module AdsCommon
|
26
|
-
|
27
|
-
# Handler class to process response messages for API unit usage and statistics
|
28
|
-
# information.
|
29
|
-
class Soap4rResponseHandler < SOAP::RPC::CallbackHandler
|
30
|
-
|
31
|
-
# Constructor for Soap4rResponseHandler.
|
32
|
-
#
|
33
|
-
# Args:
|
34
|
-
# - parent: AdsCommon::Api object to which this instance should be tied
|
35
|
-
#
|
36
|
-
def initialize(parent)
|
37
|
-
@parent = parent
|
38
|
-
end
|
39
|
-
|
40
|
-
# Handles the callback method.
|
41
|
-
# This method is a prime candidate for redefinition in specific APIs.
|
42
|
-
#
|
43
|
-
# Args:
|
44
|
-
# - method_name: name for the operation that was invoked
|
45
|
-
# - endpoint: the endpoint URL the request was sent to
|
46
|
-
# - envelope: the envelope for the SOAP response that was received
|
47
|
-
# - params: the parameters that were passed to the method
|
48
|
-
# - fault: whether the request resulted in a fault or not
|
49
|
-
# - fault_msg: the fault message in case of a fault (nil if none)
|
50
|
-
#
|
51
|
-
def on_callback(method_name, endpoint, envelope, params, fault = false,
|
52
|
-
fault_msg = nil)
|
53
|
-
fault_text = fault_msg ? fault_msg.to_s : 'none'
|
54
|
-
data = "host=%s method=%s isFault=%s faultMessage=\"%s\"" %
|
55
|
-
[URI.parse(endpoint).host, method_name, fault.to_s, fault_text]
|
56
|
-
@parent.logger.info(data)
|
57
|
-
end
|
58
|
-
|
59
|
-
# Parses the value contained in a SOAP response header.
|
60
|
-
#
|
61
|
-
# Args:
|
62
|
-
# - header: an object representing a SOAP header
|
63
|
-
#
|
64
|
-
# Returns:
|
65
|
-
# The value contained in the header as a string, or nil if the header is nil
|
66
|
-
#
|
67
|
-
def parse_header(header)
|
68
|
-
if header.nil?
|
69
|
-
return nil
|
70
|
-
end
|
71
|
-
|
72
|
-
header_element = header
|
73
|
-
if header.instance_variable_defined?('@element')
|
74
|
-
header_element = header.element
|
75
|
-
end
|
76
|
-
|
77
|
-
return header_element.text
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|