Merge branch 'master' of https://github.com/google/google-api-ruby-client into new_pr...
[arvados.git] / lib / google / api_client / service.rb
1 # Copyright 2013 Google Inc.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 require 'google/api_client'
16 require 'google/api_client/service/stub_generator'
17 require 'google/api_client/service/resource'
18 require 'google/api_client/service/request'
19 require 'google/api_client/service/result'
20
21 module Google
22   class APIClient
23
24     ##
25     # Experimental new programming interface at the API level.
26     # Hides Google::APIClient. Designed to be easier to use, with less code.
27     #
28     # @example
29     #   calendar = Google::APIClient::Service.new('calendar', 'v3')
30     #   result = calendar.events.list('calendarId' => 'primary').execute()
31     class Service
32       include Google::APIClient::Service::StubGenerator
33       extend Forwardable
34
35       # Cache for discovered APIs.
36       @@discovered = {}
37
38       ##
39       # Creates a new Service.
40       #
41       # @param [String, Symbol] api_name
42       #   The name of the API this service will access.
43       # @param [String, Symbol] api_version
44       #   The version of the API this service will access.
45       # @param [Hash] options
46       #   The configuration parameters for the service.
47       # @option options [Symbol, #generate_authenticated_request] :authorization
48       #   (:oauth_1)
49       #   The authorization mechanism used by the client.  The following
50       #   mechanisms are supported out-of-the-box:
51       #   <ul>
52       #     <li><code>:two_legged_oauth_1</code></li>
53       #     <li><code>:oauth_1</code></li>
54       #     <li><code>:oauth_2</code></li>
55       #   </ul>
56       # @option options [Boolean] :auto_refresh_token (true)
57       #   The setting that controls whether or not the api client attempts to
58       #   refresh authorization when a 401 is hit in #execute. If the token does
59       #   not support it, this option is ignored.
60       # @option options [String] :application_name
61       #   The name of the application using the client.
62       # @option options [String] :application_version
63       #   The version number of the application using the client.
64       # @option options [String] :host ("www.googleapis.com")
65       #   The API hostname used by the client. This rarely needs to be changed.
66       # @option options [String] :port (443)
67       #   The port number used by the client. This rarely needs to be changed.
68       # @option options [String] :discovery_path ("/discovery/v1")
69       #   The discovery base path. This rarely needs to be changed.
70       # @option options [String] :ca_file
71       #   Optional set of root certificates to use when validating SSL connections.
72       #   By default, a bundled set of trusted roots will be used.
73       # @option options [#generate_authenticated_request] :authorization
74       #   The authorization mechanism for requests. Used only if
75       #   `:authenticated` is `true`.
76       # @option options [TrueClass, FalseClass] :authenticated (default: true)
77       #   `true` if requests must be signed or somehow
78       #   authenticated, `false` otherwise.
79       # @option options [TrueClass, FalseClass] :gzip (default: true)
80       #   `true` if gzip enabled, `false` otherwise.
81       # @option options [Faraday::Connection] :connection
82       #   A custom connection to be used for all requests.
83       def initialize(api_name, api_version, options = {})
84         @api_name = api_name.to_s
85         if api_version.nil?
86           raise ArgumentError,
87             "API version must be set"
88         end
89         @api_version = api_version.to_s
90         if options && !options.respond_to?(:to_hash)
91           raise ArgumentError,
92             "expected options Hash, got #{options.class}"
93         end
94
95         params = {}
96         [:application_name, :application_version, :authorization, :host, :port,
97          :discovery_path, :auto_refresh_token, :key, :user_ip,
98          :ca_file].each do |option|
99           if options.include? option
100             params[option] = options[option]
101           end
102         end
103
104         @client = Google::APIClient.new(params)
105         @client.logger = options[:logger] if options.include? :logger
106
107         @connection = options[:connection] || @client.connection
108
109         @options = options
110
111         # Cache discovered APIs in memory.
112         # Not thread-safe, but the worst that can happen is a cache miss.
113         unless @api = @@discovered[[api_name, api_version]]
114           @@discovered[[api_name, api_version]] = @api = @client.discovered_api(
115             api_name, api_version)
116         end
117
118         generate_call_stubs(self, @api)
119       end
120
121       ##
122       # Logger for the Service.
123       #
124       # @return [Logger]
125       #  The logger instance.
126       def_delegators :@client, :logger, :logger=
127
128       ##
129       # Returns the authorization mechanism used by the service.
130       #
131       # @return [#generate_authenticated_request] The authorization mechanism.
132       def_delegators :@client, :authorization, :authorization=
133
134       ##
135       # The setting that controls whether or not the service attempts to
136       # refresh authorization when a 401 is hit during an API call.
137       #
138       # @return [Boolean]
139       def_delegators :@client, :auto_refresh_token, :auto_refresh_token=
140
141       ##
142       # The application's API key issued by the API console.
143       #
144       # @return [String] The API key.
145       def_delegators :@client, :key, :key=
146
147       ##
148       # The Faraday/HTTP connection used by this service.
149       #
150       # @return [Faraday::Connection]
151       attr_accessor :connection
152
153       ##
154       # Executes an API request.
155       # Do not call directly; this method is only used by Request objects when
156       # executing.
157       #
158       # @param [Google::APIClient::Service::Request] request
159       #   The request to be executed.
160       def execute(request)
161         params = {:api_method => request.method,
162           :parameters => request.parameters,
163           :connection => @connection}
164         if request.respond_to? :body
165           if request.body.respond_to? :to_hash
166             params[:body_object] = request.body
167           else
168             params[:body] = request.body
169           end
170         end
171         if request.respond_to? :media
172           params[:media] = request.media
173         end
174         [:authenticated, :gzip].each do |option|
175           if @options.include? option
176             params[option] = @options[option]
177           end
178         end
179         result = @client.execute(params)
180         return Google::APIClient::Service::Result.new(request, result)
181       end
182     end
183   end
184 end