Merge lp:~dreamhosters/txaws/921352-get-bucket-notification-method into lp:txaws

Proposed by Arsene Rei
Status: Merged
Approved by: Duncan McGreggor
Approved revision: 137
Merged at revision: 129
Proposed branch: lp:~dreamhosters/txaws/921352-get-bucket-notification-method
Merge into: lp:txaws
Diff against target: 216 lines (+128/-6)
4 files modified
txaws/s3/client.py (+23/-1)
txaws/s3/model.py (+9/-0)
txaws/s3/tests/test_client.py (+85/-5)
txaws/testing/payload.py (+11/-0)
To merge this branch: bzr merge lp:~dreamhosters/txaws/921352-get-bucket-notification-method
Reviewer Review Type Date Requested Status
Duncan McGreggor Approve
Review via email: mp+90521@code.launchpad.net

Description of the change

Add GET Bucket notification functionality

To post a comment you must log in.
Revision history for this message
Duncan McGreggor (oubiwann) wrote :

[1] Ah, I see you caught the docstrings from the previous merge -- nice :-)

[2] 180 + return succeed(payload.
    181 + sample_s3_get_bucket_notification_with_topic_result)

Even with the long line, this doesn't following PEP 8. It should either be this:

      return succeed(payload.
                     sample_s3_get_bucket_notification_with_topic_result)
or this:

      return succeed(
          payload.
              sample_s3_get_bucket_notification_with_topic_result)

Visually, I'm happier with the first option ;-)

Tests pass, pep8/pyflakes look good.

Nice work! +1 for merge, once you decide how to handle #2 above.

review: Approve
138. By Arsene Rei

make pep8 related change

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'txaws/s3/client.py'
2--- txaws/s3/client.py 2012-01-27 07:04:32 +0000
3+++ txaws/s3/client.py 2012-01-27 20:45:29 +0000
4@@ -22,7 +22,8 @@
5 from txaws.s3.acls import AccessControlPolicy
6 from txaws.s3.model import (
7 Bucket, BucketItem, BucketListing, ItemOwner, LifecycleConfiguration,
8- LifecycleConfigurationRule, RequestPayment, WebsiteConfiguration)
9+ LifecycleConfigurationRule, NotificationConfiguration, RequestPayment,
10+ WebsiteConfiguration)
11 from txaws.s3.exception import S3Error
12 from txaws.service import AWSServiceEndpoint, S3_ENDPOINT
13 from txaws.util import XML, calculate_md5
14@@ -231,6 +232,27 @@
15
16 return WebsiteConfiguration(index_suffix, error_key)
17
18+ def get_bucket_notification_config(self, bucket):
19+ """
20+ Get the notification configuration of a bucket.
21+
22+ @param bucket: The name of the bucket.
23+ @return: A C{Deferred} that will request the bucket's notification
24+ configuration.
25+ """
26+ query = self.query_factory(
27+ action='GET', creds=self.creds, endpoint=self.endpoint,
28+ bucket=bucket, object_name='?notification')
29+ return query.submit().addCallback(self._parse_notification_config)
30+
31+ def _parse_notification_config(self, xml_bytes):
32+ """Parse a C{NotificationConfiguration} XML document."""
33+ root = XML(xml_bytes)
34+ topic = root.findtext("TopicConfiguration/Topic")
35+ event = root.findtext("TopicConfiguration/Event")
36+
37+ return NotificationConfiguration(topic, event)
38+
39 def get_bucket_acl(self, bucket):
40 """
41 Get the access control policy for a bucket.
42
43=== modified file 'txaws/s3/model.py'
44--- txaws/s3/model.py 2012-01-27 07:04:32 +0000
45+++ txaws/s3/model.py 2012-01-27 20:45:29 +0000
46@@ -81,6 +81,15 @@
47 self.error_key = error_key
48
49
50+class NotificationConfiguration(object):
51+ """
52+ A mapping for the data in a bucket notification configuration.
53+ """
54+ def __init__(self, topic=None, event=None):
55+ self.topic = topic
56+ self.event = event
57+
58+
59 class FileChunk(object):
60 """
61 An Amazon S3 file chunk.
62
63=== modified file 'txaws/s3/tests/test_client.py'
64--- txaws/s3/tests/test_client.py 2012-01-27 07:04:32 +0000
65+++ txaws/s3/tests/test_client.py 2012-01-27 20:45:29 +0000
66@@ -201,7 +201,8 @@
67 """
68 L{S3Client.get_bucket_location} creates a L{Query} to get a bucket's
69 location. It parses the returned C{LocationConstraint} XML document
70- and returns a C{Deferred} that fires with the bucket's region.
71+ and returns a C{Deferred} that requests the bucket's location
72+ constraint.
73 """
74
75 class StubQuery(client.Query):
76@@ -235,7 +236,8 @@
77 """
78 L{S3Client.get_bucket_lifecycle} creates a L{Query} to get a bucket's
79 lifecycle. It parses the returned C{LifecycleConfiguration} XML
80- document and returns a C{Deferred} that fires with the bucket's region.
81+ document and returns a C{Deferred} that requests the bucket's lifecycle
82+ configuration with multiple rules.
83 """
84
85 class StubQuery(client.Query):
86@@ -275,7 +277,8 @@
87 """
88 L{S3Client.get_bucket_lifecycle} creates a L{Query} to get a bucket's
89 lifecycle. It parses the returned C{LifecycleConfiguration} XML
90- document and returns a C{Deferred} that fires with the bucket's region.
91+ document and returns a C{Deferred} that requests the bucket's lifecycle
92+ configuration.
93 """
94
95 class StubQuery(client.Query):
96@@ -314,7 +317,7 @@
97 L{S3Client.get_bucket_website_config} creates a L{Query} to get a
98 bucket's website configurtion. It parses the returned
99 C{WebsiteConfiguration} XML document and returns a C{Deferred} that
100- fires with the bucket's region.
101+ requests the bucket's website configuration.
102 """
103
104 class StubQuery(client.Query):
105@@ -351,7 +354,7 @@
106 L{S3Client.get_bucket_website_config} creates a L{Query} to get a
107 bucket's website configurtion. It parses the returned
108 C{WebsiteConfiguration} XML document and returns a C{Deferred} that
109- fires with the bucket's region.
110+ requests the bucket's website configuration with the error document.
111 """
112
113 class StubQuery(client.Query):
114@@ -382,6 +385,83 @@
115 d = s3.get_bucket_website_config("mybucket")
116 return d.addCallback(check_results)
117
118+ def test_get_bucket_notification_config(self):
119+ """
120+ L{S3Client.get_bucket_notification_config} creates a L{Query} to get a
121+ bucket's notification configuration. It parses the returned
122+ C{NotificationConfiguration} XML document and returns a C{Deferred}
123+ that requests the bucket's notification configuration.
124+ """
125+
126+ class StubQuery(client.Query):
127+
128+ def __init__(query, action, creds, endpoint, bucket=None,
129+ object_name=None):
130+ super(StubQuery, query).__init__(action=action, creds=creds,
131+ bucket=bucket,
132+ object_name=object_name)
133+ self.assertEquals(action, "GET")
134+ self.assertEqual(creds.access_key, "foo")
135+ self.assertEqual(creds.secret_key, "bar")
136+ self.assertEqual(query.bucket, "mybucket")
137+ self.assertEqual(query.object_name, "?notification")
138+ self.assertEqual(query.data, "")
139+ self.assertEqual(query.metadata, {})
140+ self.assertEqual(query.amz_headers, {})
141+
142+ def submit(query, url_context=None):
143+ return succeed(payload.
144+ sample_s3_get_bucket_notification_result)
145+
146+ def check_results(notification_config):
147+ self.assertEquals(notification_config.topic, None)
148+ self.assertEquals(notification_config.event, None)
149+
150+ creds = AWSCredentials("foo", "bar")
151+ s3 = client.S3Client(creds, query_factory=StubQuery)
152+ d = s3.get_bucket_notification_config("mybucket")
153+ return d.addCallback(check_results)
154+
155+ def test_get_bucket_notification_config_with_topic(self):
156+ """
157+ L{S3Client.get_bucket_notification_config} creates a L{Query} to get a
158+ bucket's notification configuration. It parses the returned
159+ C{NotificationConfiguration} XML document and returns a C{Deferred}
160+ that requests the bucket's notification configuration with a topic.
161+ """
162+
163+ class StubQuery(client.Query):
164+
165+ def __init__(query, action, creds, endpoint, bucket=None,
166+ object_name=None):
167+ super(StubQuery, query).__init__(action=action, creds=creds,
168+ bucket=bucket,
169+ object_name=object_name)
170+ self.assertEquals(action, "GET")
171+ self.assertEqual(creds.access_key, "foo")
172+ self.assertEqual(creds.secret_key, "bar")
173+ self.assertEqual(query.bucket, "mybucket")
174+ self.assertEqual(query.object_name, "?notification")
175+ self.assertEqual(query.data, "")
176+ self.assertEqual(query.metadata, {})
177+ self.assertEqual(query.amz_headers, {})
178+
179+ def submit(query, url_context=None):
180+ return succeed(
181+ payload.
182+ sample_s3_get_bucket_notification_with_topic_result)
183+
184+ def check_results(notification_config):
185+ self.assertEquals(notification_config.topic,
186+ "arn:aws:sns:us-east-1:123456789012:myTopic")
187+ self.assertEquals(notification_config.event,
188+ "s3:ReducedRedundancyLostObject")
189+
190+ creds = AWSCredentials("foo", "bar")
191+ s3 = client.S3Client(creds, query_factory=StubQuery)
192+ d = s3.get_bucket_notification_config("mybucket")
193+ return d.addCallback(check_results)
194+
195 def test_delete_bucket(self):
196
197 class StubQuery(client.Query):
198
199=== modified file 'txaws/testing/payload.py'
200--- txaws/testing/payload.py 2012-01-27 00:50:35 +0000
201+++ txaws/testing/payload.py 2012-01-27 20:45:29 +0000
202@@ -1060,3 +1060,14 @@
203 <Suffix>index.html</Suffix>
204 </IndexDocument>
205 </WebsiteConfiguration>"""
206+
207+sample_s3_get_bucket_notification_result = """\
208+<NotificationConfiguration />"""
209+
210+sample_s3_get_bucket_notification_with_topic_result = """\
211+<NotificationConfiguration>
212+ <TopicConfiguration>
213+ <Topic>arn:aws:sns:us-east-1:123456789012:myTopic</Topic>
214+ <Event>s3:ReducedRedundancyLostObject</Event>
215+ </TopicConfiguration>
216+</NotificationConfiguration>"""

Subscribers

People subscribed via source and target branches