google-ads-common 0.2.1 → 0.3.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 CHANGED
@@ -1,3 +1,8 @@
1
+ 0.3.0:
2
+ - Fixes towards Ruby1.9 compatibility.
3
+ - Support for method names with CAPSed words (Savon),
4
+ - New single-Logger logging system.
5
+
1
6
  0.2.1:
2
7
  - Support for Savon 0.9.1 and later which is now a dependency.
3
8
  - Upgraded to httpi/0.9.2, httpclient/2.1.6.
@@ -19,29 +19,19 @@
19
19
  #
20
20
  # Generic Api class, to be inherited from and extended by specific APIs.
21
21
 
22
+ require 'logger'
23
+
22
24
  require 'ads_common/errors'
23
25
  require 'ads_common/auth/base_handler'
24
26
  require 'ads_common/auth/client_login_handler'
25
27
  require 'ads_common/soap4r_headers/nested_header_handler'
26
28
  require 'ads_common/soap4r_headers/single_header_handler'
27
29
  require 'ads_common/soap4r_response_handler'
30
+ require 'ads_common/soap4r_logger'
28
31
 
29
32
  module AdsCommon
30
33
  class Api
31
34
 
32
- # Auxiliary method to create a new Soap4rResponseHandler
33
- # Should be redefined in inheriting classes, if planning to do specific
34
- # logging.
35
- def create_handler
36
- AdsCommon::Soap4rResponseHandler.new(self)
37
- end
38
-
39
- # Logger object used for logging request info
40
- attr_reader :request_logger
41
-
42
- # Logger object used for logging SOAP XML
43
- attr_reader :xml_logger
44
-
45
35
  # Methods that return the service configuration and the client library
46
36
  # configuration. They need to be redefined in subclasses.
47
37
  attr_reader :api_config, :config
@@ -52,6 +42,23 @@ module AdsCommon
52
42
  # The configuration for this Api object
53
43
  attr_reader :config
54
44
 
45
+ # The logger for this Api object.
46
+ attr_reader :logger
47
+
48
+ # Constructor for Api.
49
+ def initialize(provided_config = nil)
50
+ load_config(provided_config)
51
+ provided_logger = @config.read('library.logger')
52
+ self.logger = (provided_logger.nil?) ?
53
+ create_default_logger() : provided_logger
54
+ end
55
+
56
+ # Sets the logger to use.
57
+ def logger=(logger)
58
+ @logger = logger
59
+ @config.set('library.logger', @logger)
60
+ end
61
+
55
62
  # Obtain an API service, given a version and its name.
56
63
  #
57
64
  # Args:
@@ -124,7 +131,7 @@ module AdsCommon
124
131
  end
125
132
 
126
133
  # Handle loading of a single service.
127
- # Creates the driver, sets up handlers and loggers, declares the appropriate
134
+ # Creates the driver, sets up handlers and logger, declares the appropriate
128
135
  # wrapper class and creates an instance of it.
129
136
  #
130
137
  # Args:
@@ -168,7 +175,7 @@ module AdsCommon
168
175
  # Add response handler to this driver for API unit usage processing.
169
176
  driver.callbackhandler = create_callback_handler
170
177
  # Plug the wiredump to our XML logger
171
- driver.wiredump_dev = xml_logger
178
+ driver.wiredump_dev = AdsCommon::Soap4rLogger.new(@logger, Logger::DEBUG)
172
179
  driver.options['protocol.http.ssl_config.verify_mode'] = nil
173
180
  proxy = config.read('connection.proxy')
174
181
  if proxy
@@ -179,5 +186,41 @@ module AdsCommon
179
186
  @wrappers[[version, service]] = wrapper
180
187
  return driver, wrapper
181
188
  end
189
+
190
+ # Auxiliary method to create a default Logger.
191
+ def create_default_logger()
192
+ logger = Logger.new(STDOUT)
193
+ logger.level = get_log_level_for_string(
194
+ @config.read('library.log_level', Logger::INFO))
195
+ return logger
196
+ end
197
+
198
+ # Helper method to load the default configuration file or a given config.
199
+ def load_config(provided_config = nil)
200
+ @config = (provided_config.nil?) ?
201
+ AdsCommon::Config.new(
202
+ File.join(ENV['HOME'], default_config_filename)) :
203
+ AdsCommon::Config.new(provided_config)
204
+ end
205
+
206
+ # Gets the default config filename.
207
+ def default_config_filename()
208
+ return api_config.default_config_filename
209
+ end
210
+
211
+ # Converts log level string (from config) to Logger value.
212
+ def get_log_level_for_string(log_level)
213
+ result = log_level
214
+ if log_level.is_a?(String)
215
+ result = case log_level.upcase
216
+ when 'FATAL' then Logger::FATAL
217
+ when 'ERROR' then Logger:ERROR
218
+ when 'WARN' then Logger::WARN
219
+ when 'INFO' then Logger::INFO
220
+ when 'DEBUG' then Logger::DEBUG
221
+ end
222
+ end
223
+ return result
224
+ end
182
225
  end
183
226
  end
@@ -26,7 +26,7 @@ module AdsCommon
26
26
  # Contains helper methods for loading and managing the available services.
27
27
  # This module is meant to be imported into API-specific modules.
28
28
  module ApiConfig
29
- ADS_COMMON_VERSION = '0.2.1'
29
+ ADS_COMMON_VERSION = '0.3.0'
30
30
 
31
31
  # Get the available API versions.
32
32
  #
@@ -111,6 +111,11 @@ module AdsCommon
111
111
  nil
112
112
  end
113
113
 
114
+ # Get the default filename for the config file.
115
+ def default_config_filename
116
+ raise NotImplementedError, 'default_config_filename not overriden.'
117
+ end
118
+
114
119
  # Get the endpoint for a service on a given environment and API version.
115
120
  #
116
121
  # Args:
@@ -47,7 +47,8 @@ $PKG_VERSION = ENV['REL'] ? ENV['REL'] : $CURRENT_VERSION
47
47
 
48
48
  SRC_RB = FileList["#{$LIBDIR}/**/*.rb"]
49
49
 
50
- logger = Logger.new(STDERR)
50
+ logger = Logger.new(STDOUT)
51
+ logger.level = Logger::INFO
51
52
 
52
53
  CLEAN.include($WSDLDIR)
53
54
  CLEAN.include($DOCDIR)
@@ -69,9 +70,11 @@ task :getwsdl do
69
70
  $API_CONFIG.versions.each do |version|
70
71
  urls = $API_CONFIG.get_wsdls(version)
71
72
  mkdir_p File.join($WSDLDIR, version.to_s)
73
+ config = Generator.config
74
+ config.set('library.logger', logger)
72
75
  urls.each do |service, url|
73
- puts "getting #{url}"
74
- save(AdsCommon::Http.get(url, Generator.config),
76
+ logger.info("Getting #{url}...")
77
+ save(AdsCommon::Http.get(url, config),
75
78
  get_wsdl_file_name(version.to_s, service.to_s))
76
79
  end
77
80
  end
@@ -146,7 +149,8 @@ task :soap4r_generate do
146
149
  File.open(wrapper_file, 'w') do |file|
147
150
  file.write(Generator.generate_wrapper_class(version, service))
148
151
  end
149
- puts "Generated #{version} #{service_name} wrapper: #{wrapper_file}"
152
+ logger.info("Generated #{version} #{service_name} " +
153
+ "wrapper: #{wrapper_file}")
150
154
  end
151
155
  end
152
156
  end
@@ -297,7 +301,7 @@ PKG_FILES = FileList[
297
301
  PKG_FILES.exclude(/\._/)
298
302
 
299
303
  if ! defined?(Gem)
300
- puts "Package Target requires RubyGems"
304
+ logger.fatal('Package Target requires RubyGems')
301
305
  else
302
306
  spec = Gem::Specification.new do |s|
303
307
 
@@ -320,7 +324,7 @@ else
320
324
 
321
325
  # RDoc information
322
326
  s.has_rdoc = true
323
- s.extra_rdoc_files = ['README']
327
+ s.extra_rdoc_files = ['README', 'COPYING', 'ChangeLog']
324
328
  s.rdoc_options << '--main' << 'README'
325
329
 
326
330
  # Metadata
@@ -33,6 +33,7 @@ module AdsCommon
33
33
  @service_name = args[:service_name]
34
34
  @module_name = args[:module_name]
35
35
  @namespace = args[:namespace]
36
+ @logger = args[:logger]
36
37
  @generator_stamp = "Code generated by AdsCommon library %s on %s." %
37
38
  [AdsCommon::ApiConfig::ADS_COMMON_VERSION,
38
39
  Time.now.strftime("%Y-%m-%d %H:%M:%S")]
@@ -45,11 +45,19 @@ module AdsCommon
45
45
  @wsdl_url = wsdl_url
46
46
  @code_path = code_path
47
47
  @service_name = service_name
48
+ @logger = Logger.new(STDOUT)
49
+ @logger.level = Logger::INFO
48
50
  @generator_args = {
49
51
  :service_name => service_name,
50
52
  :module_name => module_name,
51
- :require_path => @code_path.sub(/^lib\//, '')
53
+ :require_path => @code_path.sub(/^lib\//, ''),
54
+ :logger => @logger
52
55
  }
56
+ Savon.configure do |config|
57
+ config.logger = @logger
58
+ config.log_level = :debug
59
+ end
60
+ HTTPI.logger = @logger
53
61
  end
54
62
 
55
63
  #
@@ -68,7 +76,6 @@ module AdsCommon
68
76
  rescue AdsCommon::Errors::Error => e
69
77
  error_msg = "An unrecoverable error occured during code generation"
70
78
  error_msg += " for service [%s]: %s" % [@wsdl_url, e]
71
- # TODO log properly
72
79
  raise AdsCommon::Errors::BuildError, error_msg
73
80
  end
74
81
  end
@@ -121,7 +128,7 @@ module AdsCommon
121
128
  # Creates a new file on specified path, overwriting existing one if it
122
129
  # exists
123
130
  def create_new_file(file_name)
124
- puts "Creating %s..." % [file_name]
131
+ @logger.info("Creating %s..." % [file_name])
125
132
  make_dir_for_path(file_name)
126
133
  new_file = File.new(file_name, File::WRONLY|File::TRUNC|File::CREAT)
127
134
  end
@@ -62,7 +62,6 @@ module AdsCommon
62
62
  @soap_exceptions << extract_exception(ctype)
63
63
  elsif ctype_name.match('.+Error$')
64
64
  # We don't use it at the moment.
65
- # TODO: log we ignore it at proper log level.
66
65
  else
67
66
  @soap_types << extract_type(ctype)
68
67
  end
@@ -96,11 +95,17 @@ module AdsCommon
96
95
 
97
96
  # Extracts method parameters from ComplexTypes element.
98
97
  def extract_method(method_element, doc)
99
- return {:name => get_element_name(method_element).snakecase,
100
- :input => extract_input_parameters(method_element, doc),
101
- :output => extract_output_parameters(method_element, doc)}
102
- # This could be used to include documentation from wsdl.
103
- # :doc => get_element_doc(operation, 'wsdl')}
98
+ name = get_element_name(method_element)
99
+ method = {
100
+ :name => name.snakecase,
101
+ :input => extract_input_parameters(method_element, doc),
102
+ :output => extract_output_parameters(method_element, doc)
103
+ # This could be used to include documentation from wsdl.
104
+ #:doc => get_element_doc(operation, 'wsdl')
105
+ }
106
+ original_name = (name.snakecase.lower_camelcase == name)? nil : name
107
+ method[:original_name] = original_name unless original_name.nil?
108
+ return method
104
109
  end
105
110
 
106
111
  # Extracts definition of all types. If a non standard undefined type is
@@ -31,8 +31,8 @@ module AdsCommon
31
31
  def initialize(param = nil)
32
32
  @config = Hash.new
33
33
  case param
34
- when String: load(param)
35
- when Hash: set_all(param)
34
+ when String then load(param)
35
+ when Hash then set_all(param)
36
36
  end
37
37
  end
38
38
 
@@ -61,14 +61,15 @@ module AdsCommon
61
61
  # Defaulting to stricter :peer validation.
62
62
  def self.prepare_request(config, url, headers = nil, data = nil)
63
63
  request = HTTPI::Request.new(url)
64
- proxy = config ? config.read('connection.proxy') : nil
64
+ proxy = config.read('connection.proxy', nil)
65
65
  request.proxy = proxy if proxy
66
66
  strict_ssl = config.nil? or
67
67
  !(config.read('connection.strict_ssl_verification') == 'false')
68
68
  request.auth.ssl.verify_mode = strict_ssl ? :peer : :none
69
69
  request.headers = headers if headers
70
70
  request.body = data if data
71
- HTTPI.log = false # TODO remove after logger CL.
71
+ logger = config.read('library.logger')
72
+ HTTPI.logger = logger if logger
72
73
  return request
73
74
  end
74
75
  end
@@ -24,7 +24,7 @@ require 'savon'
24
24
 
25
25
  module AdsCommon
26
26
  class SavonService
27
- attr_accessor :headerhandler, :wiredump_dev, :options
27
+ attr_accessor :headerhandler
28
28
 
29
29
  # Creates a new service.
30
30
  def initialize(endpoint, namespace)
@@ -32,8 +32,6 @@ module AdsCommon
32
32
  raise NoMethodError, "Tried to instantiate an abstract class"
33
33
  end
34
34
  @headerhandler = []
35
- @wiredump_dev = nil
36
- @options = {}
37
35
  @client = Savon::Client.new do |wsdl|
38
36
  wsdl.namespace = namespace
39
37
  wsdl.endpoint = endpoint
@@ -55,18 +53,27 @@ module AdsCommon
55
53
  # Executes SOAP action specified as a string with given arguments.
56
54
  def execute_action(action_name, args)
57
55
  args = validate_args(action_name, args)
58
- response = @client.request(action_name.to_sym) do |soap|
59
- set_headers(soap, args)
60
- end
56
+ response = execute_soap_request(action_name.to_sym, args)
61
57
  handle_errors(response)
62
58
  return extract_result(response, action_name)
63
59
  end
64
60
 
61
+ # Executes the SOAP request with original SOAP name.
62
+ def execute_soap_request(action, args)
63
+ original_action_name =
64
+ get_service_registry.get_method_signature(action)[:original_name]
65
+ original_action_name = action if original_action_name.nil?
66
+ response = @client.request(original_action_name) do |soap|
67
+ set_headers(soap, args)
68
+ end
69
+ return response
70
+ end
71
+
65
72
  # Validates input parameters to:
66
73
  # - add parameter names;
67
74
  # - resolve xsi:type where required;
68
75
  # - convert some native types to xml.
69
- def validate_args(action_name, *args)
76
+ def validate_args(action_name, args)
70
77
  validated_args = Hash.new
71
78
  in_params = get_service_registry.get_method_signature(action_name)[:input]
72
79
  in_params.each_with_index do |in_param, index|
@@ -82,9 +89,9 @@ module AdsCommon
82
89
  # Also handles some types that need special conversions.
83
90
  def validate_arg(arg, parent = nil, key = nil)
84
91
  result = case arg
85
- when Hash: validate_hash_arg(arg, parent, key)
86
- when Array: arg.map {|item| validate_arg(item, parent, key)}
87
- when Time: time_to_xml_hash(arg)
92
+ when Hash then validate_hash_arg(arg, parent, key)
93
+ when Array then arg.map {|item| validate_arg(item, parent, key)}
94
+ when Time then time_to_xml_hash(arg)
88
95
  else arg
89
96
  end
90
97
  return result
@@ -216,12 +223,14 @@ module AdsCommon
216
223
  # Converts XML input string into a native format.
217
224
  def normalize_type(data, field)
218
225
  type_name = field[:type]
219
- result = case type_name
220
- when 'long', 'int': Integer(data)
221
- when 'double': Float(data)
222
- when 'boolean': data.kind_of?(String) ? data.casecmp('true') == 0 : data
223
- else data
224
- end
226
+ result = (data.nil?) ? data :
227
+ case type_name
228
+ when 'long', 'int' then Integer(data)
229
+ when 'double' then Float(data)
230
+ when 'boolean' then data.kind_of?(String) ?
231
+ data.casecmp('true') == 0 : data
232
+ else data
233
+ end
225
234
  # If field signature allows an array, forcing array structure even for one
226
235
  # item.
227
236
  if !field[:min_occurs].nil? and
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # Author:: 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
+ # Wrapper class to handle Soap4r-specific logging to standard logger.
21
+
22
+ require 'logger'
23
+
24
+ module AdsCommon
25
+ class Soap4rLogger
26
+ # Constructor for Soap4rLogger.
27
+ #
28
+ # Args:
29
+ # - logger: a ruby logger to log to.
30
+ # - log_level: default log_level for streams, defaults to INFO.
31
+ #
32
+ def initialize(logger, log_level = Logger::INFO)
33
+ @logger = logger
34
+ @log_level = log_level
35
+ end
36
+
37
+ # Overload << operator to perform logging.
38
+ def << (text)
39
+ @logger.add(@log_level) {text.to_s}
40
+ end
41
+ end
42
+ end
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Authors:: api.sgomes@gmail.com (Sérgio Gomes)
4
4
  #
5
- # Copyright:: Copyright 2010, Google Inc. All Rights Reserved.
5
+ # Copyright:: Copyright 2011, Google Inc. All Rights Reserved.
6
6
  #
7
7
  # License:: Licensed under the Apache License, Version 2.0 (the "License");
8
8
  # you may not use this file except in compliance with the License.
@@ -50,19 +50,10 @@ module AdsCommon
50
50
  #
51
51
  def on_callback(method_name, endpoint, envelope, params, fault = false,
52
52
  fault_msg = nil)
53
-
54
- host = URI.parse(endpoint).host
55
-
56
- data = "host=#{host} method=#{method_name} "
57
- data += "isFault=#{(!!fault).to_s} "
58
-
59
- if fault_msg
60
- data += "faultMessage=\"#{fault_msg}\""
61
- else
62
- data += "faultMessage=none"
63
- end
64
-
65
- @parent.request_logger << data
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)
66
57
  end
67
58
 
68
59
  # Parses the value contained in a SOAP response header.
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 2
8
- - 1
9
- version: 0.2.1
7
+ - 3
8
+ - 0
9
+ version: 0.3.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Sergio Gomes
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-05-24 00:00:00 +04:00
18
+ date: 2011-06-09 00:00:00 +04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -105,9 +105,9 @@ files:
105
105
  - lib/ads_common/credential_handler.rb
106
106
  - lib/ads_common/errors.rb
107
107
  - lib/ads_common/http.rb
108
- - lib/ads_common/logger.rb
109
108
  - lib/ads_common/savon_service.rb
110
109
  - lib/ads_common/soap4r_patches.rb
110
+ - lib/ads_common/soap4r_logger.rb
111
111
  - README
112
112
  - ChangeLog
113
113
  - COPYING
@@ -1,68 +0,0 @@
1
- #!/usr/bin/ruby
2
- #
3
- # Author:: 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
- # Wrapper class to handle logging to console and/or files.
21
-
22
- require 'logger'
23
-
24
- module AdsCommon
25
-
26
- # Wrapper class to handle logging to console and/or files.
27
- class Logger
28
-
29
- # Constructor for AdsLogger.
30
- #
31
- # Args:
32
- # - filename: the filename for the log file to be written (if log_to_file is
33
- # called)
34
- # - log_to_console: boolean, indicates whether or not to log to the console
35
- #
36
- def initialize(filename, log_to_console=false)
37
- @filename = filename
38
- @loggers = []
39
- if log_to_console
40
- stderr_logger = ::Logger.new(STDERR)
41
- stderr_logger.level = ::Logger::INFO
42
- @loggers << stderr_logger
43
- end
44
- end
45
-
46
- # Enables logging to a file.
47
- # May be called several times to log to multiple files.
48
- #
49
- # Args:
50
- # - path: where to write the file (defaults to current dir). Path only, do
51
- # not provide filename.
52
- #
53
- def log_to_file(path='.')
54
- new_logger = ::Logger.new(File.join(path, @filename))
55
- new_logger.level = ::Logger::INFO
56
- @loggers << new_logger
57
-
58
- return nil
59
- end
60
-
61
- # Overload << operator to perform logging.
62
- def << (text)
63
- @loggers.each do |logger|
64
- logger.info text.to_s
65
- end
66
- end
67
- end
68
- end