occi 2.2.2 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,10 @@
1
+ require 'rubygems'
1
2
  require 'json'
2
3
  require 'nokogiri'
3
4
  require 'hashie/mash'
5
+ require 'rubygems/package'
6
+ require 'zlib'
7
+ require 'tempfile'
4
8
  require 'occi/collection'
5
9
  require 'occi/log'
6
10
  require 'occiantlr/OCCIANTLRParser'
@@ -8,58 +12,41 @@ require 'occiantlr/OCCIANTLRParser'
8
12
  module OCCI
9
13
  class Parser
10
14
 
11
- =begin
12
- if content_type.includes?('multipart')
13
- # TODO: implement multipart handling
14
- # handle file upload
15
- if params['file'] != nil
16
- OCCI::Log.debug("Location of Image #{params['file'][:tempfile].path}")
17
- $image_path = OCCI::Server.config[:one_image_tmp_dir] + '/' + params['file'][:filename]
18
- FileUtils.cp(params['file'][:tempfile].path, $image_path)
19
- end
20
-
21
- # handle file upload in multipart requests
22
- request.POST.values.each do |body|
23
- if body.kind_of?(String)
24
- parse_text(body)
25
- elsif body.kind_of?(Hash)
26
- if body['type'].include?('application/json')
27
- # try to parse body as JSON object
28
- parse_json(body.read)
29
- elsif body['type'].include?('text/plain') # text/plain
30
- parse_text(body.read)
31
- end unless body['type'].nil?
32
- end
33
- end
34
- end
35
- =end
15
+ # Declaring Class constants for OVF XML namespaces (defined in OVF specification ver.1.1)
16
+ OVF ="http://schemas.dmtf.org/ovf/envelope/1"
17
+ RASD ="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData"
18
+ VSSD ="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData"
19
+ OVFENV="http://schemas.dmtf.org/ovf/environment/1"
20
+ CIM ="http://schemas.dmtf.org/wbem/wscim/1/common"
36
21
 
37
22
  # Parses an OCCI message and extracts OCCI relevant information
38
23
  # @param [String] media_type the media type of the OCCI message
39
24
  # @param [String] body the body of the OCCI message
40
25
  # @param [true, false] category for text/plain and text/occi media types information e.g. from the HTTP request location is needed to determine if the OCCI message includes a category or an entity
26
+ # @param [OCCI::Core::Resource,OCCI::Core::Link] entity_type entity type to use for parsing of text plain entities
41
27
  # @param [Hash] header optional header of the OCCI message
42
28
  # @return [Array<Array, OCCI::Collection>] list consisting of an array of locations and the OCCI object collection
43
- def self.parse(media_type, body, category=false, header={ })
44
- OCCI::Log.debug('### Parsing request data to OCCI data structure ###')
29
+ def self.parse(media_type, body, category=false, entity_type=OCCI::Core::Resource, header={ })
30
+ OCCI::Log.debug '### Parsing request data to OCCI data structure ###'
45
31
  collection = OCCI::Collection.new
46
32
 
47
33
  locations = self.header_locations(header)
48
- category ? collection = self.header_categories(header) : collection = self.header_entity(header) if locations.empty?
34
+ category ? collection = self.header_categories(header) : collection = self.header_entity(header, entity_type) if locations.empty?
49
35
 
50
36
  case media_type
51
- when 'text/occi'
52
37
  when 'text/uri-list'
53
38
  body.each_line { |line| locations << URI.parse(line) }
54
39
  when 'text/plain', nil
55
40
  locations.concat self.text_locations(body)
56
- category ? collection = self.text_categories(body) : collection = self.text_entity(body) if locations.empty? && collection.empty?
41
+ category ? collection = self.text_categories(body) : collection = self.text_entity(body, entity_type) if locations.empty? && collection.empty?
57
42
  when 'application/occi+json', 'application/json'
58
43
  collection = self.json(body)
59
44
  when 'application/occi+xml', 'application/xml'
60
45
  collection = self.xml(body)
61
- #when 'application/ovf+xml'
62
- # collection = self.ovf(body)
46
+ when 'application/ovf', 'application/ovf+xml'
47
+ collection = self.ovf(body)
48
+ when 'application/ova'
49
+ collection = self.ova(body)
63
50
  else
64
51
  raise "Content Type not supported"
65
52
  end
@@ -78,14 +65,14 @@ module OCCI
78
65
  category_strings = header['HTTP_CATEGORY'].to_s.split(',')
79
66
  category_strings.each do |cat|
80
67
  category = OCCIANTLR::Parser.new('Category: ' + cat).category
81
- collection.kinds.concat category.kinds.collect { |kind| OCCI::Core::Kind.new(kind) }
82
- collection.mixins.concat category.mixins.collect { |mixin| OCCI::Core::Mixin.new(mixin) }
83
- collection.actions.concat category.actions.collect { |action| OCCI::Core::Action.new(action) }
68
+ collection.kinds.concat category.kinds.collect { |kind| OCCI::Core::Kind.new(kind.scheme, kind.term, kind.title, kind.attributes, kind.related, kind.actions) }
69
+ collection.mixins.concat category.mixins.collect { |mixin| OCCI::Core::Mixin.new(mixin.scheme, mixin.term, mixin.title, mixin.attributes, mixin.related, mixin.actions) }
70
+ collection.actions.concat category.actions.collect { |action| OCCI::Core::Action.new(action.scheme, action.term, action.title, action.attributes) }
84
71
  end
85
72
  collection
86
73
  end
87
74
 
88
- def self.header_entity(header)
75
+ def self.header_entity(header, entity_type)
89
76
  collection = OCCI::Collection.new
90
77
  entity = Hashie::Mash.new
91
78
  category_strings = header['HTTP_CATEGORY'].to_s.split(',')
@@ -97,14 +84,11 @@ module OCCI
97
84
  entity.kind = categories.kinds.first.scheme + categories.kinds.first.term
98
85
  entity.mixins = categories.mixins.collect { |mixin| mixin.scheme + mixin.term } if categories.mixins.any?
99
86
  attribute_strings.each { |attr| entity.attributes!.merge!(OCCIANTLR::Parser.new('X-OCCI-Attribute: ' + attr).x_occi_attribute) }
100
- kind = OCCI::Model.get_by_id(entity.kind)
101
- # TODO: error handling
102
- return collection if kind.nil?
103
- if kind.entity_type == OCCI::Core::Link.name
104
- entity.target = link.attributes.occi!.core!.target
105
- entity.source = link.attributes.occi!.core!.source
87
+ if entity_type == OCCI::Core::Link
88
+ entity.target = link.attributes!.occi!.core!.target
89
+ entity.source = link.attributes!.occi!.core!.source
106
90
  collection.links << OCCI::Core::Link.new(entity)
107
- elsif kind.entity_type == OCCI::Core::Resource.name
91
+ elsif entity_type == OCCI::Core::Resource
108
92
  link_strings = header['HTTP_LINK'].to_s.split(',')
109
93
  link_strings.each { |link| entity.links << OCCIANTLR::Parser.new('Link: ' + link).link }
110
94
  collection.resources << OCCI::Core::Resource.new(entity)
@@ -121,14 +105,14 @@ module OCCI
121
105
  text.each_line do |line|
122
106
  category = OCCIANTLR::Parser.new(line).category
123
107
  next if category.nil?
124
- collection.kinds.concat category.kinds.collect { |kind| OCCI::Core::Kind.new(kind) }
125
- collection.mixins.concat category.mixins.collect { |mixin| OCCI::Core::Mixin.new(mixin) }
126
- collection.actions.concat category.actions.collect { |action| OCCI::Core::Action.new(action) }
108
+ collection.kinds.concat category.kinds.collect { |kind| OCCI::Core::Kind.new(kind.scheme, kind.term, kind.title, kind.attributes, kind.related, kind.actions) }
109
+ collection.mixins.concat category.mixins.collect { |mixin| OCCI::Core::Mixin.new(mixin.scheme, mixin.term, mixin.title, mixin.attributes, mixin.related, mixin.actions) }
110
+ collection.actions.concat category.actions.collect { |action| OCCI::Core::Action.new(action.scheme, action.term, action.title, action.attributes) }
127
111
  end
128
112
  collection
129
113
  end
130
114
 
131
- def self.text_entity(text)
115
+ def self.text_entity(text, entity_type)
132
116
  collection = OCCI::Collection.new
133
117
  entity = Hashie::Mash.new
134
118
  links = []
@@ -140,14 +124,11 @@ module OCCI
140
124
  end
141
125
  entity.kind = categories.kinds.first.scheme + categories.kinds.first.term if categories.kinds.first
142
126
  entity.mixins = categories.mixins.collect { |mixin| mixin.scheme + mixin.term } if entity.mixins
143
- kind = OCCI::Model.get_by_id(entity.kind)
144
- # TODO: error handling
145
- return collection if kind.nil?
146
- if OCCI::Model.get_by_id(entity.kind).entity_type == OCCI::Core::Link.name
147
- entity.target = links.first.attributes.occi!.core!.target
148
- entity.source = links.first.attributes.occi!.core!.source
127
+ if entity_type == OCCI::Core::Link
128
+ entity.target = links.first.attributes!.occi!.core!.target
129
+ entity.source = links.first.attributes!.occi!.core!.source
149
130
  collection.links << OCCI::Core::Link.new(entity)
150
- elsif OCCI::Model.get_by_id(entity.kind).entity_type == OCCI::Core::Resource.name
131
+ elsif entity_type == OCCI::Core::Resource
151
132
  entity.links = links
152
133
  collection.resources << OCCI::Core::Resource.new(entity)
153
134
  end unless entity.kind.nil?
@@ -157,27 +138,173 @@ module OCCI
157
138
  def self.json(json)
158
139
  collection = OCCI::Collection.new
159
140
  hash = Hashie::Mash.new(JSON.parse(json))
160
- collection.kinds.concat hash.kinds.collect { |kind| OCCI::Core::Kind.new(kind) } if hash.kinds
161
- collection.mixins.concat hash.mixins.collect { |mixin| OCCI::Core::Mixin.new(mixin) } if hash.mixins
162
- collection.resources.concat hash.resources.collect { |resource| OCCI::Core::Resource.new(resource) } if hash.resources
163
- collection.links.concat hash.links.collect { |link| OCCI::Core::Link.new(link) } if hash.links
141
+ collection.kinds.concat hash.kinds.collect { |kind| OCCI::Core::Kind.new(kind.scheme, kind.term, kind.title, kind.attributes, kind.related, kind.actions) } if hash.kinds
142
+ collection.mixins.concat hash.mixins.collect { |mixin| OCCI::Core::Mixin.new(mixin.scheme, mixin.term, mixin.title, mixin.attributes, mixin.related, mixin.actions) } if hash.mixins
143
+ collection.resources.concat hash.resources.collect { |resource| OCCI::Core::Resource.new(resource.kind, resource.mixins, resource.attributes, resource.links) } if hash.resources
144
+ collection.links.concat hash.links.collect { |link| OCCI::Core::Link.new(link.kind, link.mixins, link.attributes) } if hash.links
164
145
  collection
165
146
  end
166
147
 
167
148
  def self.xml(xml)
168
149
  collection = OCCI::Collection.new
169
150
  hash = Hashie::Mash.new(Hash.from_xml(Nokogiri::XML(xml)))
170
- collection.kinds.concat hash.kinds.collect { |kind| OCCI::Core::Kind.new(kind) } if hash.kinds
171
- collection.mixins.concat hash.mixins.collect { |mixin| OCCI::Core::Mixin.new(mixin) } if hash.mixins
172
- collection.resources.concat hash.resources.collect { |resource| OCCI::Core::Resource.new(resource) } if hash.resources
173
- collection.links.concat hash.links.collect { |link| OCCI::Core::Link.new(link) } if hash.links
151
+ collection.kinds.concat hash.kinds.collect { |kind| OCCI::Core::Kind.new(kind.scheme, kind.term, kind.title, kind.attributes, kind.related, kind.actions) } if hash.kinds
152
+ collection.mixins.concat hash.mixins.collect { |mixin| OCCI::Core::Mixin.new(mixin.scheme, mixin.term, mixin.title, mixin.attributes, mixin.related, mixin.actions) } if hash.mixins
153
+ collection.resources.concat hash.resources.collect { |resource| OCCI::Core::Resource.new(resource.kind, resource.mixins, resource.attributes, resource.links) } if hash.resources
154
+ collection.links.concat hash.links.collect { |link| OCCI::Core::Link.new(link.kind, link.mixins, link.attributes) } if hash.links
174
155
  collection
175
156
  end
176
157
 
177
- #def self.ovf(ovf)
178
- # TODO: implement ovf / ova messages
179
- #end
180
158
 
159
+ ####################Helper method for calculation of storage size based on allocation units configured###########
160
+ def self.calculate_capacity_bytes(capacity, alloc_units_bytes)
161
+ total_capacity_bytes = alloc_units_bytes * capacity.to_i
162
+ total_capacity_bytes
163
+ end
164
+
165
+
166
+ def self.calculate_capacity_gb(capacity)
167
+ capacity_gb = capacity/(2**30)
168
+ capacity_gb
169
+ end
170
+
171
+
172
+ def self.alloc_units_bytes(alloc_units)
173
+ units = alloc_units.split('*')
174
+ #check units[1] is nil??
175
+ units[1].strip!
176
+ alloc_vars = units[1].split('^')
177
+ alloc_units_bytes = (alloc_vars[0].to_i**alloc_vars[1].to_i)
178
+ alloc_units_bytes
179
+ end
180
+
181
+ ###############End of Helper methods for OVF Parsing ##################################################################
182
+
183
+ def self.ova(ova)
184
+ tar = Gem::Package::TarReader.new(StringIO.new(ova))
185
+ ovf = mf = cert = nil
186
+ files = { }
187
+ tar.each do |entry|
188
+ tempfile = Tempfile.new(entry.full_name)
189
+ tempfile.write(entry.read)
190
+ tempfile.close
191
+ files[entry.full_name] = tempfile.path
192
+ ovf = tempfile.path if entry.full_name.end_with? '.ovf'
193
+ mf = tempfile.path if entry.full_name.end_with? '.mf'
194
+ cert = tempfile.path if entry.full_name.end_with? '.cert'
195
+ end
196
+
197
+ File.read(mf).each_line do |line|
198
+ name = line.scan(/SHA1\(([^\)]*)\)= (.*)/).flatten.first
199
+ sha1 = line.scan(/SHA1\(([^\)]*)\)= (.*)/).flatten.last
200
+ puts Digest::SHA1.hexdigest(files[name])
201
+ raise "SHA1 mismatch for file #{name}" if Digest::SHA1.hexdigest(File.read(files[name])) != sha1
202
+ end if mf
203
+
204
+ raise 'no ovf file found' if ovf.nil?
205
+
206
+ self.ovf(File.read(ovf), files)
207
+ end
208
+
209
+ def self.ovf(ovf, files={ })
210
+ collection = OCCI::Collection.new
211
+ doc = Nokogiri::XML(ovf)
212
+ references = { }
213
+
214
+ doc.xpath('envelope:Envelope/envelope:References/envelope:File', 'envelope' => "#{Parser::OVF}").each do |file|
215
+ href = URI.parse(file.attributes['href'].to_s)
216
+ if href.relative?
217
+ references[file.attributes['id'].to_s] = 'file://' + files[href.to_s] if files[href.to_s]
218
+ else
219
+ references[file.attributes['id'].to_s] = href
220
+ end
221
+ end
222
+
223
+ doc.xpath('envelope:Envelope/envelope:DiskSection/envelope:Disk', 'envelope' => "#{Parser::OVF}").each do |disk|
224
+ storage = OCCI::Core::Resource.new('http://schemas.ogf.org/occi/infrastructure#storage')
225
+ if disk.attributes['fileRef']
226
+ storagelink = OCCI::Core::Link.new("http://schemas.ogf.org/occi/infrastructure#storagelink")
227
+ storagelink.attributes.occi!.core!.title = disk.attributes['fileRef'].to_s
228
+ storagelink.attributes.occi!.core!.target = references[disk.attributes['fileRef'].to_s]
229
+ storage.attributes.occi!.core!.title = disk.attributes['diskId'].to_s
230
+ storage.links << storagelink
231
+ else
232
+ #OCCI accepts storage size in GB
233
+ #OVF ver 1.1: The capacity of a virtual disk shall be specified by the ovf:capacity attribute with an xs:long integer
234
+ #value. The default unit odf allocation shall be bytes. The optional string attribute
235
+ #ovf:capacityAllocationUnits may be used to specify a particular unit of allocation.
236
+ alloc_units = disk.attributes['capacityAllocationUnits'].to_s
237
+ if alloc_units.empty?
238
+ # The capacity is defined in bytes , convert to GB and pass it to OCCI
239
+ capacity = disk.attributes['capacity'].to_s
240
+ capacity =capacity.to_i
241
+ else
242
+ alloc_unit_bytes = self.alloc_units_bytes(alloc_units)
243
+ capacity = self.calculate_capacity_bytes(disk.attributes['capacity'].to_s, alloc_unit_bytes)
244
+ end
245
+ capacity_gb = self.calculate_capacity_gb(capacity)
246
+ OCCI::Log.debug('capacity in gb ' + capacity_gb.to_s)
247
+ storage.attributes.occi!.storage!.size = capacity_gb.to_s if capacity_gb
248
+ storage.attributes.occi!.core!.title = disk.attributes['diskId'].to_s if disk.attributes['diskId']
249
+ end
250
+ collection.resources << storage
251
+ end
252
+
253
+ doc.xpath('envelope:Envelope/envelope:NetworkSection/envelope:Network', 'envelope' => "#{Parser::OVF}").each do |nw|
254
+ network = OCCI::Core::Resource.new('http://schemas.ogf.org/occi/infrastructure#network')
255
+ network.attributes.occi!.core!.title = nw.attributes['name'].to_s
256
+ collection.resources << network
257
+ end
258
+
259
+ # Iteration through all the virtual hardware sections,and a sub-iteration on each Item defined in the Virtual Hardware section
260
+ doc.xpath('envelope:Envelope/envelope:VirtualSystem', 'envelope' => "#{Parser::OVF}").each do |virtsys|
261
+ compute = OCCI::Core::Resource.new('http://schemas.ogf.org/occi/infrastructure#compute')
262
+
263
+ doc.xpath('envelope:Envelope/envelope:VirtualSystem/envelope:VirtualHardwareSection', 'envelope' => "#{Parser::OVF}").each do |virthwsec|
264
+ compute.attributes.occi!.core!.summary = virthwsec.xpath("item:Info/text()", 'item' => "#{Parser::RASD}").to_s
265
+
266
+ virthwsec.xpath('envelope:Item', 'envelope' => "#{Parser::OVF}").each do |resource_alloc|
267
+ resType = resource_alloc.xpath("item:ResourceType/text()", 'item' => "#{Parser::RASD}")
268
+ case resType.to_s
269
+ # 4 is the ResourceType for memory in the CIM_ResourceAllocationSettingData
270
+ when "4" then
271
+ compute.attributes.occi!.compute!.memory = resource_alloc.xpath("item:VirtualQuantity/text()", 'item' => "#{Parser::RASD}").to_s.to_i
272
+ # 3 is the ResourceType for processor in the CIM_ResourceAllocationSettingData
273
+ when "3" then
274
+ compute.attributes.occi!.compute!.cores = resource_alloc.xpath("item:VirtualQuantity/text()", 'item' => "#{Parser::RASD}").to_s.to_i
275
+ when "10" then
276
+ networkinterface = OCCI::Core::Link.new('http://schemas.ogf.org/occi/infrastructure#networkinterface')
277
+ networkinterface.attributes.occi!.core!.title = resource_alloc.xpath("item:ElementName/text()", 'item' => "#{Parser::RASD}").to_s
278
+ id = resource_alloc.xpath("item:Connection/text()", 'item' => "#{Parser::RASD}").to_s
279
+ network = collection.resources.select { |resource| resource.attributes.occi!.core!.title == id }.first
280
+ raise "Network with id #{id} not found" unless network
281
+ networkinterface.attributes.occi!.core!.target = network.location
282
+ when "17" then
283
+ storagelink = OCCI::Core::Link.new("http://schemas.ogf.org/occi/infrastructure#storagelink")
284
+ storagelink.attributes.occi!.core!.title = resource_alloc.xpath("item:ElementName/text()", 'item' => "#{Parser::RASD}").to_s
285
+ # extract the mountpoint
286
+ host_resource = resource_alloc.xpath("item:HostResource/text()", 'item' => "#{Parser::RASD}").to_s
287
+ if host_resource.start_with? 'ovf:/disk/'
288
+ id = host_resource.gsub('ovf:/disk/', '')
289
+ storage = collection.resources.select { |resource| resource.attributes.occi!.core!.title == id }.first
290
+ raise "Disk with id #{id} not found" unless storage
291
+ storagelink.attributes.occi!.core!.target = storage.location
292
+ elsif host_resource.start_with? 'ovf:/file/'
293
+ id = host_resource.gsub('ovf:/file/','')
294
+ storagelink.attributes.occi!.core!.target = references[id]
295
+ end
296
+ compute.links << storagelink
297
+ end
298
+ ##Add the cpu architecture
299
+ #system_sec = virthwsec.xpath('envelope:System', 'envelope' => "#{Parser::OVF}")
300
+ #virtsys_type = system_sec.xpath('vssd_:VirtualSystemType/text()', 'vssd_' => "#{Parser::VSSD}")
301
+ #compute.attributes.occi!.compute!.architecture = virtsys_type
302
+ end
303
+ end
304
+ collection.resources << compute
305
+ end
306
+ collection
307
+ end
181
308
  end
182
309
 
183
310
  end
@@ -1,3 +1,3 @@
1
1
  module OCCI
2
- VERSION = "2.2.2" unless defined?(::OCCI::VERSION)
2
+ VERSION = "2.3.0" unless defined?(::OCCI::VERSION)
3
3
  end
@@ -0,0 +1,12 @@
1
+ require 'rspec'
2
+ require 'occi'
3
+
4
+ module OCCI
5
+ describe Client do
6
+
7
+ it "should do something" do
8
+
9
+ # TODO: Implement scenarios for client
10
+ end
11
+ end
12
+ end
@@ -7,7 +7,8 @@ module OCCI
7
7
  describe "log messages" do
8
8
  it "should log a message to a pipe" do
9
9
  r, w = IO.pipe
10
- OCCI::Log.new(w, OCCI::Log::INFO)
10
+ logger = OCCI::Log.new(w)
11
+ logger.level = OCCI::Log::INFO
11
12
  OCCI::Log.info("Test")
12
13
  r.readline.include?("Test")
13
14
  end
@@ -4,23 +4,52 @@ require 'occi/model'
4
4
  describe "Model" do
5
5
 
6
6
  it "initializes Core Model successfully" do
7
- OCCI::Model.register_core
8
- OCCI::Model.get_by_id('http://schemas.ogf.org/occi/core#entity').should be_kind_of OCCI::Core::Kind
9
- OCCI::Model.get_by_id('http://schemas.ogf.org/occi/core#resource').should be_kind_of OCCI::Core::Kind
10
- OCCI::Model.get_by_id('http://schemas.ogf.org/occi/core#link').should be_kind_of OCCI::Core::Kind
7
+ model = OCCI::Model.new
8
+ model.get_by_id('http://schemas.ogf.org/occi/core#entity').should be_kind_of OCCI::Core::Kind
9
+ model.get_by_id('http://schemas.ogf.org/occi/core#resource').should be_kind_of OCCI::Core::Kind
10
+ model.get_by_id('http://schemas.ogf.org/occi/core#link').should be_kind_of OCCI::Core::Kind
11
11
  end
12
12
 
13
13
  it "initializes Infrastructure Model successfully" do
14
- OCCI::Model.register_files('etc/model/infrastructure/')
15
- OCCI::Model.get_by_id('http://schemas.ogf.org/occi/infrastructure#compute').should be_kind_of OCCI::Core::Kind
16
- OCCI::Model.get_by_id('http://schemas.ogf.org/occi/infrastructure#os_tpl').should be_kind_of OCCI::Core::Mixin
17
- OCCI::Model.get_by_id('http://schemas.ogf.org/occi/infrastructure#resource_tpl').should be_kind_of OCCI::Core::Mixin
18
- OCCI::Model.get_by_id('http://schemas.ogf.org/occi/infrastructure#network').should be_kind_of OCCI::Core::Kind
19
- OCCI::Model.get_by_id('http://schemas.ogf.org/occi/infrastructure/network#ipnetwork').should be_kind_of OCCI::Core::Mixin
20
- OCCI::Model.get_by_id('http://schemas.ogf.org/occi/infrastructure#networkinterface').should be_kind_of OCCI::Core::Kind
21
- OCCI::Model.get_by_id('http://schemas.ogf.org/occi/infrastructure/networkinterface#ipnetworkinterface').should be_kind_of OCCI::Core::Mixin
22
- OCCI::Model.get_by_id('http://schemas.ogf.org/occi/infrastructure#storage').should be_kind_of OCCI::Core::Kind
23
- OCCI::Model.get_by_id('http://schemas.ogf.org/occi/infrastructure#storagelink').should be_kind_of OCCI::Core::Kind
14
+ model = OCCI::Model.new
15
+ model.register_infrastructure
16
+ model.get_by_id('http://schemas.ogf.org/occi/infrastructure#compute').should be_kind_of OCCI::Core::Kind
17
+ model.get_by_id('http://schemas.ogf.org/occi/infrastructure#os_tpl').should be_kind_of OCCI::Core::Mixin
18
+ model.get_by_id('http://schemas.ogf.org/occi/infrastructure#resource_tpl').should be_kind_of OCCI::Core::Mixin
19
+ model.get_by_id('http://schemas.ogf.org/occi/infrastructure#network').should be_kind_of OCCI::Core::Kind
20
+ model.get_by_id('http://schemas.ogf.org/occi/infrastructure/network#ipnetwork').should be_kind_of OCCI::Core::Mixin
21
+ model.get_by_id('http://schemas.ogf.org/occi/infrastructure#networkinterface').should be_kind_of OCCI::Core::Kind
22
+ model.get_by_id('http://schemas.ogf.org/occi/infrastructure/networkinterface#ipnetworkinterface').should be_kind_of OCCI::Core::Mixin
23
+ model.get_by_id('http://schemas.ogf.org/occi/infrastructure#storage').should be_kind_of OCCI::Core::Kind
24
+ model.get_by_id('http://schemas.ogf.org/occi/infrastructure#storagelink').should be_kind_of OCCI::Core::Kind
25
+ end
26
+
27
+ it "returns all registered categories" do
28
+ model = OCCI::Model.new
29
+ collection = model.get
30
+ collection.kind_of? OCCI::Collection
31
+ collection.kinds.should have(3).kinds
32
+ collection.mixins.should be_empty
33
+ collection.actions.should be_empty
34
+ collection.resources.should be_empty
35
+ collection.links.should be_empty
36
+ end
37
+
38
+ it "returns categories with filter" do
39
+ model = OCCI::Model.new
40
+ model.register_infrastructure
41
+ compute = OCCI::Core::Kind.new('http://schemas.ogf.org/occi/infrastructure#','compute')
42
+ ipnetwork = OCCI::Core::Mixin.new('http://schemas.ogf.org/occi/infrastructure/network#','ipnetwork')
43
+ filter = OCCI::Collection.new
44
+ filter.kinds << compute
45
+ filter.mixins << ipnetwork
46
+ collection = model.get(filter)
47
+ collection.kind_of? OCCI::Collection
48
+ collection.kinds.first.attributes.should be_kind_of OCCI::Core::AttributeProperties
49
+ collection.mixins.first.attributes.should be_kind_of OCCI::Core::AttributeProperties
50
+ collection.actions.should be_empty
51
+ collection.resources.should be_empty
52
+ collection.links.should be_empty
24
53
  end
25
54
 
26
55
  end
@@ -5,8 +5,23 @@ describe "Parser" do
5
5
 
6
6
  it "should parse OCCI message with entity in text plain format" do
7
7
  media_type = 'text/plain'
8
- body = %Q|Category: compute; scheme="http://schemas.ogf.org/occi/infrastructure#"; class="kind"\nX-OCCI-Attribute: occi.compute.cores=2|
9
- category = false
10
- OCCI::Parser.parse(media_type,body,category)
8
+ body = %Q|Category: compute; scheme="http://schemas.ogf.org/occi/infrastructure#"; class="kind"\nX-OCCI-Attribute: occi.compute.cores=2|
9
+ locations, collection = OCCI::Parser.parse(media_type, body)
10
+ end
11
+
12
+ it "should parse an OVA container" do
13
+ media_type = 'application/ova'
14
+ body = File.read('spec/occi/test.ova')
15
+ locations, collection = OCCI::Parser.parse(media_type, body)
16
+ storage_resources = collection.resources.select { |resource| resource.kind == 'http://schemas.ogf.org/occi/infrastructure#storage' }
17
+ storage_resources.should have(1).storage_resource
18
+ storage_resources.first.attributes.occi!.core!.title.should == 'lamp'
19
+ network_resources = collection.resources.select { |resource| resource.kind == 'http://schemas.ogf.org/occi/infrastructure#network' }
20
+ network_resources.should have(1).network_resource
21
+ network_resources.first.attributes.occi!.core!.title.should == 'VM Network'
22
+ compute_resources = collection.resources.select { |resource| resource.kind == 'http://schemas.ogf.org/occi/infrastructure#compute' }
23
+ compute_resources.should have(1).compute_resource
24
+ compute_resources.first.attributes.occi!.compute!.cores.should == 1
25
+ compute_resources.first.attributes.occi!.compute!.memory.should == 256
11
26
  end
12
27
  end