occi 2.0.0 → 2.0.1

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.
data/lib/occi/server.rb DELETED
@@ -1,594 +0,0 @@
1
- ##############################################################################
2
- # Copyright 2011 Service Computing group, TU Dortmund
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
- ##############################################################################
16
-
17
- ##############################################################################
18
- # Description: OCCI RESTful Web Service
19
- # Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak
20
- ##############################################################################
21
-
22
- ##############################################################################
23
- # Require Ruby Gems
24
-
25
- # gems
26
- require 'rubygems'
27
-
28
- # sinatra
29
- require 'sinatra'
30
- require 'sinatra/multi_route'
31
- require 'sinatra/cross_origin'
32
- require 'sinatra/respond_with'
33
-
34
- # Ruby standard library
35
- require 'uri'
36
- require 'fileutils'
37
-
38
- # Server configuration
39
- require 'occi/configuration'
40
-
41
- # Active support notifications
42
- require 'active_support/notifications'
43
-
44
- # Active support for xml rendering
45
- require 'active_support/core_ext'
46
-
47
- ##############################################################################
48
- # Require OCCI classes
49
-
50
- # Exceptions
51
- require 'occi/exceptions'
52
-
53
- # Category registry
54
- require 'occi/registry'
55
-
56
- # OCCI Core classes
57
- require 'occi/core/action'
58
- require 'occi/core/category'
59
- require 'occi/core/entity'
60
- require 'occi/core/kind'
61
- require 'occi/core/link'
62
- require 'occi/core/mixin'
63
- require 'occi/core/resource'
64
-
65
- # OCCI parser
66
- require 'occi/parse'
67
-
68
- # Backend support
69
- require 'occi/backend/manager'
70
-
71
- ##############################################################################
72
- # Sinatra methods for handling HTTP requests
73
-
74
- module OCCI
75
- class Server < Sinatra::Application
76
-
77
- register Sinatra::MultiRoute
78
- register Sinatra::CrossOrigin
79
- register Sinatra::RespondWith
80
-
81
- enable cross_origin
82
-
83
- # Read configuration file
84
- def self.config
85
- @@config ||= OCCI::Configuration.new('etc/occi-server.conf')
86
- end
87
-
88
- def self.location
89
- OCCI::Server.config[:server].chomp('/')
90
- end
91
-
92
- def self.port
93
- OCCI::Server.config[:port]
94
- end
95
-
96
- def self.uri
97
- self.port.nil? ? self.location : self.location + ':' + self.port
98
- end
99
-
100
- def initialize(config = {})
101
- # create logger
102
- config[:log_dest] ||= STDOUT
103
- config[:log_level] ||= Logger::INFO
104
- config[:log_level] = case OCCI::Server.config[:log_level]
105
- when "debug"
106
- Logger::DEBUG
107
- when "info"
108
- Logger::INFO
109
- when "warn"
110
- Logger::WARN
111
- when "error"
112
- Logger::ERROR
113
- when "fatal"
114
- Logger::FATAL
115
- else
116
- Logger::INFO
117
- end
118
-
119
- @logger = Logger.new(config[:log_dest])
120
- @logger.level = config[:log_level]
121
-
122
- # subscribe to log messages and send to logger
123
- @log_subscriber = ActiveSupport::Notifications.subscribe("log") do |name, start, finish, id, payload|
124
- @logger.log(payload[:level], payload[:message])
125
- end
126
-
127
- # Configuration of HTTP Authentication
128
- if OCCI::Server.config['username'] != nil and OCCI::Server.config['password'] != nil
129
- use Rack::Auth::Basic, "Restricted Area" do |username, password|
130
- [username, password] == [OCCI::Server.config['username'], OCCI::Server.config['password']]
131
- end
132
- end
133
-
134
- OCCI::Server.initialize_core_model
135
- OCCI::Server.initialize_model(OCCI::Server.config['occi_model_path'])
136
-
137
- # set views explicitly
138
- set :views, File.dirname(__FILE__) + "/../../views"
139
-
140
- super
141
- end
142
-
143
- # ---------------------------------------------------------------------------------------------------------------------
144
-
145
- def self.initialize_core_model
146
- OCCI::Log.info("### Initializing OCCI Core Model ###")
147
- OCCI::Core::Entity.register
148
- OCCI::Core::Resource.register
149
- OCCI::Core::Link.register
150
- end
151
-
152
- def self.initialize_model(path)
153
- OCCI::Log.info("### Initializing OCCI Model from #{path} ###")
154
- Dir.glob(path + '/**/*.json').each do |file|
155
- collection = Hashie::Mash.new(JSON.parse(File.read(file)))
156
- # add location of service provider to scheme if it has a relative location
157
- collection.kinds.collect { |kind| kind.scheme = self.location + kind.scheme if kind.scheme.start_with? '/' } if collection.kinds
158
- collection.mixins.collect { |mixin| mixin.scheme = self.location + mixin.scheme if mixin.scheme.start_with? '/' } if collection.mixins
159
- collection.actions.collect { |action| action.scheme = self.location + action.scheme if action.scheme.start_with? '/' } if collection.actions
160
- # register categories
161
- collection.kinds.each { |kind| OCCI::Registry.register(OCCI::Core::Kind.new(kind)) } if collection.kinds
162
- collection.mixins.each { |mixin| OCCI::Registry.register(OCCI::Core::Mixin.new(mixin)) } if collection.mixins
163
- collection.actions.each { |action| OCCI::Registry.register(OCCI::Core::Action.new(action)) } if collection.actions
164
- end
165
- end
166
-
167
- # ---------------------------------------------------------------------------------------------------------------------
168
- def initialize_backend(auth)
169
-
170
- if auth.provided? && auth.basic? && auth.credentials
171
- user, password = auth.credentials
172
- else
173
- user, password = [OCCI::Server.config['one_user'], OCCI::Server.config['one_password']]
174
- logger.debug("No basic auth data provided: using defaults from config (user = '#{user}')")
175
- end
176
-
177
- @backend = case OCCI::Server.config["backend"]
178
- when "opennebula"
179
- require 'occi/backend/opennebula/opennebula'
180
- OCCI::Server.initialize_model('etc/backend/opennebula')
181
- OCCI::Backend::Manager.register_backend(OCCI::Backend::OpenNebula::OpenNebula, OCCI::Backend::OpenNebula::OpenNebula::OPERATIONS)
182
- OCCI::Backend::OpenNebula::OpenNebula.new(user, password)
183
- when "ec2"
184
- require 'occi/backend/ec2/ec2'
185
- Bundler.require(:ec2)
186
- OCCI::Server.initialize_model('etc/backend/ec2')
187
- OCCI::Backend::Manager.register_backend(OCCI::Backend::EC2::EC2, OCCI::Backend::EC2::EC2::OPERATIONS)
188
- OCCI::Backend::EC2::EC2.new(user, password)
189
- when "dummy" then
190
- require 'occi/backend/dummy'
191
- OCCI::Backend::Manager.register_backend(OCCI::Backend::Dummy, OCCI::Backend::Dummy::OPERATIONS)
192
- OCCI::Backend::Dummy.new()
193
- else
194
- raise "Backend '" + OCCI::Server.config["backend"] + "' not found"
195
- end
196
-
197
-
198
- end
199
-
200
- # Parses a Rack/Sinatra Request and extract OCCI relevant information
201
- def parse(request)
202
- OCCI::Log.debug('### Parsing request data to OCCI data structure ###')
203
- body = request.body.read
204
- header = request.env
205
- collection = OCCI::Core::Collection.new
206
- locations = []
207
- # always check headers
208
- locations = OCCI::Parse.header_locations(header)
209
- if locations.empty?
210
- if request.path_info.include?('/-/')
211
- collection = OCCI::Parse.header_categories(header)
212
- else
213
- collection = OCCI::Parse.header_entity(header)
214
- end
215
- end
216
-
217
- case request.media_type
218
- when 'text/uri-list'
219
- body.each_line do |line|
220
- locations << URI.parse(line)
221
- end
222
- when 'text/plain', nil
223
- locations = OCCI::Parse.text_locations(body)
224
- if locations.empty?
225
- if request.path_info.include?('/-/')
226
- collection = OCCI::Parse.text_categories(body)
227
- else
228
- collection = OCCI::Parse.text_entity(body)
229
- end
230
- end
231
- when 'application/occi+json', 'application/json'
232
- collection = OCCI::Parse.json(body)
233
- when 'application/occi+xml', 'application/xml'
234
- collection = OCCI::Parse.xml(body)
235
- else
236
- raise OCCI::ContentTypeNotSupported
237
- end
238
- return locations, collection
239
- end
240
-
241
- # ---------------------------------------------------------------------------------------------------------------------
242
-
243
- # GET request
244
-
245
- # tasks to be executed before the request is handled
246
- before do
247
- OCCI::Log.debug('--------------------------------------------------------------------')
248
- OCCI::Log.debug("### Client IP: #{request.ip}")
249
- OCCI::Log.debug("### Client Accept: #{request.accept}")
250
- OCCI::Log.debug("### Client User Agent: #{request.user_agent}")
251
- OCCI::Log.debug("### Client Request URL: #{request.url}")
252
- OCCI::Log.debug("### Client Request method: #{request.request_method}")
253
- OCCI::Log.debug("### Client Request Media Type: #{request.media_type}")
254
- OCCI::Log.debug('--------------------------------------------------------------------')
255
-
256
- OCCI::Log.debug('### Prepare response ###')
257
- response['Accept'] = "application/occi+json,application/json,text/plain,text/uri-list,application/xml,text/xml,application/occi+xml"
258
- response['Server'] = "rOCCI/#{VERSION_NUMBER} OCCI/1.1"
259
- OCCI::Log.debug('### Initialize response OCCI collection ###')
260
- @collection = Hashie::Mash.new(:kinds => [], :mixins => [], :actions => [], :resources => [], :links => [])
261
- @locations = Array.new
262
- OCCI::Log.debug('### Preparing authentication handling ###')
263
- authentication = Rack::Auth::Basic::Request.new(request.env)
264
- OCCI::Log.debug('### Initializing backend ###')
265
- initialize_backend(authentication)
266
- OCCI::Log.debug('### Reset OCCI model ###')
267
- OCCI::Registry.reset
268
- @request_locations, @request_collection = parse(request)
269
- OCCI::Log.debug('### Fill OCCI model with entities from backend ###')
270
- @backend.register_existing_resources
271
- end
272
-
273
- after do
274
- # OCCI::Log.debug((@collection.resources.to_a + @collection.links.to_a).collect {|entity| entity.location}.join("\n"))
275
- OCCI::Log.debug('### Rendering response ###')
276
- @collection.delete_if { |k, v| v.empty? } # remove empty entries
277
- respond_to do |f|
278
- f.txt { erb :collection, :locals => {:collection => @collection, :locations => @locations} }
279
- f.on('*/*') { erb :collection, :locals => {:collection => @collection, :locations => @locations} }
280
- # f.html { haml :collection, :locals => {:collection => @collection} }
281
- f.json { @collection.to_json }
282
- f.on('application/occi+json') { @collection.to_json }
283
- f.xml { @collection.to_xml(:root => "collection") }
284
- f.on('application/occi+xml') { @collection.to_xml(:root => "collection") }
285
- f.on('text/uri-list') { @locations.join("\n") }
286
- end
287
- OCCI::Log.debug('### Successfully rendered ###')
288
- end
289
-
290
- # discovery interface
291
- # returns all kinds, mixins and actions registered for the server
292
- get '/-/', '/.well-known/org/ogf/occi/-/' do
293
- OCCI::Log.info("### Listing all kinds, mixins and actions ###")
294
- @collection = OCCI::Registry.get(@request_collection.categories)
295
- status 200
296
- end
297
-
298
- # Resource retrieval
299
- # returns entities either below a certain path or belonging to a certain kind or mixin
300
- get '*' do
301
- if request.path_info.end_with?('/')
302
- if request.path_info == '/'
303
- kinds = OCCI::Registry.get.kinds
304
- else
305
- kinds = [OCCI::Registry.get_by_location(request.path_info)]
306
- end
307
-
308
- kinds.each do |kind|
309
- OCCI::Log.info("### Listing all entities of kind #{kind.type_identifier} ###")
310
- @collection.resources.concat kind.entities if kind.entity_type == OCCI::Core::Resource.name
311
- @collection.links.concat kind.entities if kind.entity_type == OCCI::Core::Link.name
312
- @locations.concat kind.entities.collect { |entity| OCCI::Server.uri + entity.location }
313
- end
314
- else
315
- kind = OCCI::Registry.get_by_location(request.path_info.rpartition('/').first + '/')
316
- uuid = request.path_info.rpartition('/').last
317
- error 404 if kind.nil? or uuid.nil?
318
- OCCI::Log.info("### Listing entity with uuid #{uuid} ###")
319
- @collection.resources = kind.entities.select { |entity| entity.id == uuid } if kind.entity_type == OCCI::Core::Resource.name
320
- @collection.links = kind.entities.select { |entity| entity.id == uuid } if kind.entity_type == OCCI::Core::Link.name
321
- end
322
- status 200
323
- end
324
-
325
- # ---------------------------------------------------------------------------------------------------------------------
326
- # POST request
327
- post '/-/', '/.well-known/org/ogf/occi/-/' do
328
- logger.info("## Creating user defined mixin ###")
329
- raise OCCI::MixinAlreadyExistsError, "Mixin already exists!" if OCCI::Registry.get(@request_collection.mixins)
330
- @request_collection.mixins.each do |mixin|
331
- OCCI::CategoryRegistry.register(mixin)
332
- # TODO: inform backend about new mixin
333
- end
334
- end
335
-
336
- # Create an instance appropriate to category field and optionally link an instance to another one
337
- post '*' do
338
-
339
- category = OCCI::Registry.get_by_location(request.path_info.rpartition('/').first + '/')
340
-
341
- if category.nil?
342
- OCCI::Log.debug("### No category found for request location #{request.path_info} ###")
343
- status 404
344
- end
345
-
346
- # if action
347
- if params[:action]
348
- if @request_collection.actions.any?
349
- action = @request_collection.actions.first
350
- params[:method] ||= action.attributes!.method if action
351
- else
352
- action = OCCI::Registry.get_by_id(category.actions.select { |action| action.split('#').last == params[:action] }.first)
353
- end
354
-
355
- category.entities.each do |entity|
356
- OCCI::Backend::Manager.delegate_action(@backend, action, params, entity)
357
- status 200
358
- end
359
- elsif category.kind_of?(OCCI::Core::Kind)
360
- @request_collection.resources.each do |resource|
361
- OCCI::Log.debug("Deploying resource with title #{resource.title} in backend #{@backend.class.name}")
362
- OCCI::Backend::Manager.signal_resource(@backend, OCCI::Backend::RESOURCE_DEPLOY, resource)
363
- @locations << OCCI::Server.uri + resource.location
364
- status 201
365
- end
366
- elsif category.kind_of?(OCCI::Core::Mixin)
367
- @request_collection.locations.each do |location|
368
- OCCI::Log.debug("Attaching resource #{resource.title} to mixin #{mixin.type_identifier} in backend #{@backend.class.name}")
369
- # TODO: let backend carry out tasks related to the added mixin
370
- category.entities << OCCI::Rendering::HTTP::LocationRegistry.get_object(location)
371
- status 200
372
- end
373
- else
374
- status 400
375
- end
376
-
377
- end
378
-
379
- # ---------------------------------------------------------------------------------------------------------------------
380
- # PUT request
381
-
382
- put '*' do
383
-
384
- # Add an resource instance to a mixin
385
- unless @occi_request.mixins.empty?
386
- mixin = OCCI::Rendering::HTTP::LocationRegistry.get_object(request.path_info)
387
-
388
- @occi_request.locations.each do |location|
389
- entity = OCCI::Rendering::HTTP::LocationRegistry.get_object(URI.parse(location).path)
390
-
391
- raise "No entity found at location: #{entity_location}" if entity == nil
392
- raise "Object referenced by uri [#{entity_location}] is not a OCCI::Core::Resource instance!" if !entity.kind_of?(OCCI::Core::Resource)
393
-
394
- logger.debug("Associating entity [#{entity}] at location #{entity_location} with mixin #{mixin}")
395
-
396
- entity.mixins << mixin
397
- end
398
- break
399
- end
400
-
401
- # Update resource instance(s) at the given location
402
- unless OCCI::Rendering::HTTP::LocationRegistry.get_object(request.path_info).nil?
403
- entities = []
404
- # Determine set of resources to be updated
405
- if OCCI::Rendering::HTTP::LocationRegistry.get_object(request.path_info).kind_of?(OCCI::Core::Resource)
406
- entities = [OCCI::Rendering::HTTP::LocationRegistry.get_object(request.path_info)]
407
- elsif not OCCI::Rendering::HTTP::LocationRegistry.get_object(request.path_info).kind_of?(OCCI::Core::Category)
408
- entities = OCCI::Rendering::HTTP::LocationRegistry.get_resources_below_location(request.path_info, OCCI::CategoryRegistry.get_all)
409
- elsif OCCI::Rendering::HTTP::LocationRegistry.get_object(request.path_info).kind_of?(OCCI::Core::Category)
410
- object = OCCI::Rendering::HTTP::LocationRegistry.get_object(request.path_info)
411
- @occi_request.locations.each do |loc|
412
- entities << OCCI::Rendering::HTTP::LocationRegistry.get_object(URI.parse(loc.chomp('"').reverse.chomp('"').reverse).path)
413
- end
414
- end
415
- logger.info("Full update for [#{entities.size}] entities...")
416
-
417
- # full update of mixins
418
- object.entities.each do |entity|
419
- entity.mixins.delete(object)
420
- object.entities.delete(entity)
421
- end if object.kind_of?(OCCI::Core::Mixin)
422
-
423
- entities.each do |entity|
424
- logger.debug("Adding entity: #{entity.get_location} to mixin #{object.type_identifier}")
425
- entity.mixins.push(object).uniq!
426
- object.entities.push(entity).uniq!
427
- end if object.kind_of?(OCCI::Core::Mixin)
428
-
429
- # full update of attributes
430
- entities.each do |entity|
431
- # Refresh information from backend for entities of type resource
432
- # TODO: full update
433
- entity.attributes.merge!(@occi_request.attributes)
434
- # TODO: update entity in backend
435
- end unless @occi_request.attributes.empty?
436
-
437
- # full update of links
438
- # TODO: full update e.g. delete old links first
439
- @occi_request.links.each do |link_data|
440
- logger.debug("Extracted link data: #{link_data}")
441
- raise "Mandatory information missing (related | target | category)!" unless link_data.related != nil && link_data.target != nil && link_data.category != nil
442
-
443
- link_mixins = []
444
- link_kind = nil
445
- link_data.category.split(' ').each do |link_category|
446
- begin
447
- cat = OCCI::CategoryRegistry.get_by_id(link_category)
448
- rescue OCCI::CategoryNotFoundException => e
449
- logger.info("Category #{link_category} not found")
450
- next
451
- end
452
- link_kind = cat if cat.kind_of?(OCCI::Core::Kind)
453
- link_mixins << cat if cat.kind_of?(OCCI::Core::Mixin)
454
- end
455
-
456
- raise "No kind for link category #{link_data.category} found" if link_kind.nil?
457
-
458
- target_location = link_data.target_attr
459
- target = OCCI::Rendering::HTTP::LocationRegistry.get_object(target_location)
460
-
461
- entities.each do |entity|
462
-
463
- source_location = OCCI::Rendering::HTTP::LocationRegistry.get_location_of_object(entity)
464
-
465
- link_attributes = link_data.attributes.clone
466
- link_attributes["occi.core.target"] = target_location.chomp('"').reverse.chomp('"').reverse
467
- link_attributes["occi.core.source"] = source_location
468
-
469
- link = link_kind.entity_type.new(link_attributes, link_mixins)
470
- OCCI::Rendering::HTTP::LocationRegistry.register_location(link.get_location(), link)
471
-
472
- target.links << link
473
- entity.links << link
474
- end
475
- end
476
- break
477
- end
478
-
479
- response.status = OCCI::Rendering::HTTP::Response::HTTP_NOT_FOUND
480
- # Create resource instance at the given location
481
- raise "Creating resources with method 'put' is currently not possible!"
482
-
483
- # This must be the last statement in this block, so that sinatra does not try to respond with random body content
484
- # (or fail utterly while trying to do that!)
485
- nil
486
-
487
- end
488
-
489
- # ---------------------------------------------------------------------------------------------------------------------
490
- # DELETE request
491
-
492
- delete '/-/', '/.well-known/org/ogf/occi/-/' do
493
- # Location references query interface => delete provided mixin
494
- raise OCCI::CategoryMissingException if @request_collection.mixins.nil?
495
- mixins = OCCI::Registry.get(@request_collection.mixins)
496
- raise OCCI::MixinNotFoundException if mixins.nil?
497
- mixins.each do |mixin|
498
- OCCI::Log.debug("### Deleting mixin #{mixin.type_identifier} ###")
499
- mixin.entities.each do |entity|
500
- entity.mixins.delete(mixin)
501
- end
502
- # TODO: Notify backend to delete mixin and unassociate entities
503
- OCCI::Registry.unregister(mixin)
504
- end
505
- status 200
506
- end
507
-
508
- delete '*' do
509
-
510
- # unassociate resources specified by URI in payload from mixin specified by request location
511
- if request.path_info == '/'
512
- categories = OCCI::Registry.get.kinds
513
- else
514
- categories = [OCCI::Registry.get_by_location(request.path_info.rpartition('/').first + '/')]
515
- end
516
-
517
- categories.each do |category|
518
- case category
519
- when OCCI::Core::Mixin
520
- mixin = category
521
- OCCI::Log.debug("### Deleting entities from mixin #{mixin.type_identifier} ###")
522
- @request_collection.locations.each do |location|
523
- uuid = location.to_s.rpartition('/').last
524
- mixin.entities.delete_if { |entity| entity.id == uuid }
525
- end
526
- when OCCI::Core::Kind
527
- kind = category
528
- if request.path_info.end_with?('/')
529
- if @request_collection.mixins.any?
530
- @request_collection.mixins.each do |mixin|
531
- OCCI::Log.debug("### Deleting entities from kind #{kind.type_identifier} with mixin #{mixin.type_identifier} ###")
532
- kind.entities.each { |entity| OCCI::Backend::Manager.signal_resource(@backend, OCCI::Backend::RESOURCE_DELETE, entity) if mixin.include?(entity) }
533
- kind.entities.delete_if? { |entity| mixin.include?(entity) }
534
- # TODO: links
535
- end
536
- else
537
- # TODO: links
538
- OCCI::Log.debug("### Deleting entities from kind #{kind.type_identifier} ###")
539
- kind.entities.each { |resource| OCCI::Backend::Manager.signal_resource(@backend, OCCI::Backend::RESOURCE_DELETE, resource) }
540
- kind.entities.clear
541
- end
542
- else
543
- uuid = request.path_info.rpartition('/').last
544
- OCCI::Log.debug("### Deleting entity with id #{uuid} from kind #{kind.type_identifier} ###")
545
- OCCI::Backend::Manager.signal_resource(@backend, OCCI::Backend::RESOURCE_DELETE, entity)
546
- kind.entities.delete_if? { |entity| entity.id == uuid }
547
- end
548
- end
549
- end
550
-
551
- # delete entities
552
-
553
-
554
- # # Location references a mixin => unassociate all provided resources (by X_OCCI_LOCATION) from it
555
- # object = OCCI::Rendering::HTTP::LocationRegistry.get_object(request.path_info)
556
- # if object != nil && object.kind_of?(OCCI::Core::Mixin)
557
- # mixin = OCCI::Rendering::HTTP::LocationRegistry.get_object(request.path_info)
558
- # logger.info("Unassociating entities from mixin: #{mixin}")
559
- #
560
- # @occi_request.locations.each do |loc|
561
- # entity = OCCI::Rendering::HTTP::LocationRegistry.get_object(URI.parse(loc.chomp('"').reverse.chomp('"').reverse).path)
562
- # mixin.entities.delete(entity)
563
- # entity.mixins.delete(mixin)
564
- # end
565
- # break
566
- # end
567
- #
568
- # entities = OCCI::Rendering::HTTP::LocationRegistry.get_resources_below_location(request.path_info, @occi_request.categories)
569
- #
570
- # unless entities.nil?
571
- # entities.each do |entity|
572
- # location = entity.get_location
573
- # OCCI::Backend::Manager.signal_resource(@backend, OCCI::Backend::RESOURCE_DELETE, entity) if entity.kind_of? OCCI::Core::Resource
574
- # # TODO: delete links in backend!
575
- # entity.delete
576
- # OCCI::Rendering::HTTP::LocationRegistry.unregister(location)
577
- # end
578
- # break
579
- # end
580
- #
581
- # response.status = OCCI::Rendering::HTTP::Response::HTTP_NOT_FOUND
582
- # # This must be the last statement in this block, so that sinatra does not try to respond with random body content
583
- # # (or fail utterly while trying to do that!)
584
- # nil
585
-
586
- end
587
-
588
- error do
589
- OCCI::Log.error(sinatra.error)
590
- 'Sorry there was a nasty error - ' + env['sinatra.error'].name
591
- end
592
-
593
- end
594
- end