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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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