2013-09-10 14:29:36 +00:00
|
|
|
# Copyright 2013 Google Inc.
|
|
|
|
#
|
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
# you may not use this file except in compliance with the License.
|
|
|
|
# You may obtain a copy of the License at
|
|
|
|
#
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
#
|
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
# See the License for the specific language governing permissions and
|
|
|
|
# limitations under the License.
|
|
|
|
|
|
|
|
require 'google/api_client'
|
|
|
|
require 'google/api_client/service/stub_generator'
|
|
|
|
require 'google/api_client/service/resource'
|
|
|
|
require 'google/api_client/service/request'
|
|
|
|
require 'google/api_client/service/result'
|
2013-10-04 14:56:06 +00:00
|
|
|
require 'google/api_client/service/batch'
|
2013-10-29 12:59:52 +00:00
|
|
|
require 'google/api_client/service/simple_file_store'
|
2013-09-10 14:29:36 +00:00
|
|
|
|
|
|
|
module Google
|
|
|
|
class APIClient
|
|
|
|
|
|
|
|
##
|
|
|
|
# Experimental new programming interface at the API level.
|
|
|
|
# Hides Google::APIClient. Designed to be easier to use, with less code.
|
|
|
|
#
|
|
|
|
# @example
|
|
|
|
# calendar = Google::APIClient::Service.new('calendar', 'v3')
|
|
|
|
# result = calendar.events.list('calendarId' => 'primary').execute()
|
|
|
|
class Service
|
|
|
|
include Google::APIClient::Service::StubGenerator
|
2013-09-11 15:51:10 +00:00
|
|
|
extend Forwardable
|
2013-09-10 14:29:36 +00:00
|
|
|
|
2013-10-29 12:59:52 +00:00
|
|
|
DEFAULT_CACHE_FILE = 'discovery.cache'
|
|
|
|
|
2013-09-11 15:51:10 +00:00
|
|
|
# Cache for discovered APIs.
|
|
|
|
@@discovered = {}
|
|
|
|
|
|
|
|
##
|
|
|
|
# Creates a new Service.
|
|
|
|
#
|
|
|
|
# @param [String, Symbol] api_name
|
|
|
|
# The name of the API this service will access.
|
|
|
|
# @param [String, Symbol] api_version
|
|
|
|
# The version of the API this service will access.
|
|
|
|
# @param [Hash] options
|
|
|
|
# The configuration parameters for the service.
|
|
|
|
# @option options [Symbol, #generate_authenticated_request] :authorization
|
|
|
|
# (:oauth_1)
|
|
|
|
# The authorization mechanism used by the client. The following
|
|
|
|
# mechanisms are supported out-of-the-box:
|
|
|
|
# <ul>
|
|
|
|
# <li><code>:two_legged_oauth_1</code></li>
|
|
|
|
# <li><code>:oauth_1</code></li>
|
|
|
|
# <li><code>:oauth_2</code></li>
|
|
|
|
# </ul>
|
|
|
|
# @option options [Boolean] :auto_refresh_token (true)
|
|
|
|
# The setting that controls whether or not the api client attempts to
|
|
|
|
# refresh authorization when a 401 is hit in #execute. If the token does
|
|
|
|
# not support it, this option is ignored.
|
|
|
|
# @option options [String] :application_name
|
|
|
|
# The name of the application using the client.
|
|
|
|
# @option options [String] :application_version
|
|
|
|
# The version number of the application using the client.
|
|
|
|
# @option options [String] :host ("www.googleapis.com")
|
|
|
|
# The API hostname used by the client. This rarely needs to be changed.
|
|
|
|
# @option options [String] :port (443)
|
|
|
|
# The port number used by the client. This rarely needs to be changed.
|
|
|
|
# @option options [String] :discovery_path ("/discovery/v1")
|
|
|
|
# The discovery base path. This rarely needs to be changed.
|
|
|
|
# @option options [String] :ca_file
|
|
|
|
# Optional set of root certificates to use when validating SSL connections.
|
|
|
|
# By default, a bundled set of trusted roots will be used.
|
|
|
|
# @option options [#generate_authenticated_request] :authorization
|
|
|
|
# The authorization mechanism for requests. Used only if
|
|
|
|
# `:authenticated` is `true`.
|
|
|
|
# @option options [TrueClass, FalseClass] :authenticated (default: true)
|
|
|
|
# `true` if requests must be signed or somehow
|
|
|
|
# authenticated, `false` otherwise.
|
|
|
|
# @option options [TrueClass, FalseClass] :gzip (default: true)
|
|
|
|
# `true` if gzip enabled, `false` otherwise.
|
|
|
|
# @option options [Faraday::Connection] :connection
|
|
|
|
# A custom connection to be used for all requests.
|
2013-10-29 12:59:52 +00:00
|
|
|
# @option options [ActiveSupport::Cache::Store, :default] :discovery_cache
|
|
|
|
# A cache store to place the discovery documents for loaded APIs.
|
|
|
|
# Avoids unnecessary roundtrips to the discovery service.
|
|
|
|
# :default loads the default local file cache store.
|
2013-09-10 14:29:36 +00:00
|
|
|
def initialize(api_name, api_version, options = {})
|
|
|
|
@api_name = api_name.to_s
|
|
|
|
if api_version.nil?
|
|
|
|
raise ArgumentError,
|
|
|
|
"API version must be set"
|
|
|
|
end
|
|
|
|
@api_version = api_version.to_s
|
|
|
|
if options && !options.respond_to?(:to_hash)
|
|
|
|
raise ArgumentError,
|
|
|
|
"expected options Hash, got #{options.class}"
|
|
|
|
end
|
|
|
|
|
|
|
|
params = {}
|
|
|
|
[:application_name, :application_version, :authorization, :host, :port,
|
|
|
|
:discovery_path, :auto_refresh_token, :key, :user_ip,
|
|
|
|
:ca_file].each do |option|
|
|
|
|
if options.include? option
|
|
|
|
params[option] = options[option]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
@client = Google::APIClient.new(params)
|
2013-09-11 15:51:10 +00:00
|
|
|
|
|
|
|
@connection = options[:connection] || @client.connection
|
2013-09-10 14:29:36 +00:00
|
|
|
|
|
|
|
@options = options
|
2013-09-11 15:51:10 +00:00
|
|
|
|
2013-10-29 12:59:52 +00:00
|
|
|
# Initialize cache store. Default to SimpleFileStore if :cache_store
|
|
|
|
# is not provided and we have write permissions.
|
|
|
|
if options.include? :cache_store
|
|
|
|
@cache_store = options[:cache_store]
|
|
|
|
else
|
2014-09-17 14:55:52 +00:00
|
|
|
cache_exists = File.exists?(DEFAULT_CACHE_FILE)
|
2013-10-29 12:59:52 +00:00
|
|
|
if (cache_exists && File.writable?(DEFAULT_CACHE_FILE)) ||
|
|
|
|
(!cache_exists && File.writable?(Dir.pwd))
|
|
|
|
@cache_store = Google::APIClient::Service::SimpleFileStore.new(
|
|
|
|
DEFAULT_CACHE_FILE)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# Attempt to read API definition from memory cache.
|
2013-09-11 15:51:10 +00:00
|
|
|
# Not thread-safe, but the worst that can happen is a cache miss.
|
|
|
|
unless @api = @@discovered[[api_name, api_version]]
|
2013-10-29 12:59:52 +00:00
|
|
|
# Attempt to read API definition from cache store, if there is one.
|
|
|
|
# If there's a miss or no cache store, call discovery service.
|
|
|
|
if !@cache_store.nil?
|
|
|
|
@api = @cache_store.fetch("%s/%s" % [api_name, api_version]) do
|
|
|
|
@client.discovered_api(api_name, api_version)
|
|
|
|
end
|
|
|
|
else
|
|
|
|
@api = @client.discovered_api(api_name, api_version)
|
|
|
|
end
|
|
|
|
@@discovered[[api_name, api_version]] = @api
|
2013-09-11 15:51:10 +00:00
|
|
|
end
|
|
|
|
|
2013-09-10 14:29:36 +00:00
|
|
|
generate_call_stubs(self, @api)
|
|
|
|
end
|
|
|
|
|
|
|
|
##
|
2013-09-11 15:51:10 +00:00
|
|
|
# Returns the authorization mechanism used by the service.
|
|
|
|
#
|
|
|
|
# @return [#generate_authenticated_request] The authorization mechanism.
|
|
|
|
def_delegators :@client, :authorization, :authorization=
|
|
|
|
|
|
|
|
##
|
|
|
|
# The setting that controls whether or not the service attempts to
|
|
|
|
# refresh authorization when a 401 is hit during an API call.
|
|
|
|
#
|
|
|
|
# @return [Boolean]
|
|
|
|
def_delegators :@client, :auto_refresh_token, :auto_refresh_token=
|
|
|
|
|
|
|
|
##
|
|
|
|
# The application's API key issued by the API console.
|
|
|
|
#
|
|
|
|
# @return [String] The API key.
|
|
|
|
def_delegators :@client, :key, :key=
|
|
|
|
|
|
|
|
##
|
|
|
|
# The Faraday/HTTP connection used by this service.
|
|
|
|
#
|
|
|
|
# @return [Faraday::Connection]
|
|
|
|
attr_accessor :connection
|
2013-09-10 14:29:36 +00:00
|
|
|
|
2013-10-29 12:59:52 +00:00
|
|
|
##
|
|
|
|
# The cache store used for storing discovery documents.
|
|
|
|
#
|
|
|
|
# @return [ActiveSupport::Cache::Store,
|
|
|
|
# Google::APIClient::Service::SimpleFileStore,
|
|
|
|
# nil]
|
|
|
|
attr_reader :cache_store
|
|
|
|
|
2013-10-04 14:56:06 +00:00
|
|
|
##
|
|
|
|
# Prepares a Google::APIClient::BatchRequest object to make batched calls.
|
|
|
|
# @param [Array] calls
|
|
|
|
# Optional array of Google::APIClient::Service::Request to initialize
|
|
|
|
# the batch request with.
|
|
|
|
# @param [Proc] block
|
|
|
|
# Callback for every call's response. Won't be called if a call defined
|
|
|
|
# a callback of its own.
|
|
|
|
#
|
|
|
|
# @yield [Google::APIClient::Service::Result]
|
|
|
|
# block to be called when result ready
|
|
|
|
def batch(calls = nil, &block)
|
|
|
|
Google::APIClient::Service::BatchRequest.new(self, calls, &block)
|
|
|
|
end
|
|
|
|
|
2013-09-10 14:29:36 +00:00
|
|
|
##
|
|
|
|
# Executes an API request.
|
|
|
|
# Do not call directly; this method is only used by Request objects when
|
|
|
|
# executing.
|
2013-09-11 15:51:10 +00:00
|
|
|
#
|
2013-10-04 14:56:06 +00:00
|
|
|
# @param [Google::APIClient::Service::Request,
|
|
|
|
# Google::APIClient::Service::BatchCall] request
|
2013-09-10 14:29:36 +00:00
|
|
|
# The request to be executed.
|
|
|
|
def execute(request)
|
2013-10-04 14:56:06 +00:00
|
|
|
if request.instance_of? Google::APIClient::Service::Request
|
|
|
|
params = {:api_method => request.method,
|
|
|
|
:parameters => request.parameters,
|
|
|
|
:connection => @connection}
|
|
|
|
if request.respond_to? :body
|
|
|
|
if request.body.respond_to? :to_hash
|
|
|
|
params[:body_object] = request.body
|
|
|
|
else
|
|
|
|
params[:body] = request.body
|
|
|
|
end
|
2013-09-10 14:29:36 +00:00
|
|
|
end
|
2013-10-04 14:56:06 +00:00
|
|
|
if request.respond_to? :media
|
|
|
|
params[:media] = request.media
|
|
|
|
end
|
|
|
|
[:authenticated, :gzip].each do |option|
|
|
|
|
if @options.include? option
|
|
|
|
params[option] = @options[option]
|
|
|
|
end
|
2013-09-10 14:29:36 +00:00
|
|
|
end
|
2013-10-04 14:56:06 +00:00
|
|
|
result = @client.execute(params)
|
|
|
|
return Google::APIClient::Service::Result.new(request, result)
|
|
|
|
elsif request.instance_of? Google::APIClient::Service::BatchRequest
|
2014-12-17 04:52:57 +00:00
|
|
|
@client.execute(request.base_batch, {:connection => @connection})
|
2013-09-10 14:29:36 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|