类似于Account Server,Paste Deploy最终将使用swift.container.server模块的app_factory()函数加载Container Server的WSGI Application,即swift.account.server.ContainerController。
以Container Get操作为例:
Container Get的API参见官网:
https://developer.openstack.org/api-ref/object-store/
Container Get操作代码分析
# swift/container/server.py
class ContainerController(object):
def GET(self, req):
"""Handle HTTP GET request."""
#从请求参数req中获取drive, part, account, container, object信息
drive, part, account, container, obj = split_and_validate_path(
req, 4, 5, True)
#prefix、delimiter、marker、end_marker可以做为查询object的条件
#比如可以利用prefix参数查询前缀为某个字符串的object
path = get_param(req, 'path')
prefix = get_param(req, 'prefix')
delimiter = get_param(req, 'delimiter')
if delimiter and (len(delimiter) > 1 or ord(delimiter) > 254):
# delimiters can be made more flexible later
return HTTPPreconditionFailed(body='Bad delimiter')
marker = get_param(req, 'marker', '')
end_marker = get_param(req, 'end_marker')
limit = constraints.CONTAINER_LISTING_LIMIT
given_limit = get_param(req, 'limit')
if given_limit and given_limit.isdigit():
limit = int(given_limit)
if limit > constraints.CONTAINER_LISTING_LIMIT:
return HTTPPreconditionFailed(
request=req,
body='Maximum limit is %d'
% constraints.CONTAINER_LISTING_LIMIT)
out_content_type = get_listing_content_type(req)
if self.mount_check and not check_mount(self.root, drive):
return HTTPInsufficientStorage(drive=drive, request=req)
#获取一个ControllerBroker类的实例,与Account Server类似,
#Container的相关信息也是作为一个sqlite数据库文件存放在相应partition的
#目录下。ControllerBroker类封装了对数据库文件进行访问的方法。
broker = self._get_container_broker(drive, part, account, container,
pending_timeout=0.1,
stale_reads_ok=True)
info, is_deleted = broker.get_info_is_deleted()
resp_headers = gen_resp_headers(info, is_deleted=is_deleted)
#判断是否被删除
if is_deleted:
return HTTPNotFound(request=req, headers=resp_headers)
#调用ContainerBroker类的list_objects_iter()函数读取container数据库文件,返回object信息的列表
container_list = broker.list_objects_iter(
limit, marker, end_marker, prefix, delimiter, path,
storage_policy_index=info['storage_policy_index'])
return self.create_listing(req, out_content_type, info, resp_headers,
broker.metadata, container_list, container)