jomz-google-api-client 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/CHANGELOG.md +144 -0
  2. data/CONTRIBUTING.md +32 -0
  3. data/Gemfile +41 -0
  4. data/LICENSE +202 -0
  5. data/README.md +192 -0
  6. data/Rakefile +46 -0
  7. data/lib/cacerts.pem +2183 -0
  8. data/lib/compat/multi_json.rb +16 -0
  9. data/lib/google/api_client.rb +672 -0
  10. data/lib/google/api_client/auth/compute_service_account.rb +28 -0
  11. data/lib/google/api_client/auth/file_storage.rb +87 -0
  12. data/lib/google/api_client/auth/installed_app.rb +122 -0
  13. data/lib/google/api_client/auth/jwt_asserter.rb +126 -0
  14. data/lib/google/api_client/auth/key_utils.rb +93 -0
  15. data/lib/google/api_client/auth/pkcs12.rb +41 -0
  16. data/lib/google/api_client/batch.rb +323 -0
  17. data/lib/google/api_client/client_secrets.rb +176 -0
  18. data/lib/google/api_client/discovery.rb +19 -0
  19. data/lib/google/api_client/discovery/api.rb +300 -0
  20. data/lib/google/api_client/discovery/media.rb +77 -0
  21. data/lib/google/api_client/discovery/method.rb +363 -0
  22. data/lib/google/api_client/discovery/resource.rb +156 -0
  23. data/lib/google/api_client/discovery/schema.rb +121 -0
  24. data/lib/google/api_client/environment.rb +42 -0
  25. data/lib/google/api_client/errors.rb +60 -0
  26. data/lib/google/api_client/gzip.rb +28 -0
  27. data/lib/google/api_client/logging.rb +32 -0
  28. data/lib/google/api_client/media.rb +259 -0
  29. data/lib/google/api_client/railtie.rb +16 -0
  30. data/lib/google/api_client/reference.rb +27 -0
  31. data/lib/google/api_client/request.rb +351 -0
  32. data/lib/google/api_client/result.rb +253 -0
  33. data/lib/google/api_client/service.rb +233 -0
  34. data/lib/google/api_client/service/batch.rb +103 -0
  35. data/lib/google/api_client/service/request.rb +144 -0
  36. data/lib/google/api_client/service/resource.rb +40 -0
  37. data/lib/google/api_client/service/result.rb +162 -0
  38. data/lib/google/api_client/service/simple_file_store.rb +151 -0
  39. data/lib/google/api_client/service/stub_generator.rb +59 -0
  40. data/lib/google/api_client/service_account.rb +18 -0
  41. data/lib/google/api_client/version.rb +31 -0
  42. data/lib/google/inflection.rb +28 -0
  43. data/spec/fixtures/files/privatekey.p12 +0 -0
  44. data/spec/fixtures/files/sample.txt +33 -0
  45. data/spec/fixtures/files/secret.pem +19 -0
  46. data/spec/google/api_client/batch_spec.rb +249 -0
  47. data/spec/google/api_client/discovery_spec.rb +652 -0
  48. data/spec/google/api_client/gzip_spec.rb +86 -0
  49. data/spec/google/api_client/media_spec.rb +179 -0
  50. data/spec/google/api_client/request_spec.rb +30 -0
  51. data/spec/google/api_client/result_spec.rb +203 -0
  52. data/spec/google/api_client/service_account_spec.rb +164 -0
  53. data/spec/google/api_client/service_spec.rb +586 -0
  54. data/spec/google/api_client/simple_file_store_spec.rb +137 -0
  55. data/spec/google/api_client_spec.rb +253 -0
  56. data/spec/spec_helper.rb +56 -0
  57. data/tasks/gem.rake +97 -0
  58. data/tasks/git.rake +45 -0
  59. data/tasks/metrics.rake +22 -0
  60. data/tasks/spec.rake +57 -0
  61. data/tasks/wiki.rake +82 -0
  62. data/tasks/yard.rake +29 -0
  63. metadata +309 -0
@@ -0,0 +1,19 @@
1
+ # Copyright 2010 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
+
16
+ require 'google/api_client/discovery/api'
17
+ require 'google/api_client/discovery/resource'
18
+ require 'google/api_client/discovery/method'
19
+ require 'google/api_client/discovery/schema'
@@ -0,0 +1,300 @@
1
+ # Copyright 2010 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
+
16
+ require 'addressable/uri'
17
+ require 'multi_json'
18
+ require 'google/inflection'
19
+ require 'google/api_client/discovery/resource'
20
+ require 'google/api_client/discovery/method'
21
+ require 'google/api_client/discovery/media'
22
+
23
+ module Google
24
+ class APIClient
25
+ ##
26
+ # A service that has been described by a discovery document.
27
+ class API
28
+
29
+ ##
30
+ # Creates a description of a particular version of a service.
31
+ #
32
+ # @param [String] document_base
33
+ # Base URI for the service
34
+ # @param [Hash] discovery_document
35
+ # The section of the discovery document that applies to this service
36
+ # version.
37
+ #
38
+ # @return [Google::APIClient::API] The constructed service object.
39
+ def initialize(document_base, discovery_document)
40
+ @document_base = Addressable::URI.parse(document_base)
41
+ @discovery_document = discovery_document
42
+ metaclass = (class << self; self; end)
43
+ self.discovered_resources.each do |resource|
44
+ method_name = Google::INFLECTOR.underscore(resource.name).to_sym
45
+ if !self.respond_to?(method_name)
46
+ metaclass.send(:define_method, method_name) { resource }
47
+ end
48
+ end
49
+ self.discovered_methods.each do |method|
50
+ method_name = Google::INFLECTOR.underscore(method.name).to_sym
51
+ if !self.respond_to?(method_name)
52
+ metaclass.send(:define_method, method_name) { method }
53
+ end
54
+ end
55
+ end
56
+
57
+ # @return [String] unparsed discovery document for the API
58
+ attr_reader :discovery_document
59
+
60
+ ##
61
+ # Returns the id of the service.
62
+ #
63
+ # @return [String] The service id.
64
+ def id
65
+ return (
66
+ @discovery_document['id'] ||
67
+ "#{self.name}:#{self.version}"
68
+ )
69
+ end
70
+
71
+ ##
72
+ # Returns the identifier for the service.
73
+ #
74
+ # @return [String] The service identifier.
75
+ def name
76
+ return @discovery_document['name']
77
+ end
78
+
79
+ ##
80
+ # Returns the version of the service.
81
+ #
82
+ # @return [String] The service version.
83
+ def version
84
+ return @discovery_document['version']
85
+ end
86
+
87
+ ##
88
+ # Returns a human-readable title for the API.
89
+ #
90
+ # @return [Hash] The API title.
91
+ def title
92
+ return @discovery_document['title']
93
+ end
94
+
95
+ ##
96
+ # Returns a human-readable description of the API.
97
+ #
98
+ # @return [Hash] The API description.
99
+ def description
100
+ return @discovery_document['description']
101
+ end
102
+
103
+ ##
104
+ # Returns a URI for the API documentation.
105
+ #
106
+ # @return [Hash] The API documentation.
107
+ def documentation
108
+ return Addressable::URI.parse(@discovery_document['documentationLink'])
109
+ end
110
+
111
+ ##
112
+ # Returns true if this is the preferred version of this API.
113
+ #
114
+ # @return [TrueClass, FalseClass]
115
+ # Whether or not this is the preferred version of this API.
116
+ def preferred
117
+ return !!@discovery_document['preferred']
118
+ end
119
+
120
+ ##
121
+ # Returns the list of API features.
122
+ #
123
+ # @return [Array]
124
+ # The features supported by this API.
125
+ def features
126
+ return @discovery_document['features'] || []
127
+ end
128
+
129
+ ##
130
+ # Returns true if this API uses a data wrapper.
131
+ #
132
+ # @return [TrueClass, FalseClass]
133
+ # Whether or not this API uses a data wrapper.
134
+ def data_wrapper?
135
+ return self.features.include?('dataWrapper')
136
+ end
137
+
138
+ ##
139
+ # Returns the base URI for the discovery document.
140
+ #
141
+ # @return [Addressable::URI] The base URI.
142
+ attr_reader :document_base
143
+
144
+ ##
145
+ # Returns the base URI for this version of the service.
146
+ #
147
+ # @return [Addressable::URI] The base URI that methods are joined to.
148
+ def method_base
149
+ if @discovery_document['basePath']
150
+ return @method_base ||= (
151
+ self.document_base.join(Addressable::URI.parse(@discovery_document['basePath']))
152
+ ).normalize
153
+ else
154
+ return nil
155
+ end
156
+ end
157
+
158
+ ##
159
+ # Updates the hierarchy of resources and methods with the new base.
160
+ #
161
+ # @param [Addressable::URI, #to_str, String] new_method_base
162
+ # The new base URI to use for the service.
163
+ def method_base=(new_method_base)
164
+ @method_base = Addressable::URI.parse(new_method_base)
165
+ self.discovered_resources.each do |resource|
166
+ resource.method_base = @method_base
167
+ end
168
+ self.discovered_methods.each do |method|
169
+ method.method_base = @method_base
170
+ end
171
+ end
172
+
173
+ ##
174
+ # Returns the base URI for batch calls to this service.
175
+ #
176
+ # @return [Addressable::URI] The base URI that methods are joined to.
177
+ def batch_path
178
+ if @discovery_document['batchPath']
179
+ return @batch_path ||= (
180
+ self.document_base.join(Addressable::URI.parse('/' +
181
+ @discovery_document['batchPath']))
182
+ ).normalize
183
+ else
184
+ return nil
185
+ end
186
+ end
187
+
188
+ ##
189
+ # A list of schemas available for this version of the API.
190
+ #
191
+ # @return [Hash] A list of {Google::APIClient::Schema} objects.
192
+ def schemas
193
+ return @schemas ||= (
194
+ (@discovery_document['schemas'] || []).inject({}) do |accu, (k, v)|
195
+ accu[k] = Google::APIClient::Schema.parse(self, v)
196
+ accu
197
+ end
198
+ )
199
+ end
200
+
201
+ ##
202
+ # Returns a schema for a kind value.
203
+ #
204
+ # @return [Google::APIClient::Schema] The associated Schema object.
205
+ def schema_for_kind(kind)
206
+ api_name, schema_name = kind.split('#', 2)
207
+ if api_name != self.name
208
+ raise ArgumentError,
209
+ "The kind does not match this API. " +
210
+ "Expected '#{self.name}', got '#{api_name}'."
211
+ end
212
+ for k, v in self.schemas
213
+ return v if k.downcase == schema_name.downcase
214
+ end
215
+ return nil
216
+ end
217
+
218
+ ##
219
+ # A list of resources available at the root level of this version of the
220
+ # API.
221
+ #
222
+ # @return [Array] A list of {Google::APIClient::Resource} objects.
223
+ def discovered_resources
224
+ return @discovered_resources ||= (
225
+ (@discovery_document['resources'] || []).inject([]) do |accu, (k, v)|
226
+ accu << Google::APIClient::Resource.new(
227
+ self, self.method_base, k, v
228
+ )
229
+ accu
230
+ end
231
+ )
232
+ end
233
+
234
+ ##
235
+ # A list of methods available at the root level of this version of the
236
+ # API.
237
+ #
238
+ # @return [Array] A list of {Google::APIClient::Method} objects.
239
+ def discovered_methods
240
+ return @discovered_methods ||= (
241
+ (@discovery_document['methods'] || []).inject([]) do |accu, (k, v)|
242
+ accu << Google::APIClient::Method.new(self, self.method_base, k, v)
243
+ accu
244
+ end
245
+ )
246
+ end
247
+
248
+ ##
249
+ # Allows deep inspection of the discovery document.
250
+ def [](key)
251
+ return @discovery_document[key]
252
+ end
253
+
254
+ ##
255
+ # Converts the service to a flat mapping of RPC names and method objects.
256
+ #
257
+ # @return [Hash] All methods available on the service.
258
+ #
259
+ # @example
260
+ # # Discover available methods
261
+ # method_names = client.discovered_api('buzz').to_h.keys
262
+ def to_h
263
+ return @hash ||= (begin
264
+ methods_hash = {}
265
+ self.discovered_methods.each do |method|
266
+ methods_hash[method.id] = method
267
+ end
268
+ self.discovered_resources.each do |resource|
269
+ methods_hash.merge!(resource.to_h)
270
+ end
271
+ methods_hash
272
+ end)
273
+ end
274
+
275
+ ##
276
+ # Returns a <code>String</code> representation of the service's state.
277
+ #
278
+ # @return [String] The service's state, as a <code>String</code>.
279
+ def inspect
280
+ sprintf(
281
+ "#<%s:%#0x ID:%s>", self.class.to_s, self.object_id, self.id
282
+ )
283
+ end
284
+
285
+ ##
286
+ # Marshalling support - serialize the API to a string (doc base + original
287
+ # discovery document).
288
+ def _dump(level)
289
+ MultiJson.dump([@document_base.to_s, @discovery_document])
290
+ end
291
+
292
+ ##
293
+ # Marshalling support - Restore an API instance from serialized form
294
+ def self._load(obj)
295
+ new(*MultiJson.load(obj))
296
+ end
297
+
298
+ end
299
+ end
300
+ end
@@ -0,0 +1,77 @@
1
+ # Copyright 2010 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
+
16
+ require 'addressable/uri'
17
+ require 'addressable/template'
18
+
19
+ require 'google/api_client/errors'
20
+
21
+
22
+ module Google
23
+ class APIClient
24
+ ##
25
+ # Media upload elements for discovered methods
26
+ class MediaUpload
27
+
28
+ ##
29
+ # Creates a description of a particular method.
30
+ #
31
+ # @param [Google::APIClient::API] api
32
+ # Base discovery document for the API
33
+ # @param [Addressable::URI] method_base
34
+ # The base URI for the service.
35
+ # @param [Hash] discovery_document
36
+ # The media upload section of the discovery document.
37
+ #
38
+ # @return [Google::APIClient::Method] The constructed method object.
39
+ def initialize(api, method_base, discovery_document)
40
+ @api = api
41
+ @method_base = method_base
42
+ @discovery_document = discovery_document
43
+ end
44
+
45
+ ##
46
+ # List of acceptable mime types
47
+ #
48
+ # @return [Array]
49
+ # List of acceptable mime types for uploaded content
50
+ def accepted_types
51
+ @discovery_document['accept']
52
+ end
53
+
54
+ ##
55
+ # Maximum size of an uplad
56
+ # TODO: Parse & convert to numeric value
57
+ #
58
+ # @return [String]
59
+ def max_size
60
+ @discovery_document['maxSize']
61
+ end
62
+
63
+ ##
64
+ # Returns the URI template for the method. A parameter list can be
65
+ # used to expand this into a URI.
66
+ #
67
+ # @return [Addressable::Template] The URI template.
68
+ def uri_template
69
+ return @uri_template ||= Addressable::Template.new(
70
+ @api.method_base.join(Addressable::URI.parse(@discovery_document['protocols']['simple']['path']))
71
+ )
72
+ end
73
+
74
+ end
75
+
76
+ end
77
+ end
@@ -0,0 +1,363 @@
1
+ # Copyright 2010 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
+
16
+ require 'addressable/uri'
17
+ require 'addressable/template'
18
+
19
+ require 'google/api_client/errors'
20
+
21
+
22
+ module Google
23
+ class APIClient
24
+ ##
25
+ # A method that has been described by a discovery document.
26
+ class Method
27
+
28
+ ##
29
+ # Creates a description of a particular method.
30
+ #
31
+ # @param [Google::APIClient::API] api
32
+ # The API this method belongs to.
33
+ # @param [Addressable::URI] method_base
34
+ # The base URI for the service.
35
+ # @param [String] method_name
36
+ # The identifier for the method.
37
+ # @param [Hash] discovery_document
38
+ # The section of the discovery document that applies to this method.
39
+ #
40
+ # @return [Google::APIClient::Method] The constructed method object.
41
+ def initialize(api, method_base, method_name, discovery_document)
42
+ @api = api
43
+ @method_base = method_base
44
+ @name = method_name
45
+ @discovery_document = discovery_document
46
+ end
47
+
48
+ # @return [String] unparsed discovery document for the method
49
+ attr_reader :discovery_document
50
+
51
+ ##
52
+ # Returns the API this method belongs to.
53
+ #
54
+ # @return [Google::APIClient::API] The API this method belongs to.
55
+ attr_reader :api
56
+
57
+ ##
58
+ # Returns the identifier for the method.
59
+ #
60
+ # @return [String] The method identifier.
61
+ attr_reader :name
62
+
63
+ ##
64
+ # Returns the base URI for the method.
65
+ #
66
+ # @return [Addressable::URI]
67
+ # The base URI that this method will be joined to.
68
+ attr_reader :method_base
69
+
70
+ ##
71
+ # Updates the method with the new base.
72
+ #
73
+ # @param [Addressable::URI, #to_str, String] new_method_base
74
+ # The new base URI to use for the method.
75
+ def method_base=(new_method_base)
76
+ @method_base = Addressable::URI.parse(new_method_base)
77
+ @uri_template = nil
78
+ end
79
+
80
+ ##
81
+ # Returns a human-readable description of the method.
82
+ #
83
+ # @return [Hash] The API description.
84
+ def description
85
+ return @discovery_document['description']
86
+ end
87
+
88
+ ##
89
+ # Returns the method ID.
90
+ #
91
+ # @return [String] The method identifier.
92
+ def id
93
+ return @discovery_document['id']
94
+ end
95
+
96
+ ##
97
+ # Returns the HTTP method or 'GET' if none is specified.
98
+ #
99
+ # @return [String] The HTTP method that will be used in the request.
100
+ def http_method
101
+ return @discovery_document['httpMethod'] || 'GET'
102
+ end
103
+
104
+ ##
105
+ # Returns the URI template for the method. A parameter list can be
106
+ # used to expand this into a URI.
107
+ #
108
+ # @return [Addressable::Template] The URI template.
109
+ def uri_template
110
+ return @uri_template ||= Addressable::Template.new(
111
+ self.method_base.join(Addressable::URI.parse(@discovery_document['path']))
112
+ )
113
+ end
114
+
115
+ ##
116
+ # Returns media upload information for this method, if supported
117
+ #
118
+ # @return [Google::APIClient::MediaUpload] Description of upload endpoints
119
+ def media_upload
120
+ if @discovery_document['mediaUpload']
121
+ return @media_upload ||= Google::APIClient::MediaUpload.new(self, self.method_base, @discovery_document['mediaUpload'])
122
+ else
123
+ return nil
124
+ end
125
+ end
126
+
127
+ ##
128
+ # Returns the Schema object for the method's request, if any.
129
+ #
130
+ # @return [Google::APIClient::Schema] The request schema.
131
+ def request_schema
132
+ if @discovery_document['request']
133
+ schema_name = @discovery_document['request']['$ref']
134
+ return @api.schemas[schema_name]
135
+ else
136
+ return nil
137
+ end
138
+ end
139
+
140
+ ##
141
+ # Returns the Schema object for the method's response, if any.
142
+ #
143
+ # @return [Google::APIClient::Schema] The response schema.
144
+ def response_schema
145
+ if @discovery_document['response']
146
+ schema_name = @discovery_document['response']['$ref']
147
+ return @api.schemas[schema_name]
148
+ else
149
+ return nil
150
+ end
151
+ end
152
+
153
+ ##
154
+ # Normalizes parameters, converting to the appropriate types.
155
+ #
156
+ # @param [Hash, Array] parameters
157
+ # The parameters to normalize.
158
+ #
159
+ # @return [Hash] The normalized parameters.
160
+ def normalize_parameters(parameters={})
161
+ # Convert keys to Strings when appropriate
162
+ if parameters.kind_of?(Hash) || parameters.kind_of?(Array)
163
+ # Returning an array since parameters can be repeated (ie, Adsense Management API)
164
+ parameters = parameters.inject([]) do |accu, (k, v)|
165
+ k = k.to_s if k.kind_of?(Symbol)
166
+ k = k.to_str if k.respond_to?(:to_str)
167
+ unless k.kind_of?(String)
168
+ raise TypeError, "Expected String, got #{k.class}."
169
+ end
170
+ accu << [k, v]
171
+ accu
172
+ end
173
+ else
174
+ raise TypeError,
175
+ "Expected Hash or Array, got #{parameters.class}."
176
+ end
177
+ return parameters
178
+ end
179
+
180
+ ##
181
+ # Expands the method's URI template using a parameter list.
182
+ #
183
+ # @api private
184
+ # @param [Hash, Array] parameters
185
+ # The parameter list to use.
186
+ #
187
+ # @return [Addressable::URI] The URI after expansion.
188
+ def generate_uri(parameters={})
189
+ parameters = self.normalize_parameters(parameters)
190
+
191
+ self.validate_parameters(parameters)
192
+ template_variables = self.uri_template.variables
193
+ upload_type = parameters.assoc('uploadType') || parameters.assoc('upload_type')
194
+ if upload_type
195
+ unless self.media_upload
196
+ raise ArgumentException, "Media upload not supported for this method"
197
+ end
198
+ case upload_type.last
199
+ when 'media', 'multipart', 'resumable'
200
+ uri = self.media_upload.uri_template.expand(parameters)
201
+ else
202
+ raise ArgumentException, "Invalid uploadType '#{upload_type}'"
203
+ end
204
+ else
205
+ uri = self.uri_template.expand(parameters)
206
+ end
207
+ query_parameters = parameters.reject do |k, v|
208
+ template_variables.include?(k)
209
+ end
210
+ # encode all non-template parameters
211
+ params = ""
212
+ unless query_parameters.empty?
213
+ params = "?" + Addressable::URI.form_encode(query_parameters.sort)
214
+ end
215
+ # Normalization is necessary because of undesirable percent-escaping
216
+ # during URI template expansion
217
+ return uri.normalize + params
218
+ end
219
+
220
+ ##
221
+ # Generates an HTTP request for this method.
222
+ #
223
+ # @api private
224
+ # @param [Hash, Array] parameters
225
+ # The parameters to send.
226
+ # @param [String, StringIO] body The body for the HTTP request.
227
+ # @param [Hash, Array] headers The HTTP headers for the request.
228
+ # @option options [Faraday::Connection] :connection
229
+ # The HTTP connection to use.
230
+ #
231
+ # @return [Array] The generated HTTP request.
232
+ def generate_request(parameters={}, body='', headers={}, options={})
233
+ if !headers.kind_of?(Array) && !headers.kind_of?(Hash)
234
+ raise TypeError, "Expected Hash or Array, got #{headers.class}."
235
+ end
236
+ method = self.http_method.to_s.downcase.to_sym
237
+ uri = self.generate_uri(parameters)
238
+ headers = Faraday::Utils::Headers.new(headers)
239
+ return [method, uri, headers, body]
240
+ end
241
+
242
+
243
+ ##
244
+ # Returns a <code>Hash</code> of the parameter descriptions for
245
+ # this method.
246
+ #
247
+ # @return [Hash] The parameter descriptions.
248
+ def parameter_descriptions
249
+ @parameter_descriptions ||= (
250
+ @discovery_document['parameters'] || {}
251
+ ).inject({}) { |h,(k,v)| h[k]=v; h }
252
+ end
253
+
254
+ ##
255
+ # Returns an <code>Array</code> of the parameters for this method.
256
+ #
257
+ # @return [Array] The parameters.
258
+ def parameters
259
+ @parameters ||= ((
260
+ @discovery_document['parameters'] || {}
261
+ ).inject({}) { |h,(k,v)| h[k]=v; h }).keys
262
+ end
263
+
264
+ ##
265
+ # Returns an <code>Array</code> of the required parameters for this
266
+ # method.
267
+ #
268
+ # @return [Array] The required parameters.
269
+ #
270
+ # @example
271
+ # # A list of all required parameters.
272
+ # method.required_parameters
273
+ def required_parameters
274
+ @required_parameters ||= ((self.parameter_descriptions.select do |k, v|
275
+ v['required']
276
+ end).inject({}) { |h,(k,v)| h[k]=v; h }).keys
277
+ end
278
+
279
+ ##
280
+ # Returns an <code>Array</code> of the optional parameters for this
281
+ # method.
282
+ #
283
+ # @return [Array] The optional parameters.
284
+ #
285
+ # @example
286
+ # # A list of all optional parameters.
287
+ # method.optional_parameters
288
+ def optional_parameters
289
+ @optional_parameters ||= ((self.parameter_descriptions.reject do |k, v|
290
+ v['required']
291
+ end).inject({}) { |h,(k,v)| h[k]=v; h }).keys
292
+ end
293
+
294
+ ##
295
+ # Verifies that the parameters are valid for this method. Raises an
296
+ # exception if validation fails.
297
+ #
298
+ # @api private
299
+ # @param [Hash, Array] parameters
300
+ # The parameters to verify.
301
+ #
302
+ # @return [NilClass] <code>nil</code> if validation passes.
303
+ def validate_parameters(parameters={})
304
+ parameters = self.normalize_parameters(parameters)
305
+ required_variables = ((self.parameter_descriptions.select do |k, v|
306
+ v['required']
307
+ end).inject({}) { |h,(k,v)| h[k]=v; h }).keys
308
+ missing_variables = required_variables - parameters.map { |(k, _)| k }
309
+ if missing_variables.size > 0
310
+ raise ArgumentError,
311
+ "Missing required parameters: #{missing_variables.join(', ')}."
312
+ end
313
+ parameters.each do |k, v|
314
+ # Handle repeated parameters.
315
+ if self.parameter_descriptions[k] &&
316
+ self.parameter_descriptions[k]['repeated'] &&
317
+ v.kind_of?(Array)
318
+ # If this is a repeated parameter and we've got an array as a
319
+ # value, just provide the whole array to the loop below.
320
+ items = v
321
+ else
322
+ # If this is not a repeated parameter, or if it is but we're
323
+ # being given a single value, wrap the value in an array, so that
324
+ # the loop below still works for the single element.
325
+ items = [v]
326
+ end
327
+
328
+ items.each do |item|
329
+ if self.parameter_descriptions[k]
330
+ enum = self.parameter_descriptions[k]['enum']
331
+ if enum && !enum.include?(item)
332
+ raise ArgumentError,
333
+ "Parameter '#{k}' has an invalid value: #{item}. " +
334
+ "Must be one of #{enum.inspect}."
335
+ end
336
+ pattern = self.parameter_descriptions[k]['pattern']
337
+ if pattern
338
+ regexp = Regexp.new("^#{pattern}$")
339
+ if item !~ regexp
340
+ raise ArgumentError,
341
+ "Parameter '#{k}' has an invalid value: #{item}. " +
342
+ "Must match: /^#{pattern}$/."
343
+ end
344
+ end
345
+ end
346
+ end
347
+ end
348
+ return nil
349
+ end
350
+
351
+ ##
352
+ # Returns a <code>String</code> representation of the method's state.
353
+ #
354
+ # @return [String] The method's state, as a <code>String</code>.
355
+ def inspect
356
+ sprintf(
357
+ "#<%s:%#0x ID:%s>",
358
+ self.class.to_s, self.object_id, self.id
359
+ )
360
+ end
361
+ end
362
+ end
363
+ end