diff --git a/lib/google/api_client.rb b/lib/google/api_client.rb
index 378c56025..d2c1bb584 100644
--- a/lib/google/api_client.rb
+++ b/lib/google/api_client.rb
@@ -132,29 +132,44 @@ module Google #:nodoc:
return nil
end
- def build_request(*args, &block)
- if !args.empty? || block
- if args.size != 2
- raise ArgumentError, "wrong number of arguments (#{args.size} for 2)"
+ def discovered_method(rpc_name, service_version='1.0')
+ for service in self.discovered_services
+ # This looks kinda weird, but is not a real problem because there's
+ # almost always only one service, and this is memoized anyhow.
+ if service.version.to_s == service_version.to_s
+ return service.to_h[rpc_name] if service.to_h[rpc_name]
end
- rpc_name = args[0]
- if !rpc_name.kind_of?(String)
- raise TypeError, "Expected String, got #{rpc_name.class}."
- end
- parameters = args[1]
- if !parameters.kind_of?(Hash)
- raise TypeError, "Expected Hash, got #{parameters.class}."
- end
-
- signature_needed = false
- if signature_needed
- request = self.sign_request(request)
- end
- return args
- else
- require 'google/api_client/discovery/method_builder'
- return ::Google::APIClient::MethodBuilder.new(self, :build_request)
end
+ return nil
+ end
+
+ def generate_request(
+ api_method, parameters={}, body='', headers=[], options={})
+ options={
+ :signed => true,
+ :service_version => '1.0'
+ }.merge(options)
+ if api_method.kind_of?(String)
+ api_method = self.discovered_method(
+ api_method, options[:service_version]
+ )
+ elsif !api_method.kind_of?(::Google::APIClient::Service)
+ raise TypeError,
+ "Expected String or Google::APIClient::Service, " +
+ "got #{api_method.class}."
+ end
+ request = api_method.generate_request(parameters, body, headers)
+ if options[:signed]
+ request = self.sign_request(request)
+ end
+ return request
+ end
+
+ def execute(api_method, parameters={}, body='', headers=[], options={})
+ request = self.generate_request(
+ api_method, parameters, body, headers, options
+ )
+ return self.transmit_request(request)
end
def transmit_request(request)
@@ -172,10 +187,6 @@ module Google #:nodoc:
'#generate_authenticated_request.'
end
end
-
- def execute_signed_request(*args, &block)
- return self.transmit_request(self.build_request(*args, &block))
- end
end
end
diff --git a/lib/google/api_client/discovery/service.rb b/lib/google/api_client/discovery/service.rb
index 0db554fb4..3f89b3688 100644
--- a/lib/google/api_client/discovery/service.rb
+++ b/lib/google/api_client/discovery/service.rb
@@ -66,6 +66,19 @@ module Google #:nodoc:
)
end
+ def to_h
+ return @hash ||= (begin
+ methods_hash = {}
+ self.methods.each do |method|
+ methods_hash[method.rpc_name] = method
+ end
+ self.resources.each do |resource|
+ methods_hash.merge!(resource.to_h)
+ end
+ methods_hash
+ end)
+ end
+
##
# Returns a String
representation of the service's state.
#
@@ -117,6 +130,19 @@ module Google #:nodoc:
)
end
+ def to_h
+ return @hash ||= (begin
+ methods_hash = {}
+ self.methods.each do |method|
+ methods_hash[method.rpc_name] = method
+ end
+ self.resources.each do |resource|
+ methods_hash.merge!(resource.to_h)
+ end
+ methods_hash
+ end)
+ end
+
##
# Returns a String
representation of the resource's state.
#
@@ -137,27 +163,38 @@ module Google #:nodoc:
attr_reader :name, :description, :base
+ def rpc_name
+ return self.description['rpcName']
+ end
+
def uri_template
- return Addressable::Template.new(base + self.description['pathUrl'])
+ return @uri_template ||=
+ Addressable::Template.new(base + self.description['pathUrl'])
+ end
+
+ def normalize_parameters(parameters={})
+ # Convert keys to Strings when appropriate
+ if parameters.kind_of?(Hash) || parameters.kind_of?(Array)
+ parameters = parameters.inject({}) do |accu, (k, v)|
+ k = k.to_s if k.kind_of?(Symbol)
+ k = k.to_str if k.respond_to?(:to_str)
+ unless k.kind_of?(String)
+ raise TypeError, "Expected String, got #{k.class}."
+ end
+ accu[k] = v
+ accu
+ end
+ else
+ raise TypeError,
+ "Expected Hash or Array, got #{parameters.class}."
+ end
+ return parameters
end
def generate_uri(parameters={})
- # Convert keys to Strings when appropriate
- parameters = parameters.inject({}) do |accu, (k, v)|
- k = k.to_s if k.kind_of?(Symbol)
- k = k.to_str if k.respond_to?(:to_str)
- unless k.kind_of?(String)
- raise TypeError, "Expected String, got #{k.class}."
- end
- accu[k] = v
- accu
- end
+ parameters = self.normalize_parameters(parameters)
+ self.validate_parameters(parameters)
template_variables = self.uri_template.variables
- missing_variables = template_variables - parameters.keys
- if missing_variables.size > 0
- raise ArgumentError,
- "Missing required parameters: #{missing_variables.join(', ')}."
- end
uri = self.uri_template.expand(parameters)
query_parameters = parameters.reject do |k, v|
template_variables.include?(k)
@@ -170,13 +207,46 @@ module Google #:nodoc:
return uri.normalize
end
+ def generate_request(parameters={}, body='', headers=[])
+ method = self.description['httpMethod'] || 'GET'
+ uri = self.generate_uri(parameters)
+ return [method, uri.to_str, headers, [body]]
+ end
+
+ def validate_parameters(parameters={})
+ parameters = self.normalize_parameters(parameters)
+ parameter_description = self.description['parameters'] || {}
+ required_variables = Hash[parameter_description.select do |k, v|
+ v['required']
+ end].keys
+ missing_variables = required_variables - parameters.keys
+ if missing_variables.size > 0
+ raise ArgumentError,
+ "Missing required parameters: #{missing_variables.join(', ')}."
+ end
+ parameters.each do |k, v|
+ if parameter_description[k]
+ pattern = parameter_description[k]['pattern']
+ if pattern
+ regexp = Regexp.new("^#{pattern}$")
+ if v !~ regexp
+ raise ArgumentError,
+ "Parameter '#{k}' has an invalid value: #{v}. " +
+ "Must match: /^#{pattern}$/."
+ end
+ end
+ end
+ end
+ return nil
+ end
+
##
# Returns a String
representation of the method's state.
#
# @return [String] The method's state, as a String
.
def inspect
sprintf(
- "#<%s:%#0x NAME:%s>", self.class.to_s, self.object_id, self.name
+ "#<%s:%#0x NAME:%s>", self.class.to_s, self.object_id, self.rpc_name
)
end
end