google-ads-common 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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