occi-api 4.2.0.beta.2 → 4.2.0.beta.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,13 +5,8 @@ module Occi
5
5
  class ClientBase
6
6
 
7
7
  # a few attributes which should be visible outside the client
8
- attr_reader :endpoint
9
- attr_reader :auth_options
10
- attr_reader :media_type
11
- attr_reader :connected
12
- attr_reader :model
13
- attr_reader :logger
14
- attr_reader :last_response
8
+ attr_reader :endpoint, :auth_options, :media_type
9
+ attr_reader :connected, :model, :logger, :last_response
15
10
  attr_reader :options
16
11
 
17
12
  def initialize(options = {})
@@ -23,17 +18,17 @@ module Occi
23
18
  :media_type => nil
24
19
  }
25
20
 
26
- options = options.marshal_dump if options.is_a? OpenStruct
27
- @options = defaults.merge options
21
+ options = options.marshal_dump if options.is_a?(OpenStruct)
22
+ @options = defaults.merge(options)
28
23
 
29
24
  # set Occi::Log
30
- set_logger @options[:log]
25
+ @logger = get_logger(@options[:log])
31
26
 
32
27
  # check the validity and canonize the endpoint URI
33
- set_endpoint @options[:endpoint]
28
+ @endpoint = get_endpoint_uri(@options[:endpoint])
34
29
 
35
30
  # pass auth options
36
- set_auth @options[:auth]
31
+ @auth_options = get_auth(@options[:auth])
37
32
 
38
33
  # verify authN before attempting actual
39
34
  # message exchange with the server; this
@@ -42,7 +37,7 @@ module Occi
42
37
  preauthenticate
43
38
 
44
39
  # set accepted media types
45
- set_media_type @options[:media_type]
40
+ @media_type = get_media_type(@options[:media_type])
46
41
 
47
42
  @connected = false
48
43
  end
@@ -82,7 +77,9 @@ module Occi
82
77
  #
83
78
  # @param [String] resource type identifier or just type name
84
79
  # @return [Array<String>] list of links
85
- def list(resource_type_identifier=nil); end
80
+ def list(resource_type_identifier=nil)
81
+ raise Occi::Api::Client::Errors::NotImplementedError, "#{__method__} is just a stub!"
82
+ end
86
83
 
87
84
  # Retrieves descriptions for available resources specified by a type
88
85
  # identifier or resource location. If no type identifier or location
@@ -101,7 +98,9 @@ module Occi
101
98
  #
102
99
  # @param [String] resource type identifier, type name or resource location
103
100
  # @return [Occi::Core::Resources] list of resource descriptions
104
- def describe(resource_type_identifier=nil); end
101
+ def describe(resource_type_identifier=nil)
102
+ raise Occi::Api::Client::Errors::NotImplementedError, "#{__method__} is just a stub!"
103
+ end
105
104
 
106
105
  # Creates a new resource on the server. Resource must be provided
107
106
  # as an instance of Occi::Core::Entity, e.g. instantiated using
@@ -118,7 +117,9 @@ module Occi
118
117
  #
119
118
  # @param [Occi::Core::Entity] resource to be created on the server
120
119
  # @return [String] URI of the new resource
121
- def create(entity); end
120
+ def create(entity)
121
+ raise Occi::Api::Client::Errors::NotImplementedError, "#{__method__} is just a stub!"
122
+ end
122
123
 
123
124
  # Deploys a compute resource based on an OVF/OVA descriptor available
124
125
  # on a local file system.
@@ -128,7 +129,9 @@ module Occi
128
129
  #
129
130
  # @param [String] location of an OVF/OVA file
130
131
  # @return [String] URI of the new resource
131
- def deploy(location); end
132
+ def deploy(location)
133
+ raise Occi::Api::Client::Errors::NotImplementedError, "#{__method__} is just a stub!"
134
+ end
132
135
 
133
136
  # Deploys a compute resource based on an OVF descriptor available
134
137
  # directly as a String.
@@ -138,7 +141,9 @@ module Occi
138
141
  #
139
142
  # @param [String] OVF descriptor (e.g., already read from a file or generated)
140
143
  # @return [String] URI of the new resource
141
- def deploy_ovf(descriptor); end
144
+ def deploy_ovf(descriptor)
145
+ raise Occi::Api::Client::Errors::NotImplementedError, "#{__method__} is just a stub!"
146
+ end
142
147
 
143
148
  # Deploys a compute resource based on an OVA descriptor available
144
149
  # directly as a String.
@@ -148,7 +153,9 @@ module Occi
148
153
  #
149
154
  # @param [String] OVA descriptor (e.g., already read from a file or generated)
150
155
  # @return [String] URI of the new resource
151
- def deploy_ova(descriptor); end
156
+ def deploy_ova(descriptor)
157
+ raise Occi::Api::Client::Errors::NotImplementedError, "#{__method__} is just a stub!"
158
+ end
152
159
 
153
160
  # Deletes a resource or all resource of a certain resource type
154
161
  # from the server.
@@ -160,17 +167,21 @@ module Occi
160
167
  #
161
168
  # @param [String] resource type identifier, type name or location
162
169
  # @return [Boolean] status
163
- def delete(resource_type_identifier); end
170
+ def delete(resource_type_identifier)
171
+ raise Occi::Api::Client::Errors::NotImplementedError, "#{__method__} is just a stub!"
172
+ end
164
173
 
165
174
  # Triggers given action on a specific resource.
166
175
  #
167
176
  # @example
168
177
  # TODO: add examples
169
178
  #
170
- # @param [String] resource location
171
- # @param [String] type of action
179
+ # @param [String] resource type or type identifier
180
+ # @param [Occi::Core::ActionInstance] type of action
172
181
  # @return [String] resource location
173
- def trigger(resource_type_identifier, action); end
182
+ def trigger(resource_type_identifier, action_instance)
183
+ raise Occi::Api::Client::Errors::NotImplementedError, "#{__method__} is just a stub!"
184
+ end
174
185
 
175
186
  # Refreshes the Occi::Model used inside the client. Useful for
176
187
  # updating the model without creating a new instance or
@@ -178,7 +189,9 @@ module Occi
178
189
  #
179
190
  # @example
180
191
  # client.refresh
181
- def refresh; end
192
+ def refresh
193
+ raise Occi::Api::Client::Errors::NotImplementedError, "#{__method__} is just a stub!"
194
+ end
182
195
 
183
196
  ##############################################################################
184
197
  ######## STUBS END
@@ -196,36 +209,121 @@ module Occi
196
209
  # @param [String] resource name or resource identifier
197
210
  # @return [Occi::Core::Resource] new resource instance
198
211
  def get_resource(resource_type)
199
- Occi::Log.debug("Instantiating #{resource_type} ...")
200
-
201
- type_id = if @model.get_by_id resource_type
202
- # we got a resource type identifier
203
- resource_type
204
- else
205
- # we got a resource type name
206
- type_ids = @model.kinds.to_a.select { |kind| kind.term == resource_type }
207
- type_ids.first.type_identifier if type_ids.any?
208
- end
212
+ Occi::Log.debug("Instantiating #{resource_type.inspect}")
209
213
 
214
+ type_id = get_resource_type_identifier(resource_type)
210
215
  raise "Unknown resource type! #{resource_type.inspect}" unless type_id
211
216
 
212
- Occi::Core::Resource.new type_id
217
+ new_resource = Occi::Core::Resource.new(type_id)
218
+ new_resource.model = @model
219
+
220
+ new_resource
213
221
  end
214
222
 
215
- # Retrieves all entity type identifiers related to a given type identifier
223
+ # Retrieves all available category types.
216
224
  #
217
225
  # @example
218
- # client.get_entity_type_identifiers_related_to 'network'
226
+ # client.get_category_types # => [ "entity", "resource", "link" ]
227
+ #
228
+ # @return [Array<String>] list of available category types in a human-readable format
229
+ def get_category_types
230
+ @model.categories.to_a.collect { |category| category.term }
231
+ end
232
+
233
+ # Retrieves all available category type identifiers.
234
+ #
235
+ # @example
236
+ # client.get_category_type_identifiers
237
+ # # => [ "http://schemas.ogf.org/occi/core#entity",
238
+ # # "http://schemas.ogf.org/occi/core#resource",
239
+ # # "http://schemas.ogf.org/occi/core#link" ]
240
+ #
241
+ # @return [Array<String>] list of available category type identifiers
242
+ def get_category_type_identifiers
243
+ @model.categories.to_a.collect { |category| category.type_identifier }
244
+ end
245
+
246
+ # Retrieves available category type identifier for the given category type.
247
+ #
248
+ # @example
249
+ # client.get_category_type_identifier("compute")
250
+ # # => 'http://schemas.ogf.org/occi/infrastructure#compute'
251
+ #
252
+ # @return [String, nil] category type identifier for the given category type
253
+ def get_category_type_identifier(type)
254
+ return type if (type =~ URI::ABS_URI) || (type && type.start_with?('/'))
255
+
256
+ cats = @model.categories.to_a.select { |k| k.term == type }
257
+ tis = cats.collect { |c| c.type_identifier }
258
+ tis.uniq!
259
+
260
+ if tis.length > 1
261
+ raise Occi::Api::Client::Errors::AmbiguousNameError,
262
+ "Category type #{type.inspect} is ambiguous, use a type identifier!"
263
+ end
264
+
265
+ tis.first
266
+ end
267
+
268
+ # Retrieves all kind type identifiers related to a given type identifier
269
+ #
270
+ # @example
271
+ # client.get_kind_type_identifiers_related_to 'http://schemas.ogf.org/occi/infrastructure#network'
219
272
  # # => [ "http://schemas.ogf.org/occi/infrastructure#network",
220
273
  # # "http://schemas.ogf.org/occi/infrastructure#ipnetwork" ]
221
274
  #
222
- # @param [String] type_identifier
223
- # @return [Array<String>] list of available entity type identifiers related to
224
- # given type identifier in a human-readable format
225
- def get_entity_types_related_to(type_identifier)
226
- Occi::Log.debug("Getting entity type identifiers related to #{type_identifier}")
227
- collection = @model.get type_identifier
228
- collection.kinds.collect { |kind| kind.type_identifier }
275
+ # @param [String] type identifier
276
+ # @return [Array<String>] list of available kind type identifiers related to
277
+ # the given type identifier
278
+ def get_kind_type_identifiers_related_to(type_identifier)
279
+ Occi::Log.debug("Getting kind type identifiers related to #{type_identifier.inspect}")
280
+ collection = @model.get(type_identifier)
281
+ collection.kinds.to_a.collect { |kind| kind.type_identifier }
282
+ end
283
+
284
+ # Retrieves all available kind types.
285
+ #
286
+ # @example
287
+ # client.get_kind_types # => [ "entity", "resource", "link" ]
288
+ #
289
+ # @return [Array<String>] list of available kind types in a human-readable format
290
+ def get_kind_types
291
+ @model.kinds.to_a.collect { |kind| kind.term }
292
+ end
293
+
294
+ # Retrieves all available kind type identifiers.
295
+ #
296
+ # @example
297
+ # client.get_kind_type_identifiers
298
+ # # => [ "http://schemas.ogf.org/occi/core#entity",
299
+ # # "http://schemas.ogf.org/occi/core#resource",
300
+ # # "http://schemas.ogf.org/occi/core#link" ]
301
+ #
302
+ # @return [Array<String>] list of available kind type identifiers
303
+ def get_kind_type_identifiers
304
+ @model.kinds.to_a.collect { |kind| kind.type_identifier }
305
+ end
306
+
307
+ # Retrieves available kind type identifier for the given kind type.
308
+ #
309
+ # @example
310
+ # client.get_kind_type_identifier("compute")
311
+ # # => 'http://schemas.ogf.org/occi/infrastructure#compute'
312
+ #
313
+ # @return [String, nil] kind type identifier for the given kind type
314
+ def get_kind_type_identifier(type)
315
+ return type if (type =~ URI::ABS_URI) || (type && type.start_with?('/'))
316
+
317
+ kinds = @model.kinds.to_a.select { |k| k.term == type }
318
+ tis = kinds.collect { |k| k.type_identifier }
319
+ tis.uniq!
320
+
321
+ if tis.length > 1
322
+ raise Occi::Api::Client::Errors::AmbiguousNameError,
323
+ "Kind type #{type.inspect} is ambiguous, use a type identifier!"
324
+ end
325
+
326
+ tis.first
229
327
  end
230
328
 
231
329
  # Retrieves all available entity types.
@@ -235,21 +333,44 @@ module Occi
235
333
  #
236
334
  # @return [Array<String>] list of available entity types in a human-readable format
237
335
  def get_entity_types
238
- Occi::Log.debug("Getting entity types ...")
239
- @model.kinds.to_a.collect { |kind| kind.term }
336
+ collection = @model.get(Occi::Core::Entity.kind.type_identifier)
337
+ collection.kinds.to_a.collect { |kind| kind.term }
240
338
  end
241
339
 
242
340
  # Retrieves all available entity type identifiers.
243
341
  #
244
342
  # @example
245
- # client.get_entity_type_identifiers
343
+ # client.get_kind_type_identifiers
246
344
  # # => [ "http://schemas.ogf.org/occi/core#entity",
247
345
  # # "http://schemas.ogf.org/occi/core#resource",
248
346
  # # "http://schemas.ogf.org/occi/core#link" ]
249
347
  #
250
348
  # @return [Array<String>] list of available entity types in a OCCI ID format
251
349
  def get_entity_type_identifiers
252
- get_entity_types_related_to Occi::Core::Entity.kind.type_identifier
350
+ get_kind_type_identifiers_related_to Occi::Core::Entity.kind.type_identifier
351
+ end
352
+
353
+ # Retrieves available entity type identifier for the given entity type.
354
+ #
355
+ # @example
356
+ # client.get_entity_type_identifier("compute")
357
+ # # => 'http://schemas.ogf.org/occi/infrastructure#compute'
358
+ #
359
+ # @return [String, nil] entity type identifier for the given entity type
360
+ def get_entity_type_identifier(type)
361
+ return type if (type =~ URI::ABS_URI) || (type && type.start_with?('/'))
362
+
363
+ collection = @model.get(Occi::Core::Entity.kind.type_identifier)
364
+ e_kinds = collection.kinds.to_a.select { |e| e.term == type }
365
+ tis = e_kinds.collect { |e| e.type_identifier }
366
+ tis.uniq!
367
+
368
+ if tis.length > 1
369
+ raise Occi::Api::Client::Errors::AmbiguousNameError,
370
+ "Entity type #{type.inspect} is ambiguous, use a type identifier!"
371
+ end
372
+
373
+ tis.first
253
374
  end
254
375
 
255
376
  # Retrieves all available resource types.
@@ -259,9 +380,8 @@ module Occi
259
380
  #
260
381
  # @return [Array<String>] list of available resource types in a human-readable format
261
382
  def get_resource_types
262
- Occi::Log.debug("Getting resource types ...")
263
- collection = @model.get Occi::Core::Resource.kind
264
- collection.kinds.collect { |kind| kind.term }
383
+ collection = @model.get(Occi::Core::Resource.kind.type_identifier)
384
+ collection.kinds.to_a.collect { |kind| kind.term }
265
385
  end
266
386
 
267
387
  # Retrieves all available resource type identifiers.
@@ -274,7 +394,30 @@ module Occi
274
394
  #
275
395
  # @return [Array<String>] list of available resource types in a Occi ID format
276
396
  def get_resource_type_identifiers
277
- get_entity_types_related_to Occi::Core::Resource.kind.type_identifier
397
+ get_kind_type_identifiers_related_to Occi::Core::Resource.kind.type_identifier
398
+ end
399
+
400
+ # Retrieves available resource type identifier for the given resource type.
401
+ #
402
+ # @example
403
+ # client.get_resource_type_identifier("compute")
404
+ # # => 'http://schemas.ogf.org/occi/infrastructure#compute'
405
+ #
406
+ # @return [String, nil] resource type identifier for the given resource type
407
+ def get_resource_type_identifier(type)
408
+ return type if (type =~ URI::ABS_URI) || (type && type.start_with?('/'))
409
+
410
+ collection = @model.get(Occi::Core::Resource.kind.type_identifier)
411
+ r_kinds = collection.kinds.to_a.select { |r| r.term == type }
412
+ tis = r_kinds.collect { |r| r.type_identifier }
413
+ tis.uniq!
414
+
415
+ if tis.length > 1
416
+ raise Occi::Api::Client::Errors::AmbiguousNameError,
417
+ "Resource type #{type.inspect} is ambiguous, use a type identifier!"
418
+ end
419
+
420
+ tis.first
278
421
  end
279
422
 
280
423
  # Retrieves all available link types.
@@ -284,9 +427,8 @@ module Occi
284
427
  #
285
428
  # @return [Array<String>] list of available link types in a human-readable format
286
429
  def get_link_types
287
- Occi::Log.debug("Getting link types ...")
288
- collection = @model.get Occi::Core::Link.kind
289
- collection.kinds.collect { |kind| kind.term }
430
+ collection = @model.get(Occi::Core::Link.kind.type_identifier)
431
+ collection.kinds.to_a.collect { |kind| kind.term }
290
432
  end
291
433
 
292
434
  # Retrieves all available link type identifiers.
@@ -298,7 +440,30 @@ module Occi
298
440
  #
299
441
  # @return [Array<String>] list of available link types in a OCCI ID format
300
442
  def get_link_type_identifiers
301
- get_entity_types_related_to Occi::Core::Link.kind.type_identifier
443
+ get_kind_type_identifiers_related_to Occi::Core::Link.kind.type_identifier
444
+ end
445
+
446
+ # Retrieves available link type identifier for the given link type.
447
+ #
448
+ # @example
449
+ # client.get_link_type_identifier("storagelink")
450
+ # # => 'http://schemas.ogf.org/occi/infrastructure#storagelink'
451
+ #
452
+ # @return [String, nil] link type identifier for the given link type
453
+ def get_link_type_identifier(type)
454
+ return type if (type =~ URI::ABS_URI) || (type && type.start_with?('/'))
455
+
456
+ collection = @model.get(Occi::Core::Link.kind.type_identifier)
457
+ l_kinds = collection.kinds.to_a.select { |r| r.term == type }
458
+ tis = l_kinds.collect { |r| r.type_identifier }
459
+ tis.uniq!
460
+
461
+ if tis.length > 1
462
+ raise Occi::Api::Client::Errors::AmbiguousNameError,
463
+ "Link type #{type.inspect} is ambiguous, use a type identifier!"
464
+ end
465
+
466
+ tis.first
302
467
  end
303
468
 
304
469
  # Looks up a mixin using its name and, optionally, a type as well.
@@ -404,16 +569,16 @@ module Occi
404
569
  # @return [Occi::Core::Mixins] collection of available mixins
405
570
  def get_mixins(type = nil)
406
571
  unless type.blank?
407
- unless get_mixin_types.include?(type) || get_mixin_type_identifiers.include?(type)
572
+ type_id = get_mixin_type_identifier(type)
573
+ unless type_id
408
574
  raise ArgumentError,
409
575
  "There is no such mixin type registered in the model! #{type.inspect}"
410
576
  end
411
577
 
412
- type = get_mixin_type_identifier(type) if get_mixin_types.include?(type)
413
- mixins = @model.mixins.to_a.select { |m| m.related_to?(type) }
578
+ mixins = @model.mixins.to_a.select { |m| m.related_to?(type_id) }
414
579
 
415
580
  # drop the type mixin itself
416
- mixins.delete_if { |m| m.type_identifier == type }
581
+ mixins.delete_if { |m| m.type_identifier == type_id }
417
582
  else
418
583
  # we did not get a type, return all mixins
419
584
  mixins = Occi::Core::Mixins.new(@model.mixins)
@@ -479,8 +644,18 @@ module Occi
479
644
  #
480
645
  # @return [String, nil] mixin type identifier for the given mixin type
481
646
  def get_mixin_type_identifier(type)
482
- mixins = get_mixins.to_a.select { |m| m.term == type }
483
- mixins.collect { |m| m.type_identifier }.first
647
+ return type if (type =~ URI::ABS_URI) || (type && type.start_with?('/'))
648
+
649
+ mixins = @model.mixins.to_a.select { |m| m.term == type }
650
+ tis = mixins.collect { |m| m.type_identifier }
651
+ tis.uniq!
652
+
653
+ if tis.length > 1
654
+ raise Occi::Api::Client::Errors::AmbiguousNameError,
655
+ "Mixin type #{type.inspect} is ambiguous, use a type identifier!"
656
+ end
657
+
658
+ tis.first
484
659
  end
485
660
 
486
661
  # Retrieves available os_tpls from the model.
@@ -490,7 +665,7 @@ module Occi
490
665
  #
491
666
  # @return [Occi::Core::Mixins] collection containing all registered OS templates
492
667
  def get_os_templates
493
- get_mixins "http://schemas.ogf.org/occi/infrastructure#os_tpl"
668
+ get_mixins Occi::Infrastructure::OsTpl.mixin.type_identifier
494
669
  end
495
670
  alias_method :get_os_tpls, :get_os_templates
496
671
 
@@ -501,53 +676,90 @@ module Occi
501
676
  #
502
677
  # @return [Occi::Core::Mixins] collection containing all registered resource templates
503
678
  def get_resource_templates
504
- get_mixins "http://schemas.ogf.org/occi/infrastructure#resource_tpl"
679
+ get_mixins Occi::Infrastructure::ResourceTpl.mixin.type_identifier
505
680
  end
506
681
  alias_method :get_resource_tpls, :get_resource_templates
507
682
 
508
- # Returns the path for a given resource type identifier
683
+ # Returns the path for a given kind type identifier
509
684
  #
510
685
  # @example
511
- # path_for_resource_type "http://schemas.ogf.org/occi/infrastructure#compute"
686
+ # path_for_kind_type_identifier "http://schemas.ogf.org/occi/infrastructure#compute"
512
687
  # # => "/compute/"
513
- # path_for_resource_type "http://localhost:3300/compute/35ad4f45gsf-gsfg524s6gsfg-sfgsf4gsfg"
688
+ # path_for_kind_type_identifier "http://localhost:3300/compute/35ad4f45gsf-gsfg524s6gsfg-sfgsf4gsfg"
514
689
  # # => "/compute/35ad4f45gsf-gsfg524s6gsfg-sfgsf4gsfg"
515
690
  #
516
- # @param [String] resource type identifier
691
+ # @param [String] kind type identifier
517
692
  # @return [String]
518
- def path_for_resource_type(resource_type_identifier)
519
- return "/" if resource_type_identifier.nil? || resource_type_identifier == "/"
520
-
521
- kinds = @model.kinds.select { |kind| kind.term == resource_type_identifier }
522
- if kinds.any?
523
- #we got an type identifier
524
- path = "/" + kinds.first.type_identifier.split('#').last + "/"
525
- elsif resource_type_identifier.start_with?(@endpoint) || resource_type_identifier.start_with?('/')
526
- #we got an resource link
527
- path = sanitize_resource_link(resource_type_identifier)
528
- else
529
- raise "Unknown resource identifier! #{resource_type_identifier.inspect}"
693
+ def path_for_kind_type_identifier(kind_type_identifier)
694
+ raise ArgumentError,
695
+ "Kind type identifier is a required argument!" if kind_type_identifier.blank?
696
+
697
+ if kind_type_identifier.start_with?(@endpoint.to_s) || kind_type_identifier.start_with?('/')
698
+ #we got an instance link
699
+ return sanitize_instance_link(kind_type_identifier)
700
+ end
701
+
702
+ kind_type_id = get_kind_type_identifier(kind_type_identifier)
703
+ unless kind_type_id
704
+ raise ArgumentError,
705
+ "There is no such kind type registered in the model! #{kind_type_identifier.inspect}"
706
+ end
707
+
708
+ kinds = @model.kinds.select { |kind| kind.type_identifier == kind_type_id }
709
+ path_for_instance(kinds.first)
710
+ end
711
+
712
+ # Returns the path for a given instance, instances not providing
713
+ # path information will raise an exception.
714
+ #
715
+ # @example
716
+ # path_for_instance Occi::Infrastructure::Network.new
717
+ # # => "/network/35ad4f45gsf-gsfg524s6gsfg-sfgsf4gsfg"
718
+ # path_for_instance Occi::Infrastructure::Compute.new
719
+ # # => "/compute/35ad4f45gsf-gsfg524s6gsfg-sfgsf4gsfg"
720
+ # path_for_instance Occi::Core::Mixin.new
721
+ # # => "/mixin/my_mixin/"
722
+ # path_for_instance Occi::Infrastructure::Storagelink.new
723
+ # # => "/link/storagelink/35ad4f45gsf-gsfg524s6gsfg-sfgsf4gsfg"
724
+ #
725
+ # @param [Object] instance
726
+ # @return [String] path for the given instance
727
+ def path_for_instance(instance)
728
+ unless instance.respond_to?(:location)
729
+ raise Occi::Api::Client::Errors::TypeMismatchError,
730
+ "Expected an instance responding to #location, " \
731
+ "got #{instance.class.name.inspect}"
732
+ end
733
+
734
+ if instance.location.blank?
735
+ raise Occi::Api::Client::Errors::LocationError,
736
+ "Instance of #{instance.class.name.inspect} has " \
737
+ "an empty location"
530
738
  end
739
+
740
+ instance.location
531
741
  end
532
742
 
533
- # Extracts the resource path from a resource link. It will remove the leading @endpoint
743
+ # Extracts path from an instance link. It will remove the leading @endpoint
534
744
  # and replace it with a slash.
535
745
  #
536
746
  # @example
537
- # sanitize_resource_link "http://localhost:3300/compute/35ad4f45gsf-gsfg524s6gsfg-sfgsf4gsfg"
747
+ # sanitize_instance_link "http://localhost:3300/compute/35ad4f45gsf-gsfg524s6gsfg-sfgsf4gsfg"
538
748
  # # => "/compute/35ad4f45gsf-gsfg524s6gsfg-sfgsf4gsfg"
539
- # sanitize_resource_link "/compute/35ad4f45gsf-gsfg524s6gsfg-sfgsf4gsfg"
749
+ # sanitize_instance_link "/compute/35ad4f45gsf-gsfg524s6gsfg-sfgsf4gsfg"
540
750
  # # => "/compute/35ad4f45gsf-gsfg524s6gsfg-sfgsf4gsfg"
541
751
  #
542
- # @param [String] string containing the full resource link
752
+ # @param [String] string containing the full instance link
543
753
  # @return [String] extracted path, with a leading slash
544
- def sanitize_resource_link(resource_link)
754
+ def sanitize_instance_link(instance_link)
545
755
  # everything starting with '/' is considered to be a resource path
546
- return resource_link if resource_link.start_with? '/'
756
+ return instance_link if instance_link.start_with? '/'
547
757
 
548
- raise "Resource link #{resource_link.inspect} is not valid!" unless resource_link.start_with? @endpoint
758
+ unless instance_link.start_with?(@endpoint.to_s)
759
+ raise ArgumentError, "Resource link #{instance_link.inspect} is not valid!"
760
+ end
549
761
 
550
- resource_link.gsub @endpoint, '/'
762
+ URI(instance_link).request_uri
551
763
  end
552
764
 
553
765
  protected
@@ -560,29 +772,36 @@ module Occi
560
772
  # are: ["basic", "digest", "x509", "none"]
561
773
  #
562
774
  # @example
563
- # set_auth { :type => "none" }
564
- # set_auth { :type => "basic", :username => "123", :password => "321" }
565
- # set_auth { :type => "digest", :username => "123", :password => "321" }
566
- # set_auth { :type => "x509", :user_cert => "~/cert.pem",
775
+ # get_auth { :type => "none" }
776
+ # get_auth { :type => "basic", :username => "123", :password => "321" }
777
+ # get_auth { :type => "digest", :username => "123", :password => "321" }
778
+ # get_auth { :type => "x509", :user_cert => "~/cert.pem",
567
779
  # :user_cert_password => "321", :ca_path => nil }
568
780
  #
569
781
  # @param [Hash] authentication options
570
782
  # @param [Boolean] allow fallback-only options
571
- def set_auth(auth_options, fallback = false); end
783
+ # @return [Hash] transformed hash with authN information
784
+ def get_auth(auth_options, fallback = false)
785
+ raise Occi::Api::Client::Errors::NotImplementedError, "#{__method__} is just a stub!"
786
+ end
572
787
 
573
788
  # Attempts to establish a preliminary connection with the server
574
789
  # to verify provided credentials and perform fallback authN
575
- # if necessary. Has to be invoked after set_auth
576
- def preauthenticate; end
790
+ # if necessary. Has to be invoked after @auth_options have been set.
791
+ def preauthenticate
792
+ raise Occi::Api::Client::Errors::NotImplementedError, "#{__method__} is just a stub!"
793
+ end
577
794
 
578
795
  # Sets media type. Will choose either application/occi+json or text/plain
579
796
  # based on the formats supported by the server.
580
797
  #
581
798
  # @example
582
- # set_media_type # => 'application/occi+json'
799
+ # get_media_type # => 'application/occi+json'
583
800
  #
584
801
  # @return [String] chosen media type
585
- def set_media_type(force_type = nil); end
802
+ def get_media_type(force_type = nil)
803
+ raise Occi::Api::Client::Errors::NotImplementedError, "#{__method__} is just a stub!"
804
+ end
586
805
 
587
806
  ##############################################################################
588
807
  ######## STUBS END
@@ -592,40 +811,52 @@ module Occi
592
811
  # instances to the rOCCI client.
593
812
  #
594
813
  # @example
595
- # set_logger { :out => STDERR, :level => Occi::Log::WARN, :logger => nil }
814
+ # get_logger { :out => STDERR, :level => Occi::Log::WARN, :logger => nil }
596
815
  #
597
816
  # @param [Hash] logger options
598
- def set_logger(log_options)
817
+ # @return [Occi::Log] instance of the logger
818
+ def get_logger(log_options)
599
819
  unless log_options[:logger] && log_options[:logger].kind_of?(Occi::Log)
600
- @logger = Occi::Log.new(log_options[:out])
601
- @logger.level = log_options[:level]
820
+ logger = Occi::Log.new(log_options[:out])
821
+ logger.level = log_options[:level]
822
+ else
823
+ logger = log_options[:logger]
602
824
  end
825
+
826
+ logger
603
827
  end
604
828
 
605
- # Checks whether the given endpoint URI is valid and adds a trailing
606
- # slash if necessary.
829
+ # Checks whether the given endpoint URI is valid and converts it
830
+ # to a URI instance.
607
831
  #
608
832
  # @example
609
- # set_endpoint "http://localhost:3300" # => "http://localhost:3300/"
833
+ # get_endpoint_uri "http://localhost:3300" # => #<URI::*>
610
834
  #
611
835
  # @param [String] endpoint URI in a non-canonical string
612
- # @return [String] canonical endpoint URI in a string, with a trailing slash
613
- def set_endpoint(endpoint)
614
- raise 'Endpoint not a valid URI' unless (endpoint =~ URI::ABS_URI)
615
- @endpoint = endpoint.chomp('/') + '/'
836
+ # @return [URI] canonical endpoint URI
837
+ def get_endpoint_uri(endpoint)
838
+ unless endpoint =~ URI::ABS_URI
839
+ raise "Endpoint not a valid absolute URI! #{endpoint.inspect}"
840
+ end
841
+
842
+ # normalize URIs, remove trailing slashes
843
+ endpoint = URI(endpoint)
844
+ endpoint.path = endpoint.path.gsub(/\/+/, '/').chomp('/')
845
+
846
+ endpoint
616
847
  end
617
848
 
618
849
  # Creates an Occi::Model from data retrieved from the server.
619
850
  #
620
851
  # @example
621
- # model = get('/-/')
622
- # set_model model # => #<Occi::Model>
852
+ # model_collection = get('/-/')
853
+ # get_model model_collection # => #<Occi::Model>
623
854
  #
624
855
  # @param [Occi::Collection] parsed representation of server's model
625
856
  # @return [Occi::Model] Model instance
626
- def set_model(model)
857
+ def get_model(model_collection)
627
858
  # build model
628
- @model = Occi::Model.new(model)
859
+ Occi::Model.new(model_collection)
629
860
  end
630
861
 
631
862
  # Returns mixin type identifiers for os_tpl mixins
@@ -88,8 +88,8 @@ module Occi
88
88
 
89
89
  # get model information from the endpoint
90
90
  # and create Occi::Model instance
91
- model = get('/-/')
92
- set_model model
91
+ model_collection = get('/-/')
92
+ @model = get_model(model_collection)
93
93
 
94
94
  # auto-connect?
95
95
  @connected = @options[:auto_connect]
@@ -98,33 +98,18 @@ module Occi
98
98
  # @see Occi::Api::Client::ClientBase
99
99
  def list(resource_type_identifier=nil)
100
100
  if resource_type_identifier
101
- # convert type to type identifier
102
- kinds = @model.kinds.select {
103
- |kind| kind.term == resource_type_identifier
104
- }
105
- if kinds.any?
106
- resource_type_identifier = kinds.first.type_identifier
107
- end
108
-
109
- raise 'Unkown resource type identifier!' unless resource_type_identifier
110
- unless @model.get_by_id resource_type_identifier
111
- raise "Resource type identifier not allowed with this model! [#{resource_type_identifier}]"
112
- end
113
-
114
- # split the type identifier and get the most important part
115
- uri_part = resource_type_identifier.split('#').last
116
-
117
- # request uri-list from the server
118
- path = uri_part + '/'
101
+ resource_type_identifier = get_resource_type_identifier(resource_type_identifier)
102
+ path = path_for_kind_type_identifier(resource_type_identifier)
119
103
  end
120
104
 
121
105
  path = '/' unless path
106
+ path = "#{@endpoint.to_s}#{path}"
122
107
 
123
108
  headers = self.class.headers.clone
124
109
  headers['Accept'] = 'text/uri-list'
125
110
 
126
111
  response = self.class.get(
127
- @endpoint + path,
112
+ path,
128
113
  :headers => headers
129
114
  )
130
115
 
@@ -134,20 +119,13 @@ module Occi
134
119
 
135
120
  # @see Occi::Api::Client::ClientBase
136
121
  def describe(resource_type_identifier=nil)
137
-
138
- # convert type to type identifier whenever possible
139
122
  if resource_type_identifier
140
- kinds = @model.kinds.select {
141
- |kind| kind.term == resource_type_identifier
142
- }
143
- if kinds.any?
144
- resource_type_identifier = kinds.first.type_identifier
145
- end
123
+ resource_type_identifier = get_resource_type_identifier(resource_type_identifier)
146
124
  end
147
125
 
148
126
  descriptions = Occi::Collection.new
149
127
 
150
- if resource_type_identifier.nil?
128
+ if resource_type_identifier.blank?
151
129
  # no filters, describe all available resources
152
130
  descriptions.merge! get('/')
153
131
  elsif @model.get_by_id(resource_type_identifier)
@@ -157,13 +135,13 @@ module Occi
157
135
 
158
136
  # make the requests
159
137
  locations.each do |location|
160
- descriptions.merge! get(sanitize_resource_link(location))
138
+ path = sanitize_instance_link(location)
139
+ descriptions.merge! get(path)
161
140
  end
162
- elsif resource_type_identifier.start_with?(@endpoint) || resource_type_identifier.start_with?('/')
163
- # this is a link of a specific resource (obsolute or relative)
164
- descriptions.merge! get(sanitize_resource_link(resource_type_identifier))
165
141
  else
166
- raise "Unkown resource type identifier! [#{resource_type_identifier}]"
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)
167
145
  end
168
146
 
169
147
  descriptions.resources
@@ -171,30 +149,27 @@ module Occi
171
149
 
172
150
  # @see Occi::Api::Client::ClientBase
173
151
  def create(entity)
152
+ raise "#{entity.class.name.inspect} not an entity!" unless entity.kind_of? Occi::Core::Entity
174
153
 
175
- raise "#{entity} not an entity!" unless entity.kind_of? Occi::Core::Entity
176
-
177
- Occi::Log.debug "Entity kind: #{entity.kind}"
178
- kind = entity.kind
179
- raise "No kind found for #{entity}" unless kind
154
+ Occi::Log.debug "Entity kind: #{entity.kind.type_identifier.inspect}"
155
+ raise "No kind found for #{entity.inspect}" unless entity.kind
180
156
 
181
157
  # get location for this kind of entity
182
- Occi::Log.debug "Kind location: #{entity.kind.location}"
183
- location = kind.location
158
+ path = path_for_kind_type_identifier(entity.kind.type_identifier)
184
159
  collection = Occi::Collection.new
185
160
 
186
161
  # is this entity a Resource or a Link?
187
- Occi::Log.debug "Entity class: #{entity.class.name}"
162
+ Occi::Log.debug "Entity class: #{entity.class.name.inspect}"
188
163
  collection.resources << entity if entity.kind_of? Occi::Core::Resource
189
164
  collection.links << entity if entity.kind_of? Occi::Core::Link
190
165
 
191
166
  # make the request
192
- post location, collection
167
+ post path, collection
193
168
  end
194
169
 
195
170
  # @see Occi::Api::Client::ClientBase
196
171
  def deploy(location)
197
- raise "File #{location} does not exist!" unless File.exist? location
172
+ raise "File #{location.inspect} does not exist!" unless File.exist? location
198
173
 
199
174
  file = File.read(location)
200
175
 
@@ -209,12 +184,14 @@ module Occi
209
184
 
210
185
  # @see Occi::Api::Client::ClientBase
211
186
  def deploy_ovf(descriptor)
212
- media_types = self.class.head(@endpoint).headers['accept'].to_s
187
+ media_types = self.class.head(@endpoint.to_s).headers['accept'].to_s
213
188
 
189
+ path = path_for_kind_type_identifier(Occi::Infrastructure::Compute.type_identifier)
190
+ path = "#{@endpoint.to_s}#{path}"
214
191
  if media_types.include? 'application/ovf'
215
192
  headers = self.class.headers.clone
216
193
  headers['Content-Type'] = 'application/ovf'
217
- self.class.post(@endpoint + '/compute/',
194
+ self.class.post(path,
218
195
  :body => descriptor,
219
196
  :headers => headers)
220
197
  else
@@ -224,12 +201,14 @@ module Occi
224
201
 
225
202
  # @see Occi::Api::Client::ClientBase
226
203
  def deploy_ova(descriptor)
227
- media_types = self.class.head(@endpoint).headers['accept'].to_s
204
+ media_types = self.class.head(@endpoint.to_s).headers['accept'].to_s
228
205
 
206
+ path = path_for_kind_type_identifier(Occi::Infrastructure::Compute.type_identifier)
207
+ path = "#{@endpoint.to_s}#{path}"
229
208
  if media_types.include? ' application/ova '
230
209
  headers = self.class.headers.clone
231
210
  headers['Content-Type'] = 'application/ova'
232
- self.class.post(@endpoint + '/compute/',
211
+ self.class.post(path,
233
212
  :body => descriptor,
234
213
  :headers => headers)
235
214
  else
@@ -239,47 +218,31 @@ module Occi
239
218
 
240
219
  # @see Occi::Api::Client::ClientBase
241
220
  def delete(resource_type_identifier)
242
- raise 'Resource not provided!' unless resource_type_identifier
243
- path = path_for_resource_type(resource_type_identifier)
221
+ raise 'Resource not provided!' if resource_type_identifier.blank?
222
+ path = path_for_kind_type_identifier(resource_type_identifier)
244
223
 
245
- Occi::Log.debug("Deleting #{path} ...")
224
+ Occi::Log.debug("Deleting #{path.inspect} for #{resource_type_identifier.inspect}")
246
225
  del path
247
226
  end
248
227
 
249
228
  # @see Occi::Api::Client::ClientBase
250
- def trigger(resource_type_identifier, action)
229
+ def trigger(resource_type_identifier, action_instance)
251
230
  # TODO: not tested
252
- raise 'Resource not provided!' unless resource_type_identifier
253
- type_identifiers = @model.kinds.select {
254
- |kind| kind.term == resource_type_identifier
255
- }
256
-
257
- if type_identifiers.any?
258
- type_identifier = @model.kinds.select {
259
- |kind| kind.term == resource_type_identifier
260
- }.first.type_identifier
261
-
262
- location = @model.get_by_id(type_identifier).location
263
- resource_type_identifier = @endpoint + location
264
- end
265
-
266
- raise "Unknown resource identifier! #{resource_type_identifier}" unless resource_type_identifier.start_with? @endpoint
231
+ raise 'Resource not provided!' if resource_type_identifier.blank?
267
232
 
268
- # encapsulate the acion in a collection
269
- collection = Occi::Collection.new
270
- scheme, term = action.split('#')
271
- collection.actions << Occi::Core::Action.new(scheme + '#', term)
233
+ #
234
+ resource_type_identifier = get_resource_type_identifier(resource_type_identifier)
235
+ path = path_for_kind_type_identifier(resource_type_identifier)
272
236
 
273
237
  # make the request
274
- path = sanitize_resource_link(resource_type_identifier) + '?action=' + term
275
- post path, collection
238
+ post path, action_instance
276
239
  end
277
240
 
278
241
  # @see Occi::Api::Client::ClientBase
279
242
  def refresh
280
243
  # re-download the model from the server
281
- model = get('/-/')
282
- set_model model
244
+ model_collection = get('/-/')
245
+ @model = get_model(model_collection)
283
246
  end
284
247
 
285
248
  private
@@ -294,10 +257,10 @@ module Occi
294
257
  # @param [String] path for the GET request
295
258
  # @param [Occi::Collection] collection of filters
296
259
  # @return [Occi::Collection] parsed result of the request
297
- def get(path='', filter=nil)
298
- # remove the leading slash
299
- path = path.gsub(/\A\//, '')
300
-
260
+ def get(path='/', filter=nil)
261
+ relative_path = path
262
+ path = "#{@endpoint.to_s}#{path}"
263
+ # apply filters if present
301
264
  response = if filter
302
265
  categories = filter.categories.collect { |category| category.to_text }.join(',')
303
266
  attributes = filter.entities.collect { |entity| entity.attributes.combine.collect { |k, v| k + '=' + v } }.join(',')
@@ -307,28 +270,28 @@ module Occi
307
270
  headers['Category'] = categories unless categories.empty?
308
271
  headers['X-OCCI-Attributes'] = attributes unless attributes.empty?
309
272
 
310
- self.class.get(@endpoint + path, :headers => headers)
273
+ self.class.get(path, :headers => headers)
311
274
  else
312
- self.class.get(@endpoint + path)
275
+ self.class.get(path)
313
276
  end
314
277
 
315
278
  response_msg = response_message response
316
279
  raise "HTTP GET failed! #{response_msg}" unless response.code.between? 200, 300
317
280
 
318
- Occi::Log.debug "Response location: #{('/' + path).match(/\/.*\//).to_s}"
319
- kind = @model.get_by_location(('/' + path).match(/\/.*\//).to_s) if @model
281
+ Occi::Log.debug "Response location: #{relative_path.inspect}"
282
+ kind = @model.get_by_location(relative_path) if @model
320
283
 
321
- Occi::Log.debug "Response kind: #{kind}"
284
+ Occi::Log.debug "Response kind: #{kind.inspect}"
322
285
 
323
- if kind
324
- kind.related_to? Occi::Core::Resource ? entity_type = Occi::Core::Resource : entity_type = nil
325
- entity_type = Occi::Core::Link if kind.related_to? Occi::Core::Link
286
+ entity_type = nil
287
+ if kind && kind.related_to?(Occi::Core::Link)
288
+ entity_type = Occi::Core::Link
326
289
  end
327
290
 
328
291
  entity_type = Occi::Core::Resource unless entity_type
329
292
 
330
- Occi::Log.debug "Parser call: #{response.content_type} #{path.include?('-/')} #{entity_type} #{response.headers.inspect}"
331
- collection = Occi::Parser.parse(response.content_type, response.body, path.include?('-/'), entity_type, response.headers)
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)
332
295
 
333
296
  Occi::Log.debug "Parsed collection: empty? #{collection.empty?}"
334
297
  collection
@@ -350,27 +313,28 @@ module Occi
350
313
  # @param [Occi::Collection] resource data to be POSTed
351
314
  # @return [String] URI location
352
315
  def post(path, collection)
353
- # remove the leading slash
354
- path = path.gsub(/\A\//, '')
316
+ raise ArgumentError, "Path is a required argument!" if path.blank?
355
317
 
356
318
  headers = self.class.headers.clone
357
319
  headers['Content-Type'] = @media_type
358
320
 
321
+ path = "#{@endpoint.to_s}#{path}"
322
+
359
323
  response = case @media_type
360
324
  when 'application/occi+json'
361
- self.class.post(@endpoint + path,
325
+ self.class.post(path,
362
326
  :body => collection.to_json,
363
327
  :headers => headers)
364
328
  when 'text/occi'
365
- self.class.post(@endpoint + path,
329
+ self.class.post(path,
366
330
  :headers => collection.to_header.merge(headers))
367
331
  else
368
- self.class.post(@endpoint + path,
332
+ self.class.post(path,
369
333
  :body => collection.to_text,
370
334
  :headers => headers)
371
335
  end
372
336
 
373
- response_msg = response_message response
337
+ response_msg = response_message(response)
374
338
 
375
339
  case response.code
376
340
  when 200
@@ -403,27 +367,28 @@ module Occi
403
367
  # @param [Occi::Collection] resource data to send
404
368
  # @return [Occi::Collection] parsed result of the request
405
369
  def put(path, collection)
406
- # remove the leading slash
407
- path = path.gsub(/\A\//, '')
370
+ raise ArgumentError, "Path is a required argument!" if path.blank?
408
371
 
409
372
  headers = self.class.headers.clone
410
373
  headers['Content-Type'] = @media_type
411
374
 
375
+ path = "#{@endpoint.to_s}#{path}"
376
+
412
377
  response = case @media_type
413
378
  when 'application/occi+json'
414
- self.class.post(@endpoint + path,
379
+ self.class.post(path,
415
380
  :body => collection.to_json,
416
381
  :headers => headers)
417
382
  when 'text/occi'
418
- self.class.post(@endpoint + path,
383
+ self.class.post(path,
419
384
  :headers => collection.to_header.merge(headers))
420
385
  else
421
- self.class.post(@endpoint + path,
386
+ self.class.post(path,
422
387
  :body => collection.to_text,
423
388
  :headers => headers)
424
389
  end
425
390
 
426
- response_msg = response_message response
391
+ response_msg = response_message(response)
427
392
 
428
393
  case response.code
429
394
  when 200, 201
@@ -442,38 +407,37 @@ module Occi
442
407
  # @param [Occi::Collection] collection of filters (currently NOT used)
443
408
  # @return [Boolean] status
444
409
  def del(path, filter=nil)
445
- # remove the leading slash
446
- path = path.gsub(/\A\//, '')
410
+ raise ArgumentError, "Path is a required argument!" if path.blank?
447
411
 
448
- response = self.class.delete(@endpoint + path)
412
+ response = self.class.delete("#{@endpoint.to_s}#{path}")
449
413
 
450
- response_msg = response_message response
414
+ response_msg = response_message(response)
451
415
  raise "HTTP DELETE failed! #{response_msg}" unless response.code.between? 200, 300
452
416
 
453
417
  true
454
418
  end
455
419
 
456
420
  # @see Occi::Api::Client::ClientBase
457
- def set_logger(log_options)
458
- super log_options
421
+ def get_logger(log_options)
422
+ logger = super(log_options)
423
+ self.class.debug_output $stderr if logger.level == Occi::Log::DEBUG
459
424
 
460
- self.class.debug_output $stderr if log_options[:level] == Occi::Log::DEBUG
425
+ logger
461
426
  end
462
427
 
463
428
  # @see Occi::Api::Client::ClientBase
464
- def set_auth(auth_options, fallback = false)
465
- @auth_options = auth_options
466
-
467
- case @auth_options[:type]
429
+ def get_auth(auth_options, fallback = false)
430
+ # select appropriate authN type
431
+ case auth_options[:type]
468
432
  when "basic"
469
- @authn_plugin = Http::AuthnPlugins::Basic.new self, @auth_options
433
+ @authn_plugin = Http::AuthnPlugins::Basic.new self, auth_options
470
434
  when "digest"
471
- @authn_plugin = Http::AuthnPlugins::Digest.new self, @auth_options
435
+ @authn_plugin = Http::AuthnPlugins::Digest.new self, auth_options
472
436
  when "x509"
473
- @authn_plugin = Http::AuthnPlugins::X509.new self, @auth_options
437
+ @authn_plugin = Http::AuthnPlugins::X509.new self, auth_options
474
438
  when "keystone"
475
439
  raise ::Occi::Api::Client::Errors::AuthnError, "This authN method is for fallback only!" unless fallback
476
- @authn_plugin = Http::AuthnPlugins::Keystone.new self, @auth_options
440
+ @authn_plugin = Http::AuthnPlugins::Keystone.new self, auth_options
477
441
  when "none", nil
478
442
  @authn_plugin = Http::AuthnPlugins::Dummy.new self
479
443
  else
@@ -481,6 +445,8 @@ module Occi
481
445
  end
482
446
 
483
447
  @authn_plugin.setup
448
+
449
+ auth_options
484
450
  end
485
451
 
486
452
  # @see Occi::Api::Client::ClientBase
@@ -495,7 +461,7 @@ module Occi
495
461
  @auth_options[:original_type] = @auth_options[:type]
496
462
  @auth_options[:type] = @authn_plugin.fallbacks.first
497
463
 
498
- set_auth @auth_options, true
464
+ @auth_options = get_auth(@auth_options, true)
499
465
  @authn_plugin.authenticate
500
466
  else
501
467
  raise e
@@ -504,34 +470,41 @@ module Occi
504
470
  end
505
471
 
506
472
  # @see Occi::Api::Client::ClientBase
507
- def set_media_type(force_type = nil)
473
+ def get_media_type(force_type = nil)
508
474
  # force media_type if provided
509
- if force_type
475
+ unless force_type.blank?
510
476
  self.class.headers 'Accept' => force_type
511
- @media_type = force_type
477
+ media_type = force_type
512
478
  else
513
- media_types = self.class.head(@endpoint).headers['accept']
514
- Occi::Log.debug("Available media types: #{media_types}")
515
- @media_type = case media_types
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
516
483
  when /application\/occi\+json/
517
484
  'application/occi+json'
485
+ when /application\/occi\+xml/
486
+ 'application/occi+xml'
487
+ when /text\/occi/
488
+ 'text/occi'
518
489
  else
519
490
  'text/plain'
520
491
  end
521
492
  end
493
+
494
+ media_type
522
495
  end
523
496
 
524
497
  # Generates a human-readable response message based on the HTTP response code.
525
498
  #
526
499
  # @example
527
- # response_message self.class.delete(@endpoint + path)
500
+ # response_message self.class.delete(@endpoint.to_s + path)
528
501
  # # => 'HTTP Response status: [200] OK'
529
502
  #
530
503
  # @param [HTTParty::Response] HTTParty response object
531
504
  # @return [String] message
532
505
  def response_message(response)
533
506
  @last_response = response
534
- 'HTTP Response status: [' + response.code.to_s + '] ' + reason_phrase(response.code)
507
+ "HTTP Response status: [#{response.code.to_s}] #{reason_phrase(response.code)}"
535
508
  end
536
509
 
537
510
  # Converts HTTP response codes to human-readable phrases.
@@ -1 +1,4 @@
1
- require 'occi/api/client/errors/authn_error'
1
+ module Occi::Api::Client::Errors; end
2
+
3
+ # load all
4
+ Dir[File.join(File.dirname(__FILE__), 'errors', '*.rb')].each { |file| require file.gsub('.rb', '') }
@@ -0,0 +1,5 @@
1
+ module Occi::Api::Client::Errors
2
+
3
+ class AmbiguousNameError < RuntimeError; end
4
+
5
+ end
@@ -1,7 +1,5 @@
1
- module Occi::Api::Client
2
- module Errors
1
+ module Occi::Api::Client::Errors
3
2
 
4
- class AuthnError < RuntimeError; end
3
+ class AuthnError < RuntimeError; end
5
4
 
6
- end
7
5
  end
@@ -0,0 +1,5 @@
1
+ module Occi::Api::Client::Errors
2
+
3
+ class LocationError < RuntimeError; end
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ module Occi::Api::Client::Errors
2
+
3
+ class NotImplementedError < NotImplementedError; end
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ module Occi::Api::Client::Errors
2
+
3
+ class TypeMismatchError < ArgumentError; end
4
+
5
+ end
@@ -16,7 +16,7 @@ module Occi::Api::Client
16
16
  def setup(options = {}); end
17
17
 
18
18
  def authenticate(options = {})
19
- response = @env_ref.class.head "#{@env_ref.endpoint}-/"
19
+ response = @env_ref.class.head("#{@env_ref.endpoint.to_s}/-/")
20
20
  raise ::Occi::Api::Client::Errors::AuthnError, "Authentication failed with code #{response.code.to_s}!" unless response.success?
21
21
  end
22
22
 
@@ -18,7 +18,7 @@ module Occi::Api::Client
18
18
 
19
19
  def authenticate(options = {})
20
20
  # OCCI-OS doesn't support HEAD method!
21
- response = @env_ref.class.get "#{@env_ref.endpoint}-/"
21
+ response = @env_ref.class.get "#{@env_ref.endpoint.to_s}/-/"
22
22
  raise ::Occi::Api::Client::Errors::AuthnError,
23
23
  "Authentication failed with code #{response.code.to_s}!" unless response.success?
24
24
  end
@@ -26,7 +26,7 @@ module Occi::Api::Client
26
26
  private
27
27
 
28
28
  def set_keystone_base_url
29
- response = @env_ref.class.head "#{@env_ref.endpoint}-/"
29
+ response = @env_ref.class.head "#{@env_ref.endpoint.to_s}/-/"
30
30
  Occi::Log.debug response.inspect
31
31
 
32
32
  return if response.success?
@@ -1,5 +1,5 @@
1
1
  module Occi
2
2
  module Api
3
- VERSION = "4.2.0.beta.2" unless defined?(::Occi::Api::VERSION)
3
+ VERSION = "4.2.0.beta.3" unless defined?(::Occi::Api::VERSION)
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: occi-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.2.0.beta.2
4
+ version: 4.2.0.beta.3
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2013-12-04 00:00:00.000000000 Z
14
+ date: 2013-12-06 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: occi-core
@@ -87,7 +87,11 @@ files:
87
87
  - lib/occi/api/client/client_base.rb
88
88
  - lib/occi/api/client/client_http.rb
89
89
  - lib/occi/api/client/errors.rb
90
+ - lib/occi/api/client/errors/ambiguous_name_error.rb
90
91
  - lib/occi/api/client/errors/authn_error.rb
92
+ - lib/occi/api/client/errors/location_error.rb
93
+ - lib/occi/api/client/errors/not_implemented_error.rb
94
+ - lib/occi/api/client/errors/type_mismatch_error.rb
91
95
  - lib/occi/api/client/http/authn_plugins.rb
92
96
  - lib/occi/api/client/http/authn_plugins/base.rb
93
97
  - lib/occi/api/client/http/authn_plugins/basic.rb