diff --git a/gcloud/pubsub/message.py b/gcloud/pubsub/message.py index 832a5d554c44..8d1d2bcd0787 100644 --- a/gcloud/pubsub/message.py +++ b/gcloud/pubsub/message.py @@ -35,6 +35,8 @@ class Message(object): :param attributes: Extra metadata associated by the publisher with the message. """ + _service_timesstamp = None + def __init__(self, data, message_id, attributes=None): self.data = data self.message_id = message_id @@ -64,6 +66,15 @@ def timestamp(self): raise ValueError('No timestamp') return _rfc3339_to_datetime(stamp) + @property + def service_timestamp(self): + """Return server-set timestamp. + + :rtype: string + :returns: timestamp (in UTC timezone) in RFC 3339 format + """ + return self._service_timesstamp + @classmethod def from_api_repr(cls, api_repr): """Factory: construct message from API representation. @@ -72,5 +83,8 @@ def from_api_repr(cls, api_repr): :param api_repr: The API representation of the message """ data = base64.b64decode(api_repr.get('data', b'')) - return cls(data=data, message_id=api_repr['messageId'], - attributes=api_repr.get('attributes')) + instance = cls( + data=data, message_id=api_repr['messageId'], + attributes=api_repr.get('attributes')) + instance._service_timesstamp = api_repr.get('publishTimestamp') + return instance diff --git a/gcloud/pubsub/test_message.py b/gcloud/pubsub/test_message.py index 7bdc245ea2a9..3408ae41ab5c 100644 --- a/gcloud/pubsub/test_message.py +++ b/gcloud/pubsub/test_message.py @@ -31,6 +31,7 @@ def test_ctor_no_attributes(self): self.assertEqual(message.data, DATA) self.assertEqual(message.message_id, MESSAGE_ID) self.assertEqual(message.attributes, {}) + self.assertEqual(message.service_timestamp, None) def test_ctor_w_attributes(self): DATA = b'DEADBEEF' @@ -41,6 +42,7 @@ def test_ctor_w_attributes(self): self.assertEqual(message.data, DATA) self.assertEqual(message.message_id, MESSAGE_ID) self.assertEqual(message.attributes, ATTRS) + self.assertEqual(message.service_timestamp, None) def test_timestamp_no_attributes(self): DATA = b'DEADBEEF' @@ -85,17 +87,24 @@ def test_from_api_repr_missing_data(self): self.assertEqual(message.data, b'') self.assertEqual(message.message_id, MESSAGE_ID) self.assertEqual(message.attributes, {}) + self.assertEqual(message.service_timestamp, None) def test_from_api_repr_no_attributes(self): from base64 import b64encode as b64 DATA = b'DEADBEEF' B64_DATA = b64(DATA) MESSAGE_ID = '12345' - api_repr = {'data': B64_DATA, 'messageId': MESSAGE_ID} + TIMESTAMP = '2016-03-18-19:38:22.001393427Z' + api_repr = { + 'data': B64_DATA, + 'messageId': MESSAGE_ID, + 'publishTimestamp': TIMESTAMP, + } message = self._getTargetClass().from_api_repr(api_repr) self.assertEqual(message.data, DATA) self.assertEqual(message.message_id, MESSAGE_ID) self.assertEqual(message.attributes, {}) + self.assertEqual(message.service_timestamp, TIMESTAMP) def test_from_api_repr_w_attributes(self): from base64 import b64encode as b64 @@ -103,10 +112,15 @@ def test_from_api_repr_w_attributes(self): B64_DATA = b64(DATA) MESSAGE_ID = '12345' ATTRS = {'a': 'b'} - api_repr = {'data': B64_DATA, - 'messageId': MESSAGE_ID, - 'attributes': ATTRS} + TIMESTAMP = '2016-03-18-19:38:22.001393427Z' + api_repr = { + 'data': B64_DATA, + 'messageId': MESSAGE_ID, + 'publishTimestamp': TIMESTAMP, + 'attributes': ATTRS, + } message = self._getTargetClass().from_api_repr(api_repr) self.assertEqual(message.data, DATA) self.assertEqual(message.message_id, MESSAGE_ID) + self.assertEqual(message.service_timestamp, TIMESTAMP) self.assertEqual(message.attributes, ATTRS)