bubblez 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/bubblez.gemspec ADDED
@@ -0,0 +1,46 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'bubblez/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = Bubblez::VersionInformation.package_name
8
+ spec.version = Bubblez::VersionInformation.version_name
9
+ spec.date = Date.today.strftime("%Y-%m-%d")
10
+ spec.summary = 'Bubblez REST Client'
11
+ spec.homepage = 'https://github.com/FoamFactory/bubblez'
12
+ spec.authors = ['Scott Johnson']
13
+ spec.email = 'jaywir3@gmail.com'
14
+ spec.files = %w(lib/bubblez.rb lib/bubblez/rest_environment.rb lib/bubblez/version.rb)
15
+ spec.license = 'MPL-2.0'
16
+ spec.summary = %q{A gem for easily defining client REST interfaces in Ruby}
17
+ spec.description = %q{Retrofit, by Square, allows you to easily define annoations that will generate the necessary boilerplate code for your REST interfaces. Bubblez is a Gem that seeks to bring a similar style of boilerplate generation to Ruby.}
18
+
19
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
20
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
21
+ if spec.respond_to?(:metadata)
22
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
23
+ else
24
+ raise "RubyGems 2.0 or newer is required to protect against " \
25
+ "public gem pushes."
26
+ end
27
+
28
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
29
+ f.match(%r{^(test|spec|features)/})
30
+ end
31
+ spec.bindir = "exe"
32
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
33
+ spec.require_paths = ["lib"]
34
+
35
+ spec.add_development_dependency "bundler", "~> 2.2.26"
36
+ spec.add_development_dependency 'rake', '~> 12.3', '>= 12.3.3'
37
+ spec.add_development_dependency "minitest", "~> 5.0"
38
+ spec.add_development_dependency "minitest-reporters", "~> 1.1"
39
+ spec.add_development_dependency "simplecov", "~> 0.16"
40
+ spec.add_development_dependency "webmock", "~> 3.5"
41
+ spec.add_development_dependency "vcr", "~> 3.0"
42
+ spec.add_development_dependency "rspec", "~> 3.8"
43
+ spec.add_development_dependency "os", "~> 1.1.4"
44
+ spec.add_dependency "addressable", "~> 2.5"
45
+ spec.add_dependency "rest-client", "~> 2.0"
46
+ end
@@ -0,0 +1,353 @@
1
+ require 'bubblez/rest_environment'
2
+ require 'bubblez/endpoint'
3
+ require 'base64'
4
+
5
+ module Bubblez
6
+ class << self
7
+ attr_writer :configuration
8
+ end
9
+
10
+ ##
11
+ # Configure the Bubblez instance.
12
+ #
13
+ # Use this method if you want to configure the Bubblez instance, typically during initialization of your Gem or
14
+ # application.
15
+ #
16
+ # @example In app/config/initializers/bubblez.rb
17
+ # Bubblez.configure do |config|
18
+ # config.endpoints = [
19
+ # {
20
+ # :type => :get,
21
+ # :location => :version,
22
+ # :authenticated => false,
23
+ # :api_key_required => false
24
+ # }
25
+ # ]
26
+ # end
27
+ def self.configure
28
+ yield(configuration)
29
+ end
30
+
31
+ def self.configuration
32
+ @configuration ||= Configuration.new
33
+ end
34
+
35
+ ##
36
+ # The configuration of the Bubblez rest client.
37
+ #
38
+ # Use this class if you want to retrieve configuration values set during initialization.
39
+ #
40
+ class Configuration
41
+ def initialize
42
+ @environments = Hash.new
43
+ @endpoints = Hash.new
44
+ end
45
+
46
+ ##
47
+ # Retrieve the {RestEnvironment} object defined as part of this Configuration having a specified name.
48
+ #
49
+ # @param [String] environment_name The name of the {RestEnvironment} to retrieve.
50
+ #
51
+ # The +environment_name+ is +nil+ by default, which will return the default configuration, if only one exists.
52
+ #
53
+ # @return [RestEnvironment] A new +RestEnvironment+ having the configuration that was created with key
54
+ # +environment_name+. Note that +RestEnvironment+s are essentially immutable once they are created, so
55
+ # an existing object will _never_ be returned.
56
+ #
57
+ def environment(environment_name = nil)
58
+ if environment_name.nil?
59
+ if @environments.length > 1
60
+ raise 'You must specify an environment_name parameter because more than one environment is defined'
61
+ end
62
+
63
+ env_hash = @environments[nil]
64
+ else
65
+ env_hash = @environments[environment_name]
66
+ end
67
+
68
+ if env_hash.nil?
69
+ if environment_name.nil?
70
+ raise 'No default environment specified'
71
+ end
72
+
73
+ raise 'No environment specified having name {}', environment_name
74
+ end
75
+
76
+ RestEnvironment.new(env_hash[:scheme], env_hash[:host], env_hash[:port], env_hash[:api_key],
77
+ env_hash[:api_key_name])
78
+ end
79
+
80
+ ##
81
+ # Set the environments that can be used.
82
+ #
83
+ # @param [Array] environments The environments, as an array with each entry a +Hash+.
84
+ #
85
+ # One or more environments may be specified, but if more than one environment is specified, it is required that each
86
+ # environment have a +:environment_name:+ parameter to differentiate it from other environments.
87
+ #
88
+ # @example In app/config/environments/staging.rb:
89
+ # Bubblez.configure do |config|
90
+ # config.environments = [{
91
+ # :scheme => 'https',
92
+ # :host => 'stage.api.somehost.com',
93
+ # :port => '443',
94
+ # :api_key => 'something',
95
+ # :api_key_name => 'X-API-Key' # Optional
96
+ # }]
97
+ # end
98
+ #
99
+ def environments=(environments)
100
+ default = nil
101
+ environments.each do |environment|
102
+ if environments.length > 1 && environment[:environment_name].nil?
103
+ message = 'More than one environment was specified and at least one of the environments does not have an ' \
104
+ ':environment_name field. Verify all environments have an :environment_name.'
105
+
106
+ raise message
107
+ end
108
+
109
+ @environments = {}
110
+ env_api_key = 'X-API-Key'
111
+ env_api_key = environment[:api_key_name] if environment.key? :api_key_name
112
+
113
+ @environments[environment[:environment_name]] = {
114
+ scheme: environment[:scheme],
115
+ host: environment[:host],
116
+ port: environment[:port],
117
+ api_key: environment[:api_key],
118
+ api_key_name: env_api_key
119
+ }
120
+ end
121
+ end
122
+
123
+ ##
124
+ # Retrieve the list of +Endpoint+s configured in this +Configuration+ object.
125
+ #
126
+ # @return {Array} An Array of {Endpoint}s.
127
+ #
128
+ def endpoints
129
+ @endpoints
130
+ end
131
+
132
+ ##
133
+ # Add all {Endpoint} objects within this {Configuration} instance.
134
+ #
135
+ # {Endpoint} objects are defined using two required parameters: type and location, and three optional parameters:
136
+ # authenticated, api_key_required and name.
137
+ # - method: Indicates the HTTP method used to access the endpoint. Must be one of {Endpoint::METHODS}.
138
+ # - location: Indicates the path at which the {Endpoint} can be accessed on the host environment.
139
+ # - authenticated: (Optional) A true or false value indicating whether the {Endpoint} requires an authorization
140
+ # token to access it. Defaults to false.
141
+ # - api_key_required: (Optional) A true or false value indicating whether the {Endpoint} requires a API key to
142
+ # access it. Defaults to false.
143
+ # - name: (Optional): A +String+ indicating the name of the method to add. If not provided, the method name will
144
+ # be the same as the +location+.
145
+ #
146
+ def endpoints=(endpoints)
147
+ new_endpoints = Hash.new
148
+ endpoints.each do |ep|
149
+ endpoint_object = Endpoint.new ep[:method], ep[:location].to_s, ep[:authenticated], ep[:api_key_required], ep[:name], ep[:return_type], ep[:encode_authorization], ep[:headers]
150
+
151
+ new_endpoints[endpoint_object.get_key_string] = endpoint_object
152
+ end
153
+
154
+ @endpoints = new_endpoints
155
+
156
+ # Define all of the endpoints as methods on RestEnvironment
157
+ @endpoints.values.each do |endpoint|
158
+ if endpoint.name != nil
159
+ endpoint_name_as_sym = endpoint.name.to_sym
160
+ else
161
+ endpoint_name_as_sym = endpoint.get_location_string.to_sym
162
+ end
163
+
164
+ if Bubblez::RestEnvironment.instance_methods(false).include?(endpoint_name_as_sym)
165
+ Bubblez::RestEnvironment.class_exec do
166
+ remove_method endpoint_name_as_sym
167
+ end
168
+ end
169
+
170
+ if endpoint.method == :get
171
+ if endpoint.authenticated?
172
+ Bubblez::RestEnvironment.class_exec do
173
+ if endpoint.has_uri_params?
174
+ if endpoint.encode_authorization_header?
175
+ define_method(endpoint_name_as_sym) do |username, password, uri_params|
176
+ login_data = {
177
+ :login => username,
178
+ :password => password
179
+ }
180
+ auth_value = RestClientResources.get_encoded_authorization(endpoint, login_data)
181
+ RestClientResources.execute_get_authenticated self, endpoint, :basic, auth_value, uri_params, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
182
+ end
183
+ else
184
+ define_method(endpoint_name_as_sym) do |auth_token, uri_params|
185
+ RestClientResources.execute_get_authenticated self, endpoint, :bearer, auth_token, uri_params, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
186
+ end
187
+ end
188
+ else
189
+ if endpoint.encode_authorization_header?
190
+ define_method(endpoint_name_as_sym) do |username, password|
191
+ login_data = {
192
+ :username => username,
193
+ :password => password
194
+ }
195
+ auth_value = RestClientResources.get_encoded_authorization(endpoint, login_data)
196
+
197
+ RestClientResources.execute_get_authenticated self, endpoint, :basic, auth_value, {}, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
198
+ end
199
+ else
200
+ define_method(endpoint_name_as_sym) do |auth_token|
201
+ RestClientResources.execute_get_authenticated self, endpoint, :bearer, auth_token, {}, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
202
+ end
203
+ end
204
+ end
205
+ end
206
+ else
207
+ Bubblez::RestEnvironment.class_exec do
208
+ if endpoint.has_uri_params?
209
+ define_method(endpoint_name_as_sym) do |uri_params|
210
+ RestClientResources.execute_get_unauthenticated self, endpoint, uri_params, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
211
+ end
212
+ else
213
+ define_method(endpoint_name_as_sym) do
214
+ RestClientResources.execute_get_unauthenticated self, endpoint, {}, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
215
+ end
216
+ end
217
+ end
218
+ end
219
+ elsif endpoint.method == :post
220
+ if endpoint.authenticated? and !endpoint.encode_authorization_header?
221
+ Bubblez::RestEnvironment.class_exec do
222
+ define_method(endpoint_name_as_sym) do |auth_token, data|
223
+ RestClientResources.execute_post_authenticated self, endpoint, :bearer, auth_token, data, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
224
+ end
225
+ end
226
+ elsif endpoint.encode_authorization_header?
227
+ Bubblez::RestEnvironment.class_exec do
228
+ define_method(endpoint_name_as_sym) do |username, password, data = {}|
229
+ login_data = {
230
+ :username => username,
231
+ :password => password
232
+ }
233
+
234
+ auth_value = RestClientResources.get_encoded_authorization(endpoint, login_data)
235
+ # composite_headers = RestClientResources.build_composite_headers(endpoint.additional_headers, {
236
+ # Authorization: 'Basic ' + Base64.strict_encode64(auth_value)
237
+ # })
238
+ RestClientResources.execute_post_authenticated self, endpoint, :basic, auth_value, data, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
239
+ end
240
+ end
241
+ else
242
+ Bubblez::RestEnvironment.class_exec do
243
+ define_method(endpoint_name_as_sym) do |data|
244
+ composite_headers = endpoint.additional_headers
245
+ RestClientResources.execute_post_unauthenticated self, endpoint, data, composite_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
246
+ end
247
+ end
248
+ end
249
+ elsif endpoint.method == :delete
250
+ if endpoint.has_uri_params?
251
+ if endpoint.authenticated?
252
+ Bubblez::RestEnvironment.class_exec do
253
+ define_method(endpoint_name_as_sym) do |auth_token, uri_params|
254
+ RestClientResources.execute_delete_authenticated self, endpoint, auth_token, uri_params, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
255
+ end
256
+ end
257
+ else
258
+ Bubblez::RestEnvironment.class_exec do
259
+ define_method(endpoint_name_as_sym) do |uri_params|
260
+ RestClientResources.execute_delete_unauthenticated self, endpoint, uri_params, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
261
+ end
262
+ end
263
+ end
264
+ else
265
+ # XXX_jwir3: While MDN states that DELETE requests with a body are allowed, it seems that a number of
266
+ # documentation sites discourage its use. Thus, it's possible that, depending on the server API
267
+ # framework, the DELETE request could be rejected. In addition, RestClient doesn't seem to support DELETE
268
+ # requests with a body, so we're a bit stuck on this one, even if we wanted to support it.
269
+ raise 'DELETE requests without URI parameters are not allowed'
270
+ end
271
+ elsif endpoint.method == :patch
272
+ if endpoint.authenticated?
273
+ Bubblez::RestEnvironment.class_exec do
274
+ if endpoint.has_uri_params?
275
+ define_method(endpoint_name_as_sym) do |auth_token, uri_params, data|
276
+ RestClientResources.execute_patch_authenticated self, endpoint, auth_token, uri_params, data, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
277
+ end
278
+ else
279
+ define_method(endpoint_name_as_sym) do |auth_token, data|
280
+ RestClientResources.execute_patch_authenticated self, endpoint, auth_token, {}, data, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
281
+ end
282
+ end
283
+ end
284
+ else
285
+ Bubblez::RestEnvironment.class_exec do
286
+ if endpoint.has_uri_params?
287
+ define_method(endpoint_name_as_sym) do |uri_params, data|
288
+ RestClientResources.execute_patch_unauthenticated self, endpoint, uri_params, data, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
289
+ end
290
+ else
291
+ define_method(endpoint_name_as_sym) do |data|
292
+ RestClientResources.execute_patch_unauthenticated self, endpoint, {}, data, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
293
+ end
294
+ end
295
+ end
296
+ end
297
+ elsif endpoint.method == :put
298
+ if endpoint.authenticated?
299
+ Bubblez::RestEnvironment.class_exec do
300
+ if endpoint.has_uri_params?
301
+ define_method(endpoint_name_as_sym) do |auth_token, uri_params, data|
302
+ RestClientResources.execute_put_authenticated self, endpoint, auth_token, uri_params, data, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
303
+ end
304
+ else
305
+ define_method(endpoint_name_as_sym) do |auth_token, data|
306
+ RestClientResources.execute_put_authenticated self, endpoint, auth_token, {}, data, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
307
+ end
308
+ end
309
+ end
310
+ else
311
+ Bubblez::RestEnvironment.class_exec do
312
+ if endpoint.has_uri_params?
313
+ define_method(endpoint_name_as_sym) do |uri_params, data|
314
+ RestClientResources.execute_put_unauthenticated self, endpoint, uri_params, data, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
315
+ end
316
+ else
317
+ define_method(endpoint_name_as_sym) do |data|
318
+ RestClientResources.execute_put_unauthenticated self, endpoint, {}, data, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
319
+ end
320
+ end
321
+ end
322
+ end
323
+ elsif endpoint.method == :head
324
+ if endpoint.authenticated?
325
+ Bubblez::RestEnvironment.class_exec do
326
+ if endpoint.has_uri_params?
327
+ define_method(endpoint_name_as_sym) do |auth_token, uri_params|
328
+ RestClientResources.execute_head_authenticated self, endpoint, auth_token, uri_params, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
329
+ end
330
+ else
331
+ define_method(endpoint_name_as_sym) do |auth_token|
332
+ RestClientResources.execute_head_authenticated self, endpoint, auth_token, {}, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
333
+ end
334
+ end
335
+ end
336
+ else
337
+ Bubblez::RestEnvironment.class_exec do
338
+ if endpoint.has_uri_params?
339
+ define_method(endpoint_name_as_sym) do |uri_params|
340
+ RestClientResources.execute_head_unauthenticated self, endpoint, uri_params, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
341
+ end
342
+ else
343
+ define_method(endpoint_name_as_sym) do
344
+ RestClientResources.execute_head_unauthenticated self, endpoint, {}, endpoint.additional_headers, self.get_api_key_if_needed(endpoint), self.api_key_name
345
+ end
346
+ end
347
+ end
348
+ end
349
+ end
350
+ end
351
+ end
352
+ end
353
+ end
@@ -0,0 +1,286 @@
1
+ require 'addressable/template'
2
+
3
+ module Bubblez
4
+ ##
5
+ # Representation of a single API endpoint within the Bubblez infrastructure.
6
+ #
7
+ # In order to access an API Endpoint, an {RestEnvironment} must also be provided. This class is an abstract
8
+ # representation of an +Endpoint+, without any information provided as part of the Environment. In other words, an
9
+ # Endpoint can be used with any +RestEnvironment+.
10
+ #
11
+ class Endpoint
12
+ ##
13
+ # Controls the method used to access the endpoint. Must be one of {Endpoint::Methods}.
14
+ # @return [Symbol] the method used to access the endpoint. Will always be one of the symbols defined in
15
+ # {Endpoint::METHODS}.
16
+ attr_accessor :method
17
+
18
+ ##
19
+ # Controls the location, relative to the web root of the host, used to access the endpoint.
20
+ # @return [String] the location relative to the web root of the host used to access the endpoint
21
+ attr_accessor :location
22
+
23
+ ##
24
+ # Controls whether authentication is required to access this endpoint. Defaults to false.
25
+ # @return [Boolean] true, if authentication is required to access this endpoint; false, otherwise.
26
+ attr_accessor :authentication_required
27
+
28
+ ##
29
+ # Controls whether an API key is required to access this endpoint. Defaults to false.
30
+ # @return [Boolean] true, if an API key is required to access this endpoint; false, otherwise.
31
+ attr_accessor :api_key_required
32
+
33
+ ##
34
+ # Controls what type of object will be returned from the REST API call on success. Must be one of the symbols
35
+ # defined in {Endpoint::RETURN_TYPES}.
36
+ #
37
+ attr_accessor :return_type
38
+
39
+ ##
40
+ # Controls which data values should be encoded as part of an Authorization header. They will be separated with a
41
+ # colon in the order they are received and Base64-encoded.
42
+ # @return [Array] An array of +Symbol+s specifying which of the data attributes should be Base64-encoded as part of
43
+ # an Authorization header. The values will be encoded in the order they are received.
44
+ attr_accessor :encode_authorization
45
+
46
+ ##
47
+ # An array of parameters that are specified on the URI of this endpoint for each call.
48
+ attr_accessor :uri_params
49
+
50
+ ## A template for specifying the complete URL for endpoints.
51
+ API_URL = ::Addressable::Template.new("{scheme}://{host}/{endpoint}")
52
+
53
+ ## A template for specifying the complete URL for endpoints, with a port attached to the host.
54
+ API_URL_WITH_PORT = ::Addressable::Template.new("{scheme}://{host}:{port}/{endpoint}")
55
+
56
+ ## The HTTP methods supported by a rest client utilizing Bubblez.
57
+ METHODS = %w[get post patch put delete head].freeze
58
+
59
+ ## The possible return types for successful REST calls. Defaults to :body_as_string.
60
+ RETURN_TYPES = %w[full_response body_as_string body_as_object].freeze
61
+
62
+ ##
63
+ # Construct a new instance of an Endpoint.
64
+ #
65
+ # @param [Symbol] method The type of the new Endpoint to create. Must be one of the methods in
66
+ # {Endpoint::METHODS}.
67
+ # @param [String] location The location, relative to the root of the host, at which the endpoint resides.
68
+ # @param [Boolean] auth_required If true, then authorization/authentication is required to access this endpoint.
69
+ # Defaults to +false+.
70
+ # @param [Boolean] api_key_required If true, then an API key is required to access this endpoint. Defaults to
71
+ # +false+.
72
+ # @param [String] name An optional name which will be given to the method that will execute this {Endpoint} within
73
+ # the context of a {RestClientResources} object.
74
+ # @param [Array<Symbol>] encode_authorization Parameters that should be treated as authorization parameters and
75
+ # encoded using a Base64 encoding.
76
+ #
77
+ def initialize(method, location, auth_required = false, api_key_required = false, name = nil, return_type = :body_as_string, encode_authorization = {}, headers = {})
78
+ @method = method
79
+ @location = location
80
+ @auth_required = auth_required
81
+ @api_key_required = api_key_required
82
+ @name = name
83
+ @encode_authorization = encode_authorization
84
+ @additional_headers = headers
85
+
86
+ unless Endpoint::RETURN_TYPES.include? return_type.to_s
87
+ return_type = :body_as_string
88
+ end
89
+
90
+ @return_type = return_type
91
+
92
+ @uri_params = []
93
+
94
+ # Strip the leading slash from the endpoint location, if it's there
95
+ if @location.to_s[0] == '/'
96
+ @location = @location.to_s.slice(1, @location.to_s.length)
97
+ end
98
+
99
+ # Extract URI parameters and create symbols for them
100
+ # URI parameters are enclosed by curly braces '{' and '}'
101
+ @location.to_s.split('/').each do |uri_segment|
102
+
103
+ match_data = /\{(.*)\}/.match(uri_segment)
104
+ unless match_data == nil
105
+ @uri_params.push(match_data[1].to_sym)
106
+ end
107
+ end
108
+ end
109
+
110
+ ##
111
+ # Retrieve a +String+ that will identify this +Endpoint+ uniquely within a hash table.
112
+ #
113
+ # @return [String] A unique identifier for this Endpoint, including its method (get/post/put/etc..), location, whether or not it is authenticated, and whether it needs an API key to successfully execute.
114
+ #
115
+ def get_key_string
116
+ auth_string = '-unauthenticated'
117
+ if @auth_required
118
+ auth_string = '-authenticated'
119
+ end
120
+
121
+ api_key_string = ''
122
+ if @api_key_required
123
+ api_key_string = '-with-api-key'
124
+ end
125
+
126
+ method.to_s + "-" + @location.to_s + auth_string + api_key_string
127
+ end
128
+
129
+ ##
130
+ # Retrieve the base URL template for this +Endpoint+, given a +RestEnvironment+.
131
+ #
132
+ # @param [RestEnvironment] env The +RestEnvironment+ to use to access this endpoint.
133
+ #
134
+ # @return [Addressable::Template] A +Template+ containing the URL to use to access this +Endpoint+.
135
+ #
136
+ def get_base_url(env)
137
+ unless env.port == 80 || env.port == 443
138
+ return API_URL_WITH_PORT
139
+ end
140
+
141
+ API_URL
142
+ end
143
+
144
+ ##
145
+ # Retrieve the URL to access this +Endpoint+, as a +String+ with all parameters expanded.
146
+ #
147
+ # @param [RestEnvironment] env The +RestEnvironment+ to use to access this +Endpoint+.
148
+ #
149
+ # @return [Addressable::URI] An +Addressable::URI+ containing the full URL to access this +Endpoint+ on the given
150
+ # +RestEnvironment+.
151
+ #
152
+ def get_expanded_url(env, uri_params = {})
153
+ url = get_base_url env
154
+
155
+ if is_complex?
156
+ special_url_string = '{scheme}://{host}/'
157
+ unless @port == 80 || @port == 443
158
+ special_url_string = '{scheme}://{host}:{port}/'
159
+ end
160
+
161
+ special_url_string = special_url_string + @location
162
+
163
+ uri_params.each do |param, value|
164
+ needle = "{#{param.to_s}}"
165
+ special_url_string = special_url_string.sub(needle, value.to_s)
166
+ end
167
+
168
+ url = ::Addressable::Template.new(special_url_string)
169
+
170
+ return url.expand(scheme: env.scheme, host: env.host, port: env.port)
171
+ end
172
+
173
+ url.expand(scheme: env.scheme, host: env.host, port: env.port, endpoint: @location)
174
+ end
175
+
176
+ ##
177
+ # Determine if the location for this Endpoint is complex.
178
+ #
179
+ # @return [Boolean] true, if the location for this Endpoint is complex (contains a '/'); false, otherwise.
180
+ def is_complex?
181
+ @location.include? '/'
182
+ end
183
+
184
+ ##
185
+ # Retrieve a String representing the location of this Endpoint.
186
+ #
187
+ # Complex Endpoints will have instances of '/' replaced with '_'.
188
+ #
189
+ # @return [String] The string representation of the location of this endpoint.
190
+ def get_location_string
191
+ unless is_complex?
192
+ return @location
193
+ end
194
+
195
+ @location.to_s.gsub('/', '_')
196
+ end
197
+
198
+ ##
199
+ # Determine if this +Endpoint+ requires authentication/authorization to utilize
200
+ #
201
+ # @return [Boolean] true, if this +Endpoint+ requires authentication/authorization to use; false, otherwise.
202
+ def authenticated?
203
+ @auth_required
204
+ end
205
+
206
+ ##
207
+ # Determine if an API key is required
208
+ #
209
+ # @return [Boolean] true, if an API key is required to make the request; false, otherwise.
210
+ def api_key_required?
211
+ api_key_required
212
+ end
213
+
214
+ ##
215
+ # Set the name of the method on {RestClientResources} used to access this {Endpoint}.
216
+ #
217
+ # @param [String] name The name of the method used to access this {Endpoint}.
218
+ #
219
+ def name=(name)
220
+ @name = name
221
+ end
222
+
223
+ ##
224
+ # Retrieve the name of the method on {RestClientResources} used to access this {Endpoint}.
225
+ #
226
+ # @return [String] A String containing the name of the method on {RestClientResources} used to access this
227
+ # {Endpoint}, or +nil+ if one wasn't provided.
228
+ #
229
+ def name
230
+ @name
231
+ end
232
+
233
+ ##
234
+ # Determine if this {Endpoint} has a method name, different from the +location+ name, specified for it.
235
+ #
236
+ # @return [Boolean] true, if this {Endpoint} has a method name that is different than the +location+ name specified
237
+ # for the +Endpoint+, to be defined on {RestClientResources}; false, otherwise.
238
+ #
239
+ def name?
240
+ @name != nil
241
+ end
242
+
243
+ ##
244
+ # Whether or not an Authorization header should be Base64-encoded.
245
+ #
246
+ # @return [Boolean] true, if attributes from the data array have been specified to be Base64-encoded as part of an
247
+ # Authorization header; false, otherwise.
248
+ #
249
+ def encode_authorization_header?
250
+ !@encode_authorization.nil? and @encode_authorization.length > 0
251
+ end
252
+
253
+ ##
254
+ # Retrieve the return type of this REST endpoint.
255
+ #
256
+ # This will always be one of:
257
+ #
258
+ # - +full_response+ : Indicates that the full +Response+ object should be returned so that headers and
259
+ # return code can be used.
260
+ # - +body_as_object+ : Indicates that the body of the +Response+ should be parsed as a full +OpenStruct+
261
+ # object and returned.
262
+ # - +body_as_string+ : Indicates that only the body of the +Response+ object should be returned, as a +String+.
263
+ #
264
+ # By default, if this is not specified, it will be +body_as+string+.
265
+ #
266
+ def return_type
267
+ @return_type
268
+ end
269
+
270
+ def has_uri_params?
271
+ !@uri_params.empty?
272
+ end
273
+
274
+ def additional_headers
275
+ unless @additional_headers
276
+ @additional_headers = {}
277
+ end
278
+
279
+ @additional_headers
280
+ end
281
+
282
+ def has_additional_headers?
283
+ not additional_headers.empty?
284
+ end
285
+ end
286
+ end