## Account (HEAD) ## Account (PBE) class AccountController(object): class AccountController(object): def __call__(self, env, start_response): def __call__(self, env, start_response): method = getattr(self, req.method) method = getattr(self, req.method) res = method(req) res = method(req) def HEAD(self, req): def HEAD(self, req): if self.mount_check and not check_mount(self.root, drive): if self.mount_check and not check_mount(self.root, drive): return HTTPInsufficientStorage(drive=drive, request=req) return HTTPInsufficientStorage(drive=drive, request=req) broker = self._get_account_broker(drive, part, account, ...) broker = self.get_account_backend(drive, part, account,...) if broker.is_deleted(): return self._deleted_response(broker, req, HTTPNotFound) try: info = broker.get_info() info = broker.get_info() except AccountDeleted as err: if err.marked: headers = {'X-Account-Status': 'Deleted'} else: headers = {} return HTTPNotFound(request=req, headers=headers, ...) [for key, (value, timestamp) in broker.metadata.iteritems()] [for key, (value, timestamp) in broker.metadata.iteritems()] def GET(self, req): def GET(self, req): if self.mount_check and not check_mount(self.root, drive): if self.mount_check and not check_mount(self.root, drive): return HTTPInsufficientStorage(drive=drive, request=req) return HTTPInsufficientStorage(drive=drive, request=req) broker = self._get_account_broker(drive, part, account, ...) broker = self.get_account_backend(drive, part, account, if broker.is_deleted(): return self._deleted_response(broker, req, HTTPNotFound) return account_listing_response(account,req,o_c_t, broker, ..) return account_listing_response(account, req, o_c_t, broker,..) def PUT(self, req): def PUT(self, req): if self.mount_check and not check_mount(self.root, drive): if self.mount_check and not check_mount(self.root, drive): return HTTPInsufficientStorage(drive=drive, request=req) return HTTPInsufficientStorage(drive=drive, request=req) broker = self.get_account_backend(drive, part, account, ...) if not broker: return HTTPInsufficientStorage(drive=drive, request=req) if container: # put account container if container: broker = self._get_account_broker(drive, part, account,..) if account.startswith(self.auto_create_account_prefix) \ a_c = account.startswith(self.auto_create_account_prefix) and not os.path.exists(broker.db_file): try: broker.initialize(timestamp) except DatabaseAlreadyExists: pass ovd = req.headers['x-account-override-deleted'] ovd = req.headers['x-account-override-deleted'] if ovd !~= 'yes' and broker.is_deleted(): try: return HTTPNotFound(request=req) ret = broker.put_container(container, .., a_c, ovd) broker.put_container(container, req.headers['x-xxxxx'],..) except EntityNotExist: if req.headers['x-delete-timestamp'] > \ resp = HTTPNotFound req.headers['x-put-timestamp']: else: return HTTPNoContent(request=req) if ret: else: resp = HTTPCreated return HTTPCreated(request=req) else: resp = HTTPNoContent return resp(request=req) else: # put account else: # put account broker = self._get_account_broker(drive, part, account) if not os.path.exists(broker.db_file): try: try: broker.initialize(timestamp) state = broker.create(timestamp, metadata) created = True except DatabaseAlreadyExists: created = False elif broker.is_status_deleted(): except EntityNotExist: return self._deleted_response(broker,req,HTTPForbidden) headers = {'X-Account-Status': 'Deleted'} resp = HTTPForbidden(request=req, headers=headers,...) else: created = broker.is_deleted() broker.update_put_timestamp(timestamp) if broker.is_deleted(): return HTTPConflict(request=req) except EntityConflict: if metadata: resp = HTTPConflict(request=req) broker.update_metadata(metadata..(req, timestamp)) else: if created: if state: return HTTPCreated(request=req) resp = HTTPCreated(request=req) else: else: return HTTPAccepted(request=req) resp = HTTPAccepted(request=req) return resp def POST(self, req): def POST(self, req): if self.mount_check and not check_mount(self.root, drive): return HTTPInsufficientStorage(drive=drive, request=req) broker = self._get_account_broker(drive, part, account) if broker.is_deleted(): return self._deleted_response(broker, req, HTTPNotFound) if metadata: broker.update_metadata(metadata..(req, timestamp)) def DELETE(self, req): def DELETE(self, req): if self.mount_check and not check_mount(self.root, drive): return HTTPInsufficientStorage(drive=drive, request=req) broker = self._get_account_broker(drive, part, account) if broker.is_deleted(): return self._deleted_response(broker, req, HTTPNotFound) broker.delete_db(req.headers['x-timestamp']) return self._deleted_response(broker, req, HTTPNoContent) @replication def REPLICATE(self, req): def _deleted_response(self, broker, req, resp, body=''): headers = {} try: if broker.is_status_deleted(): headers = {'X-Account-Status': 'Deleted'} except DatabaseConnectionError: pass return resp(request=req, headers=headers, ...) def _get_account_broker(self, drive, part, account, **kwargs): hsh = hash_path(account) db_dir = storage_directory(DATADIR, part, hsh) db_path = os.path.join(self.root, drive, db_dir, hsh + '.db') kwargs.setdefault('account', account) kwargs.setdefault('logger', self.logger) return AccountBroker(db_path, **kwargs) # account_listing_response is also used by in proxy's account controller to report just-autocreated accounts def account_listing_response(account, req, r_c_t, broker=None, if broker is None: broker = FakeAccountBroker() info = broker.get_info() [for key, (value, timestamp) in broker.metadata.iteritems()] account_list = broker.list_containers_iter(limit, marker, ...) for (name, object_count, bytes_used, is_subdir) in account_list ... class AccountBroker(DatabaseBroker): ## Full listing of methods and properties used by server: # is_deleted # get_info # metadata -- @property # db_file -- instance variable property # initialize -- inherited from DatabaseBroker # re-calls _initialize -> # create_container_table(conn) # create_account_stat_table(conn, put_timestamp) # throws DatabaseAlreadyExists, ValueError # put_container # is_status_deleted # update_put_timestamp -- inherited from DatabaseBroker # update_metadata -- inherited from DatabaseBroker # delete_db -- inherited from DatabaseBroker # re-calls _delete_db