Consistent resource.prop for timestamps and booleans (object store)

This patch set updates all object store objects to use consistent
resource.prop for timestamps and booleans. In particular, the
following changes were made:
  - Clarify documentation for timestamp and boolean attributes
  - Use 'is_' prefix and boolean type for boolean attributes
  - Use '_at' suffix and timestamp type for timestamp attributes

This patch set also include missing documentation for the
Account resource.

Change-Id: Ibf204bb0ab444e7090c1102acdd3d0e1d9722829
Partial-Bug: #1544584
This commit is contained in:
Richard Theis 2016-03-25 12:52:51 -05:00
parent 2f2152fb0e
commit b4329508e9
8 changed files with 44 additions and 20 deletions

View File

@ -4,5 +4,6 @@ Object Store Resources
.. toctree::
:maxdepth: 1
v1/account
v1/container
v1/obj

View File

@ -0,0 +1,12 @@
openstack.object_store.v1.account
=================================
.. automodule:: openstack.object_store.v1.account
The Account Class
-----------------
The ``Account`` class inherits from :class:`~openstack.resource.Resource`.
.. autoclass:: openstack.object_store.v1.account.Account
:members:

View File

@ -111,8 +111,9 @@ class Proxy(proxy.BaseProxy):
metadata are keys defined by the Object Store
and values defined by the user. The system
metadata keys are:
- `content_type`
- `detect_content_type`
- `is_content_type_detected`
- `versions_location`
- `read_ACL`
- `write_ACL`
@ -282,12 +283,13 @@ class Proxy(proxy.BaseProxy):
metadata are keys defined by the Object Store
and values defined by the user. The system
metadata keys are:
- `content_type`
- `content_encoding`
- `content_disposition`
- `detect_content_type`
- `delete_after`
- `delete_at`
- `is_content_type_detected`
"""
container_name = self._get_container_name(obj, container)
res = self._get_resource(_obj.Object, obj,

View File

@ -40,4 +40,5 @@ class Account(_base.BaseResource):
#: this header is not returned by this operation.
meta_temp_url_key_2 = resource.header("x-account-meta-temp-url-key-2")
#: The timestamp of the transaction.
#: *Type: datetime object parsed from a UNIX epoch*
timestamp = resource.header("x-timestamp", type=format.UNIXEpoch)

View File

@ -20,7 +20,7 @@ class Container(_base.BaseResource):
_custom_metadata_prefix = "X-Container-Meta-"
_system_metadata = {
"content_type": "content-type",
"detect_content_type": "x-detect-content-type",
"is_content_type_detected": "x-detect-content-type",
"versions_location": "x-versions-location",
"read_ACL": "x-container-read",
"write_ACL": "x-container-write",
@ -53,6 +53,7 @@ class Container(_base.BaseResource):
#: The count of bytes used in total.
bytes_used = resource.header("x-container-bytes-used", type=int)
#: The timestamp of the transaction.
#: *Type: datetime object parsed from a UNIX epoch*
timestamp = resource.header("x-timestamp", type=format.UNIXEpoch)
# Request headers (when id=None)
@ -60,8 +61,8 @@ class Container(_base.BaseResource):
#: most recent one. If you omit this header, Object Storage responds
#: faster after it finds one valid replica. Because setting this
#: header to True is more expensive for the back end, use it only
#: when it is absolutely needed.
newest = resource.header("x-newest", type=bool)
#: when it is absolutely needed. *Type: bool*
is_newest = resource.header("x-newest", type=bool)
# Request headers (when id=name)
#: The ACL that grants read access. If not set, this header is not
@ -85,8 +86,9 @@ class Container(_base.BaseResource):
content_type = resource.header("content-type")
#: If set to true, Object Storage guesses the content type based
#: on the file extension and ignores the value sent in the
#: Content-Type header, if present.
detect_content_type = resource.header("x-detect-content-type", type=bool)
#: Content-Type header, if present. *Type: bool*
is_content_type_detected = resource.header("x-detect-content-type",
type=bool)
#: In combination with Expect: 100-Continue, specify an
#: "If-None-Match: \*" header to query whether the server already
#: has a copy of the object before any data is sent.

View File

@ -25,9 +25,9 @@ class Object(_base.BaseResource):
"content_disposition": "content-disposition",
"content_encoding": "content-encoding",
"content_type": "content-type",
"detect_content_type": "x-detect-content-type",
"delete_after": "x-delete-after",
"delete_at": "x-delete-at"
"delete_at": "x-delete-at",
"is_content_type_detected": "x-detect-content-type",
}
base_path = "/%(container)s"
@ -59,8 +59,8 @@ class Object(_base.BaseResource):
#: the most recent one. If you omit this header, Object Storage
#: responds faster after it finds one valid replica. Because
#: setting this header to True is more expensive for the back end,
#: use it only when it is absolutely needed.
newest = resource.header("x-newest", type=bool)
#: use it only when it is absolutely needed. *Type: bool*
is_newest = resource.header("x-newest", type=bool)
#: TODO(briancurtin) there's a lot of content here...
range = resource.header("range", type=dict)
#: See http://www.ietf.org/rfc/rfc2616.txt.
@ -82,7 +82,8 @@ class Object(_base.BaseResource):
#: Used with temporary URLs to specify the expiry time of the
#: signature. For more information about temporary URLs, see
#: OpenStack Object Storage API v1 Reference.
expires = resource.header("expires")
#: *Type: datetime object parsed from ISO 8601 formatted string*
expires_at = resource.header("expires", type=format.ISO8601)
#: If you include the multipart-manifest=get query parameter and
#: the object is a large object, the object contents are not
#: returned. Instead, the manifest is returned in the
@ -113,7 +114,9 @@ class Object(_base.BaseResource):
#: was corrupted, so retry the operation.
etag = resource.header("etag")
#: Set to True if this object is a static large object manifest object.
is_static_large_object = resource.header("x-static-large-object")
#: *Type: bool*
is_static_large_object = resource.header("x-static-large-object",
type=bool)
#: If set, the value of the Content-Encoding metadata.
#: If not set, this header is not returned by this operation.
content_encoding = resource.header("content-encoding")
@ -130,16 +133,18 @@ class Object(_base.BaseResource):
#: If set, the time when the object will be deleted by the system
#: in the format of a UNIX Epoch timestamp.
#: If not set, this header is not returned by this operation.
#: *Type: datetime object parsed from a UNIX epoch*
delete_at = resource.header("x-delete-at", type=format.UNIXEpoch)
#: If set, to this is a dynamic large object manifest object.
#: The value is the container and object name prefix of the
#: segment objects in the form container/prefix.
object_manifest = resource.header("x-object-manifest")
#: The timestamp of the transaction.
#: *Type: datetime object parsed from a UNIX epoch*
timestamp = resource.header("x-timestamp", type=format.UNIXEpoch)
#: The date and time that the object was created or the last
#: time that the metadata was changed.
last_modified = resource.header("last_modified", alias="last-modified")
last_modified_at = resource.header("last_modified", alias="last-modified")
# Headers for PUT and POST requests
#: Set to chunked to enable chunked transfer encoding. If used,
@ -147,8 +152,9 @@ class Object(_base.BaseResource):
transfer_encoding = resource.header("transfer-encoding")
#: If set to true, Object Storage guesses the content type based
#: on the file extension and ignores the value sent in the
#: Content-Type header, if present.
detect_content_type = resource.header("x-detect-content-type", type=bool)
#: Content-Type header, if present. *Type: bool*
is_content_type_detected = resource.header("x-detect-content-type",
type=bool)
#: If set, this is the name of an object used to create the new
#: object by copying the X-Copy-From object. The value is in form
#: {container}/{object}. You must UTF-8-encode and then URL-encode

View File

@ -138,7 +138,7 @@ class TestContainer(testtools.TestCase):
def _test_create_update(self, sot, sot_call, sess_method):
sot.read_ACL = "some ACL"
sot.write_ACL = "another ACL"
sot.detect_content_type = True
sot.is_content_type_detected = True
headers = {
"x-container-read": "some ACL",
"x-container-write": "another ACL",

View File

@ -96,7 +96,7 @@ class TestObject(testtools.TestCase):
headers = DICT_EXAMPLE['headers']
self.assertEqual(headers['content-length'], sot.content_length)
self.assertEqual(headers['accept-ranges'], sot.accept_ranges)
self.assertEqual(headers['last-modified'], sot.last_modified)
self.assertEqual(headers['last-modified'], sot.last_modified_at)
self.assertEqual(headers['etag'], sot.etag)
self.assertEqual(datetime(2016, 1, 21, 22, 10, 56, 281120,
tzinfo=iso8601.UTC),
@ -108,7 +108,7 @@ class TestObject(testtools.TestCase):
def test_get(self):
sot = obj.Object.new(container=CONTAINER_NAME, name=OBJECT_NAME)
sot.newest = True
sot.is_newest = True
sot.if_match = {"who": "what"}
rv = sot.get(self.sess)
@ -127,7 +127,7 @@ class TestObject(testtools.TestCase):
def _test_create(self, method, data, accept):
sot = obj.Object.new(container=CONTAINER_NAME, name=OBJECT_NAME,
data=data)
sot.newest = True
sot.is_newest = True
headers = {"x-newest": True, "Accept": ""}
rv = sot.create(self.sess)