def render_delete(self, request): name = unicode(parse_path(request.path)[-1]) existing_object = self.context[name] if existing_object: del self.context[name] else: raise NotFound
def render_put(self, request): existing_object = self.context if not hasattr(request, 'unresolved_path') else None requested_type = request.getHeader('content-type') content_length = request.getHeader('content-length') if requested_type is None: log.error('content-type not found in %s', request.getAllHeaders()) raise BadRequest('No Content-Type specified') data = {} noncdmi = False if requested_type not in self.object_constructor_map.keys(): noncdmi = True dstream = request.content data[u'content_length'] = content_length data[u'mimetype'] = requested_type data[u'value'] = None # set to a 'correct' one - the only supported via CDMI requested_type = 'application/cdmi-object' elif requested_type == 'application/cdmi-object': data = self._parse_and_validate_data(request) dstream = StringIO.StringIO(data.get('value', '')) data[u'value'] = None elif requested_type == 'application/cdmi-container': dstream = io.BytesIO() data = self._parse_and_validate_data(request) else: raise BadRequest('Cannot handle PUT for the request object type %s' % requested_type) if existing_object: data[u'name'] = unicode(parse_path(request.path)[-1]) form = CdmiObjectValidatorFactory.get_applier(existing_object, data) request.setHeader('content-type', self.object_type_map[existing_object.type]) action = 'apply' else: data[u'name'] = unicode(request.unresolved_path) requested_class = self.object_constructor_map[requested_type] form = CdmiObjectValidatorFactory.get_creator(requested_class, data) request.setHeader('content-type', requested_type) action = 'create' if form.errors: log.error('Validation failed: %s (%s):\n%s', form, request, form.errors) request.setResponseCode(BadRequest.status_code) return form.error_dict() result_object = getattr(form, action)() principal = self.get_principal(request) d = self.handle_success(None, request, result_object, principal, existing_object, dstream, data.get(u'valuetransferencoding', 'utf-8')) connection_lost = request.notifyFinish() connection_lost.addBoth(lambda r: d.cancel()) d.addCallback(self.finish_response, request, result_object, noncdmi, render_value=False) d.addErrback(self.handle_error, request, result_object, principal, existing_object) return NOT_DONE_YET
def render_delete(self, request): name = unicode(parse_path(request.path)[-1]) existing_object = self.context.__parent__[name] if existing_object: log.debug('Deleting %s', self.context) # are we deleting a container? if IStorageContainer.providedBy(self.context): # check children children = [child for child in self.context.listcontent() if IDataObject.providedBy(child) or IStorageContainer.providedBy(child)] if len(children) > 0: raise BadRequest('Attempt to delete a non-empty container') else: # XXX: Alternative authentication methods! credentials = request.getHeader('X-Auth-Token') storemgr = getAdapter(self.context, IDataStoreFactory).create() storemgr.delete(credentials) del self.context.__parent__[name] handle(self.context, ModelDeletedEvent(self.context.__parent__)) else: raise NotFound
def render_put(self, request): data = self._parse_and_validate_data(request) existing_object = self.context if not hasattr(request, 'unresolved_path') else None requested_type = request.getHeader('content-type') if requested_type is None: log.error('content-type not found in %s', request.getAllHeaders()) raise BadRequest('No Content-Type specified') if requested_type not in self.object_constructor_map.keys(): raise BadRequest('Don\'t know how to create objects of type: %s' % requested_type) if existing_object: data[u'name'] = unicode(parse_path(request.path)[-1]) form = CdmiObjectValidatorFactory.get_applier(existing_object, data) request.setHeader('content-type', self.object_type_map[existing_object.type]) action = 'apply' else: requested_class = self.object_constructor_map[requested_type] data[u'name'] = unicode(request.unresolved_path[-1]) request.setHeader('content-type', requested_type) form = CdmiObjectValidatorFactory.get_creator(requested_class, data) action = 'create' if form.errors: log.error('Validation failed: %s (%s):\n%s', form, request, form.errors) request.setResponseCode(BadRequest.status_code) return form.error_dict() result_object = getattr(form, action)() @db.transact def handle_success(r, request, obj, principal): if not existing_object: obj.__owner__ = principal self.context.add(obj) self.add_log_event(principal, '%s of %s (%s) via CDMI was successful' % ('Creation' if not existing_object else 'Update', obj.name, obj.__name__)) def finish_response(r, request, obj): if request.finished: # Should not be triggered at all log.error('Connection lost: cannot render resulting object. ' 'Modifications were saved. %s', request) return request.write(self.render_object(obj)) request.finish() def handle_error(f, request, obj, principal): f.trap(Exception) if request.finished: # Should not be triggered at all try: f.raiseException() except Exception: log.error('Connection lost: cannot return error message to the client. %s', request, exc_info=True) return self.add_log_event(principal, '%s of %s (%s) via CDMI failed: %s: %s' % ('Creation' if not existing_object else 'Update', obj.name, obj.__name__, type(f.value).__name__, f.value)) request.setResponseCode(500) request.write(json.dumps({'errorMessage': str(f.value)})) request.finish() principal = self.get_principal(request) d = handle_success(None, request, result_object, principal) connection_lost = request.notifyFinish() connection_lost.addCallback(lambda r: d.cancel()) d.addCallback(finish_response, request, result_object) d.addErrback(handle_error, request, result_object, principal) return NOT_DONE_YET