occi-api 4.2.0.beta.4 → 4.2.0.beta.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,525 +1,214 @@
1
1
  require 'httparty'
2
2
 
3
- require 'occi/api/client/http/net_http_fix'
4
- require 'occi/api/client/http/httparty_fix'
5
- require 'occi/api/client/authn_utils'
6
- require 'occi/api/client/http/authn_plugins'
7
-
8
- module Occi
9
- module Api
10
- module Client
11
-
12
- class ClientHttp < ClientBase
13
-
14
- # HTTParty for raw HTTP requests
15
- include HTTParty
16
-
17
- # TODO: change default Accept to JSON as soon as it is properly
18
- # implemented in OpenStack's OCCI-OS
19
- # 'Accept' => 'application/occi+json,text/plain;q=0.8,text/occi;q=0.2'
20
- DEFAULT_HEADERS = {
21
- 'Accept' => 'text/plain,text/occi;q=0.2',
22
- 'User-Agent' => "rOCCI HTTPClient #{Occi::Api::VERSION}"
23
- }
24
- headers DEFAULT_HEADERS
25
-
26
- # hash mapping HTTP response codes to human-readable messages
27
- HTTP_CODES = {
28
- "100" => "Continue",
29
- "101" => "Switching Protocols",
30
- "200" => "OK",
31
- "201" => "Created",
32
- "202" => "Accepted",
33
- "203" => "Non-Authoritative Information",
34
- "204" => "No Content",
35
- "205" => "Reset Content",
36
- "206" => "Partial Content",
37
- "300" => "Multiple Choices",
38
- "301" => "Moved Permanently",
39
- "302" => "Found",
40
- "303" => "See Other",
41
- "304" => "Not Modified",
42
- "305" => "Use Proxy",
43
- "307" => "Temporary Redirect",
44
- "400" => "Bad Request",
45
- "401" => "Unauthorized",
46
- "402" => "Payment Required",
47
- "403" => "Forbidden",
48
- "404" => "Not Found",
49
- "405" => "Method Not Allowed",
50
- "406" => "Not Acceptable",
51
- "407" => "Proxy Authentication Required",
52
- "408" => "Request Time-out",
53
- "409" => "Conflict",
54
- "410" => "Gone",
55
- "411" => "Length Required",
56
- "412" => "Precondition Failed",
57
- "413" => "Request Entity Too Large",
58
- "414" => "Request-URI Too Large",
59
- "415" => "Unsupported Media Type",
60
- "416" => "Requested range not satisfiable",
61
- "417" => "Expectation Failed",
62
- "500" => "Internal Server Error",
63
- "501" => "Not Implemented",
64
- "502" => "Bad Gateway",
65
- "503" => "Service Unavailable",
66
- "504" => "Gateway Time-out",
67
- "505" => "HTTP Version not supported"
68
- }
69
-
70
- # Initializes client data structures and retrieves OCCI model
71
- # from the server.
72
- #
73
- # @example
74
- # options = {
75
- # :endpoint => "http://localhost:3300/",
76
- # :auth => {:type => "none"},
77
- # :log => {:out => STDERR, :level => Occi::Log::WARN, :logger => nil},
78
- # :auto_connect => "value", auto_connect => true,
79
- # :media_type => nil
80
- # }
81
- #
82
- # Occi::Api::Client::ClientHttp.new options # => #<Occi::Api::Client::ClientHttp>
83
- #
84
- # @param [Hash] options, for available options and defaults see examples
85
- # @return [Occi::Api::Client::ClientHttp] client instance
86
- def initialize(options = {})
87
- super options
88
-
89
- # get model information from the endpoint
90
- # and create Occi::Model instance
91
- model_collection = get('/-/')
92
- @model = get_model(model_collection)
93
-
94
- # auto-connect?
95
- @connected = @options[:auto_connect]
96
- end
97
-
98
- # @see Occi::Api::Client::ClientBase
99
- def list(resource_type_identifier=nil)
100
- if resource_type_identifier
101
- resource_type_identifier = get_resource_type_identifier(resource_type_identifier)
102
- path = path_for_kind_type_identifier(resource_type_identifier)
103
- end
104
-
105
- path = '/' unless path
106
- path = "#{@endpoint.to_s}#{path}"
107
-
108
- headers = self.class.headers.clone
109
- headers['Accept'] = 'text/uri-list'
110
-
111
- response = self.class.get(
112
- path,
113
- :headers => headers
114
- )
115
-
116
- # TODO: remove the gsub OCCI-OS hack as soon as they stop using 'uri:'
117
- response.body.gsub(/\# uri:\/(compute|storage|network)\/[\n]?/, '').split("\n").compact
118
- end
119
-
120
- # @see Occi::Api::Client::ClientBase
121
- def describe(resource_type_identifier=nil)
122
- if resource_type_identifier
123
- resource_type_identifier = get_resource_type_identifier(resource_type_identifier)
124
- end
125
-
126
- descriptions = Occi::Collection.new
127
-
128
- if resource_type_identifier.blank?
129
- # no filters, describe all available resources
130
- descriptions.merge! get('/')
131
- elsif @model.get_by_id(resource_type_identifier)
132
- # we got type identifier
133
- # get all available resources of this type
134
- locations = list(resource_type_identifier)
135
-
136
- # make the requests
137
- locations.each do |location|
138
- path = sanitize_instance_link(location)
139
- descriptions.merge! get(path)
140
- end
141
- else
142
- # this is a link of a specific resource (absolute or relative)
143
- path = sanitize_instance_link(resource_type_identifier)
144
- descriptions.merge! get(path)
145
- end
146
-
147
- descriptions.resources
148
- end
149
-
150
- # @see Occi::Api::Client::ClientBase
151
- def create(entity)
152
- raise "#{entity.class.name.inspect} not an entity!" unless entity.kind_of? Occi::Core::Entity
153
-
154
- Occi::Log.debug "Entity kind: #{entity.kind.type_identifier.inspect}"
155
- raise "No kind found for #{entity.inspect}" unless entity.kind
3
+ # load all parts of the ClientHttp
4
+ Dir[File.join(File.dirname(__FILE__), 'http', '*.rb')].each { |file| require file.gsub('.rb', '') }
5
+
6
+ module Occi::Api::Client
7
+
8
+ class ClientHttp < ClientBase
9
+
10
+ # HTTParty for raw HTTP requests
11
+ include HTTParty
12
+
13
+ # TODO: change default Accept to JSON as soon as it is properly
14
+ # implemented in OpenStack's OCCI-OS
15
+ # 'Accept' => 'application/occi+json,text/plain;q=0.8,text/occi;q=0.2'
16
+ DEFAULT_HEADERS = {
17
+ 'Accept' => 'text/plain,text/occi;q=0.2',
18
+ 'User-Agent' => "rOCCI HTTPClient #{Occi::Api::VERSION}"
19
+ }
20
+ headers DEFAULT_HEADERS
21
+
22
+ # Initializes client data structures and retrieves OCCI model
23
+ # from the server.
24
+ #
25
+ # @example
26
+ # options = {
27
+ # :endpoint => "http://localhost:3300/",
28
+ # :timeout => 15
29
+ # :auth => {:type => "none"},
30
+ # :log => {:out => STDERR, :level => Occi::Log::WARN, :logger => nil},
31
+ # :auto_connect => true,
32
+ # :media_type => nil
33
+ # }
34
+ #
35
+ # Occi::Api::Client::ClientHttp.new options # => #<Occi::Api::Client::ClientHttp>
36
+ #
37
+ # @param [Hash] options, for available options and defaults see examples
38
+ # @return [Occi::Api::Client::ClientHttp] client instance
39
+ def initialize(options = {})
40
+ super options
41
+
42
+ self.class.base_uri @endpoint.to_s
43
+ self.class.timeout @options[:timeout].to_i unless @options[:timeout].blank?
44
+
45
+ # get model information from the endpoint
46
+ # and create Occi::Model instance
47
+ model_collection = get('/-/')
48
+ @model = get_model(model_collection)
49
+
50
+ # auto-connect?
51
+ @connected = @options[:auto_connect]
52
+ end
156
53
 
157
- # get location for this kind of entity
158
- path = path_for_kind_type_identifier(entity.kind.type_identifier)
159
- collection = Occi::Collection.new
54
+ # @see Occi::Api::Client::ClientBase
55
+ def list(resource_type_identifier=nil)
56
+ if resource_type_identifier
57
+ resource_type_identifier = get_resource_type_identifier(resource_type_identifier)
58
+ path = path_for_kind_type_identifier(resource_type_identifier)
59
+ end
160
60
 
161
- # is this entity a Resource or a Link?
162
- Occi::Log.debug "Entity class: #{entity.class.name.inspect}"
163
- collection.resources << entity if entity.kind_of? Occi::Core::Resource
164
- collection.links << entity if entity.kind_of? Occi::Core::Link
61
+ path = '/' unless path
165
62
 
166
- # make the request
167
- post path, collection
168
- end
63
+ headers = self.class.headers.clone
64
+ headers['Accept'] = 'text/uri-list'
169
65
 
170
- # @see Occi::Api::Client::ClientBase
171
- def deploy(location)
172
- raise "File #{location.inspect} does not exist!" unless File.exist? location
66
+ response = self.class.get(
67
+ path,
68
+ :headers => headers
69
+ )
173
70
 
174
- file = File.read(location)
71
+ # TODO: remove the gsub OCCI-OS hack as soon as they stop using 'uri:'
72
+ response.body.gsub(/\# uri:\/(compute|storage|network)\/[\n]?/, '').split("\n").compact
73
+ end
175
74
 
176
- if location.include? '.ovf'
177
- deploy_ovf file
178
- elsif location.include? '.ova'
179
- deploy_ova file
180
- else
181
- raise "Unsupported descriptor format! Only OVF or OVA files are supported."
182
- end
183
- end
75
+ # @see Occi::Api::Client::ClientBase
76
+ def describe(resource_type_identifier=nil)
77
+ if resource_type_identifier
78
+ resource_type_identifier = get_resource_type_identifier(resource_type_identifier)
79
+ end
184
80
 
185
- # @see Occi::Api::Client::ClientBase
186
- def deploy_ovf(descriptor)
187
- media_types = self.class.head(@endpoint.to_s).headers['accept'].to_s
188
-
189
- path = path_for_kind_type_identifier(Occi::Infrastructure::Compute.type_identifier)
190
- path = "#{@endpoint.to_s}#{path}"
191
- if media_types.include? 'application/ovf'
192
- headers = self.class.headers.clone
193
- headers['Content-Type'] = 'application/ovf'
194
- self.class.post(path,
195
- :body => descriptor,
196
- :headers => headers)
197
- else
198
- raise "Unsupported descriptor format! Server does not support OVF descriptors."
199
- end
200
- end
81
+ descriptions = Occi::Collection.new
82
+
83
+ if resource_type_identifier.blank?
84
+ # no filters, describe all available resources
85
+ descriptions.merge! get('/')
86
+ elsif @model.get_by_id(resource_type_identifier)
87
+ # we got type identifier
88
+ # get all available resources of this type
89
+ locations = list(resource_type_identifier)
90
+
91
+ # make the requests
92
+ locations.each do |location|
93
+ path = sanitize_instance_link(location)
94
+ descriptions.merge! get(path)
95
+ end
96
+ else
97
+ # this is a link of a specific resource (absolute or relative)
98
+ path = sanitize_instance_link(resource_type_identifier)
99
+ descriptions.merge! get(path)
100
+ end
201
101
 
202
- # @see Occi::Api::Client::ClientBase
203
- def deploy_ova(descriptor)
204
- media_types = self.class.head(@endpoint.to_s).headers['accept'].to_s
205
-
206
- path = path_for_kind_type_identifier(Occi::Infrastructure::Compute.type_identifier)
207
- path = "#{@endpoint.to_s}#{path}"
208
- if media_types.include? ' application/ova '
209
- headers = self.class.headers.clone
210
- headers['Content-Type'] = 'application/ova'
211
- self.class.post(path,
212
- :body => descriptor,
213
- :headers => headers)
214
- else
215
- raise "Unsupported descriptor format! Server does not support OVA descriptors."
216
- end
217
- end
102
+ descriptions.resources
103
+ end
218
104
 
219
- # @see Occi::Api::Client::ClientBase
220
- def delete(resource_type_identifier)
221
- raise 'Resource not provided!' if resource_type_identifier.blank?
222
- path = path_for_kind_type_identifier(resource_type_identifier)
105
+ # @see Occi::Api::Client::ClientBase
106
+ def create(entity)
107
+ raise "#{entity.class.name.inspect} not an entity!" unless entity.kind_of? Occi::Core::Entity
223
108
 
224
- Occi::Log.debug("Deleting #{path.inspect} for #{resource_type_identifier.inspect}")
225
- del path
226
- end
109
+ Occi::Log.debug "Entity kind: #{entity.kind.type_identifier.inspect}"
110
+ raise "No kind found for #{entity.inspect}" unless entity.kind
227
111
 
228
- # @see Occi::Api::Client::ClientBase
229
- def trigger(resource_type_identifier, action_instance)
230
- # TODO: not tested
231
- raise 'Resource not provided!' if resource_type_identifier.blank?
112
+ # get location for this kind of entity
113
+ path = path_for_kind_type_identifier(entity.kind.type_identifier)
114
+ collection = Occi::Collection.new
232
115
 
233
- #
234
- resource_type_identifier = get_resource_type_identifier(resource_type_identifier)
235
- path = path_for_kind_type_identifier(resource_type_identifier)
116
+ # is this entity a Resource or a Link?
117
+ Occi::Log.debug "Entity class: #{entity.class.name.inspect}"
118
+ collection.resources << entity if entity.kind_of? Occi::Core::Resource
119
+ collection.links << entity if entity.kind_of? Occi::Core::Link
236
120
 
237
- # make the request
238
- post path, action_instance
239
- end
121
+ # make the request
122
+ post path, collection
123
+ end
240
124
 
241
- # @see Occi::Api::Client::ClientBase
242
- def refresh
243
- # re-download the model from the server
244
- model_collection = get('/-/')
245
- @model = get_model(model_collection)
246
- end
125
+ # @see Occi::Api::Client::ClientBase
126
+ def deploy(location)
127
+ raise "File #{location.inspect} does not exist!" unless File.exist? location
247
128
 
248
- private
249
-
250
- # Performs GET request and parses the responses to collections.
251
- #
252
- # @example
253
- # get "/-/" # => #<Occi::Collection>
254
- # get "/compute/" # => #<Occi::Collection>
255
- # get "/compute/fs65g4fs6g-sf54g54gsf-aa12faddf52" # => #<Occi::Collection>
256
- #
257
- # @param [String] path for the GET request
258
- # @param [Occi::Collection] collection of filters
259
- # @return [Occi::Collection] parsed result of the request
260
- def get(path='/', filter=nil)
261
- relative_path = path
262
- path = "#{@endpoint.to_s}#{path}"
263
- # apply filters if present
264
- response = if filter
265
- categories = filter.categories.collect { |category| category.to_text }.join(',')
266
- attributes = filter.entities.collect { |entity| entity.attributes.combine.collect { |k, v| k + '=' + v } }.join(',')
267
-
268
- headers = self.class.headers.clone
269
- headers['Content-Type'] = 'text/occi'
270
- headers['Category'] = categories unless categories.empty?
271
- headers['X-OCCI-Attributes'] = attributes unless attributes.empty?
272
-
273
- self.class.get(path, :headers => headers)
274
- else
275
- self.class.get(path)
276
- end
277
-
278
- response_msg = response_message response
279
- raise "HTTP GET failed! #{response_msg}" unless response.code.between? 200, 300
280
-
281
- Occi::Log.debug "Response location: #{relative_path.inspect}"
282
- kind = @model.get_by_location(relative_path) if @model
283
-
284
- Occi::Log.debug "Response kind: #{kind.inspect}"
285
-
286
- entity_type = nil
287
- if kind && kind.related_to?(Occi::Core::Link)
288
- entity_type = Occi::Core::Link
289
- end
290
-
291
- entity_type = Occi::Core::Resource unless entity_type
292
-
293
- Occi::Log.debug "Parser call: #{response.content_type} #{path.include?('/-/')} #{entity_type} #{response.headers.inspect}"
294
- collection = Occi::Parser.parse(response.content_type, response.body, path.include?('/-/'), entity_type, response.headers)
295
-
296
- Occi::Log.debug "Parsed collection: empty? #{collection.empty?}"
297
- collection
298
- end
129
+ file = File.read(location)
299
130
 
300
- # Performs POST requests and returns URI locations. Resource data must be provided
301
- # in an Occi::Collection instance.
302
- #
303
- # @example
304
- # collection = Occi::Collection.new
305
- # collection.resources << entity if entity.kind_of? Occi::Core::Resource
306
- # collection.links << entity if entity.kind_of? Occi::Core::Link
307
- #
308
- # post "/compute/", collection # => "http://localhost:3300/compute/23sf4g65as-asdgsg2-sdfgsf2g"
309
- # post "/network/", collection # => "http://localhost:3300/network/23sf4g65as-asdgsg2-sdfgsf2g"
310
- # post "/storage/", collection # => "http://localhost:3300/storage/23sf4g65as-asdgsg2-sdfgsf2g"
311
- #
312
- # @param [String] path for the POST request
313
- # @param [Occi::Collection] resource data to be POSTed
314
- # @return [String] URI location
315
- def post(path, collection)
316
- raise ArgumentError, "Path is a required argument!" if path.blank?
317
-
318
- headers = self.class.headers.clone
319
- headers['Content-Type'] = @media_type
320
-
321
- path = "#{@endpoint.to_s}#{path}"
322
-
323
- response = case @media_type
324
- when 'application/occi+json'
325
- self.class.post(path,
326
- :body => collection.to_json,
327
- :headers => headers)
328
- when 'text/occi'
329
- self.class.post(path,
330
- :headers => collection.to_header.merge(headers))
331
- else
332
- self.class.post(path,
333
- :body => collection.to_text,
334
- :headers => headers)
335
- end
336
-
337
- response_msg = response_message(response)
338
-
339
- case response.code
340
- when 200
341
- collection = Occi::Parser.parse(response.header["content-type"].split(";").first, response.body)
342
-
343
- if collection.empty?
344
- Occi::Parser.locations(response.header["content-type"].split(";").first, response.body, response.headers).first
345
- else
346
- collection.resources.first.location if collection.resources.first
347
- end
348
- when 201
349
- # TODO: OCCI-OS hack, look for header Location instead of uri-list
350
- # This should be probably implemented in Occi::Parser.locations
351
- if response.header['location']
352
- response.header['location']
353
- else
354
- Occi::Parser.locations(response.header["content-type"].split(";").first, response.body, response.headers).first
355
- end
356
- else
357
- raise "HTTP POST failed! #{response_msg}"
358
- end
359
- end
360
-
361
- # Performs PUT requests and parses responses to collections.
362
- #
363
- # @example
364
- # TODO: add examples
365
- #
366
- # @param [String] path for the PUT request
367
- # @param [Occi::Collection] resource data to send
368
- # @return [Occi::Collection] parsed result of the request
369
- def put(path, collection)
370
- raise ArgumentError, "Path is a required argument!" if path.blank?
371
-
372
- headers = self.class.headers.clone
373
- headers['Content-Type'] = @media_type
374
-
375
- path = "#{@endpoint.to_s}#{path}"
376
-
377
- response = case @media_type
378
- when 'application/occi+json'
379
- self.class.post(path,
380
- :body => collection.to_json,
381
- :headers => headers)
382
- when 'text/occi'
383
- self.class.post(path,
384
- :headers => collection.to_header.merge(headers))
385
- else
386
- self.class.post(path,
387
- :body => collection.to_text,
388
- :headers => headers)
389
- end
390
-
391
- response_msg = response_message(response)
392
-
393
- case response.code
394
- when 200, 201
395
- Occi::Parser.parse(response.header["content-type"].split(";").first, response.body)
396
- else
397
- raise "HTTP POST failed! #{response_msg}"
398
- end
399
- end
131
+ if location.include? '.ovf'
132
+ deploy_ovf file
133
+ elsif location.include? '.ova'
134
+ deploy_ova file
135
+ else
136
+ raise "Unsupported descriptor format! Only OVF or OVA files are supported."
137
+ end
138
+ end
400
139
 
401
- # Performs DELETE requests and returns True on success.
402
- #
403
- # @example
404
- # del "/compute/65sf4g65sf4g-sf6g54sf5g-sfgsf32g3" # => true
405
- #
406
- # @param [String] path for the DELETE request
407
- # @param [Occi::Collection] collection of filters (currently NOT used)
408
- # @return [Boolean] status
409
- def del(path, filter=nil)
410
- raise ArgumentError, "Path is a required argument!" if path.blank?
140
+ # @see Occi::Api::Client::ClientBase
141
+ def deploy_ovf(descriptor)
142
+ media_types = self.class.head('/').headers['accept'].to_s
143
+
144
+ path = path_for_kind_type_identifier(Occi::Infrastructure::Compute.type_identifier)
145
+ if media_types.include? 'application/ovf'
146
+ headers = self.class.headers.clone
147
+ headers['Content-Type'] = 'application/ovf'
148
+ self.class.post(path,
149
+ :body => descriptor,
150
+ :headers => headers)
151
+ else
152
+ raise "Unsupported descriptor format! Server does not support OVF descriptors."
153
+ end
154
+ end
411
155
 
412
- response = self.class.delete("#{@endpoint.to_s}#{path}")
156
+ # @see Occi::Api::Client::ClientBase
157
+ def deploy_ova(descriptor)
158
+ media_types = self.class.head('/').headers['accept'].to_s
159
+
160
+ path = path_for_kind_type_identifier(Occi::Infrastructure::Compute.type_identifier)
161
+ if media_types.include? ' application/ova '
162
+ headers = self.class.headers.clone
163
+ headers['Content-Type'] = 'application/ova'
164
+ self.class.post(path,
165
+ :body => descriptor,
166
+ :headers => headers)
167
+ else
168
+ raise "Unsupported descriptor format! Server does not support OVA descriptors."
169
+ end
170
+ end
413
171
 
414
- response_msg = response_message(response)
415
- raise "HTTP DELETE failed! #{response_msg}" unless response.code.between? 200, 300
172
+ # @see Occi::Api::Client::ClientBase
173
+ def delete(resource_type_identifier)
174
+ raise 'Resource not provided!' if resource_type_identifier.blank?
175
+ path = path_for_kind_type_identifier(resource_type_identifier)
416
176
 
417
- true
418
- end
177
+ Occi::Log.debug("Deleting #{path.inspect} for #{resource_type_identifier.inspect}")
178
+ del path
179
+ end
419
180
 
420
- # @see Occi::Api::Client::ClientBase
421
- def get_logger(log_options)
422
- logger = super(log_options)
423
- self.class.debug_output $stderr if logger.level == Occi::Log::DEBUG
181
+ # @see Occi::Api::Client::ClientBase
182
+ def trigger(resource_type_identifier, action_instance)
183
+ # TODO: not tested
184
+ raise 'Resource not provided!' if resource_type_identifier.blank?
424
185
 
425
- logger
426
- end
186
+ #
187
+ resource_type_identifier = get_resource_type_identifier(resource_type_identifier)
188
+ path = path_for_kind_type_identifier(resource_type_identifier)
427
189
 
428
- # @see Occi::Api::Client::ClientBase
429
- def get_auth(auth_options, fallback = false)
430
- # select appropriate authN type
431
- case auth_options[:type]
432
- when "basic"
433
- @authn_plugin = Http::AuthnPlugins::Basic.new self, auth_options
434
- when "digest"
435
- @authn_plugin = Http::AuthnPlugins::Digest.new self, auth_options
436
- when "x509"
437
- @authn_plugin = Http::AuthnPlugins::X509.new self, auth_options
438
- when "keystone"
439
- raise ::Occi::Api::Client::Errors::AuthnError, "This authN method is for fallback only!" unless fallback
440
- @authn_plugin = Http::AuthnPlugins::Keystone.new self, auth_options
441
- when "none", nil
442
- @authn_plugin = Http::AuthnPlugins::Dummy.new self
443
- else
444
- raise ::Occi::Api::Client::Errors::AuthnError, "Unknown authN method [#{@auth_options[:type]}]!"
445
- end
446
-
447
- @authn_plugin.setup
448
-
449
- auth_options
450
- end
190
+ # make the request
191
+ post path, action_instance
192
+ end
451
193
 
452
- # @see Occi::Api::Client::ClientBase
453
- def preauthenticate
454
- begin
455
- @authn_plugin.authenticate
456
- rescue ::Occi::Api::Client::Errors::AuthnError => e
457
- Occi::Log.debug e.message
458
-
459
- if @authn_plugin.fallbacks.any?
460
- # TODO: multiple fallbacks
461
- @auth_options[:original_type] = @auth_options[:type]
462
- @auth_options[:type] = @authn_plugin.fallbacks.first
463
-
464
- @auth_options = get_auth(@auth_options, true)
465
- @authn_plugin.authenticate
466
- else
467
- raise e
468
- end
469
- end
470
- end
194
+ # @see Occi::Api::Client::ClientBase
195
+ def refresh
196
+ # re-download the model from the server
197
+ model_collection = get('/-/')
198
+ @model = get_model(model_collection)
199
+ end
471
200
 
472
- # @see Occi::Api::Client::ClientBase
473
- def get_media_type(force_type = nil)
474
- # force media_type if provided
475
- unless force_type.blank?
476
- self.class.headers 'Accept' => force_type
477
- media_type = force_type
478
- else
479
- media_types = self.class.head(@endpoint.to_s).headers['accept']
480
-
481
- Occi::Log.debug("Available media types: #{media_types.inspect}")
482
- media_type = case media_types
483
- when /application\/occi\+json/
484
- 'application/occi+json'
485
- when /application\/occi\+xml/
486
- 'application/occi+xml'
487
- when /text\/occi/
488
- 'text/occi'
489
- else
490
- 'text/plain'
491
- end
492
- end
493
-
494
- media_type
495
- end
201
+ private
496
202
 
497
- # Generates a human-readable response message based on the HTTP response code.
498
- #
499
- # @example
500
- # response_message self.class.delete(@endpoint.to_s + path)
501
- # # => 'HTTP Response status: [200] OK'
502
- #
503
- # @param [HTTParty::Response] HTTParty response object
504
- # @return [String] message
505
- def response_message(response)
506
- @last_response = response
507
- "HTTP Response status: [#{response.code.to_s}] #{reason_phrase(response.code)}"
508
- end
203
+ # include HTTParty wrappers
204
+ include Occi::Api::Client::Http::PartyWrappers
509
205
 
510
- # Converts HTTP response codes to human-readable phrases.
511
- #
512
- # @example
513
- # reason_phrase(500) # => "Internal Server Error"
514
- #
515
- # @param [Integer] HTTP response code
516
- # @return [String] human-readable phrase
517
- def reason_phrase(code)
518
- HTTP_CODES[code.to_s]
519
- end
206
+ # include various helper methods (media type stuff, authN, etc.)
207
+ include Occi::Api::Client::Http::Helpers
520
208
 
521
- end
209
+ # include methods dealing with HTTP codes
210
+ include Occi::Api::Client::Http::CodeHelpers
522
211
 
523
- end
524
212
  end
213
+
525
214
  end