Skip to content

Commit 3286ae4

Browse files
authored
Add 'user_project' support to BucketNotification API methods. (#4176)
Closes #4150.
1 parent 2b88f0b commit 3286ae4

File tree

3 files changed

+74
-9
lines changed

3 files changed

+74
-9
lines changed

storage/google/cloud/storage/notification.py

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -233,13 +233,18 @@ def create(self, client=None):
233233

234234
client = self._require_client(client)
235235

236+
query_params = {}
237+
if self.bucket.user_project is not None:
238+
query_params['userProject'] = self.bucket.user_project
239+
236240
path = '/b/{}/notificationConfigs'.format(self.bucket.name)
237241
properties = self._properties.copy()
238242
properties['topic'] = _TOPIC_REF_FMT.format(
239243
self.topic_project, self.topic_name)
240244
self._properties = client._connection.api_request(
241245
method='POST',
242246
path=path,
247+
query_params=query_params,
243248
data=properties,
244249
)
245250

@@ -262,8 +267,17 @@ def exists(self, client=None):
262267
raise ValueError("Notification not intialized by server")
263268

264269
client = self._require_client(client)
270+
271+
query_params = {}
272+
if self.bucket.user_project is not None:
273+
query_params['userProject'] = self.bucket.user_project
274+
265275
try:
266-
client._connection.api_request(method='GET', path=self.path)
276+
client._connection.api_request(
277+
method='GET',
278+
path=self.path,
279+
query_params=query_params,
280+
)
267281
except NotFound:
268282
return False
269283
else:
@@ -288,7 +302,16 @@ def reload(self, client=None):
288302
raise ValueError("Notification not intialized by server")
289303

290304
client = self._require_client(client)
291-
response = client._connection.api_request(method='GET', path=self.path)
305+
306+
query_params = {}
307+
if self.bucket.user_project is not None:
308+
query_params['userProject'] = self.bucket.user_project
309+
310+
response = client._connection.api_request(
311+
method='GET',
312+
path=self.path,
313+
query_params=query_params,
314+
)
292315
self._set_properties(response)
293316

294317
def delete(self, client=None):
@@ -310,4 +333,13 @@ def delete(self, client=None):
310333
raise ValueError("Notification not intialized by server")
311334

312335
client = self._require_client(client)
313-
client._connection.api_request(method='DELETE', path=self.path)
336+
337+
query_params = {}
338+
if self.bucket.user_project is not None:
339+
query_params['userProject'] = self.bucket.user_project
340+
341+
client._connection.api_request(
342+
method='DELETE',
343+
path=self.path,
344+
query_params=query_params,
345+
)

storage/tests/system.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,3 +932,23 @@ def test_notification_explicit(self):
932932
notification.payload_format, self.payload_format())
933933
finally:
934934
notification.delete()
935+
936+
@unittest.skipUnless(USER_PROJECT, 'USER_PROJECT not set in environment.')
937+
def test_notification_w_user_project(self):
938+
new_bucket_name = 'notification-minimal' + unique_resource_id('-')
939+
bucket = retry_429(Config.CLIENT.create_bucket)(
940+
new_bucket_name, requester_pays=True)
941+
self.case_buckets_to_delete.append(new_bucket_name)
942+
with_user_project = Config.CLIENT.bucket(
943+
new_bucket_name, user_project=USER_PROJECT)
944+
self.assertEqual(list(with_user_project.list_notifications()), [])
945+
notification = with_user_project.notification(self.TOPIC_NAME)
946+
retry_429(notification.create)()
947+
try:
948+
self.assertTrue(notification.exists())
949+
self.assertIsNotNone(notification.notification_id)
950+
notifications = list(with_user_project.list_notifications())
951+
self.assertEqual(len(notifications), 1)
952+
self.assertEqual(notifications[0].topic_name, self.TOPIC_NAME)
953+
finally:
954+
notification.delete()

storage/tests/unit/test_notification.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,11 @@ def _make_client(self, project=BUCKET_PROJECT):
6767

6868
return mock.Mock(project=project, spec=Client)
6969

70-
def _make_bucket(self, client, name=BUCKET_NAME):
71-
bucket = mock.Mock(spec=['client', 'name'])
70+
def _make_bucket(self, client, name=BUCKET_NAME, user_project=None):
71+
bucket = mock.Mock(spec=['client', 'name', 'user_project'])
7272
bucket.client= client
7373
bucket.name = name
74+
bucket.user_project = user_project
7475
return bucket
7576

7677
def test_ctor_defaults(self):
@@ -268,13 +269,15 @@ def test_create_w_defaults(self):
268269
api_request.assert_called_once_with(
269270
method='POST',
270271
path=self.CREATE_PATH,
272+
query_params={},
271273
data=data,
272274
)
273275

274276
def test_create_w_explicit_client(self):
277+
USER_PROJECT = 'user-project-123'
275278
client = self._make_client()
276279
alt_client = self._make_client()
277-
bucket = self._make_bucket(client)
280+
bucket = self._make_bucket(client, user_project=USER_PROJECT)
278281
notification = self._make_one(
279282
bucket, self.TOPIC_NAME,
280283
topic_project=self.TOPIC_ALT_PROJECT,
@@ -317,6 +320,7 @@ def test_create_w_explicit_client(self):
317320
api_request.assert_called_once_with(
318321
method='POST',
319322
path=self.CREATE_PATH,
323+
query_params={'userProject': USER_PROJECT},
320324
data=data,
321325
)
322326

@@ -344,11 +348,13 @@ def test_exists_miss(self):
344348
api_request.assert_called_once_with(
345349
method='GET',
346350
path=self.NOTIFICATION_PATH,
351+
query_params={},
347352
)
348353

349354
def test_exists_hit(self):
355+
USER_PROJECT = 'user-project-123'
350356
client = self._make_client()
351-
bucket = self._make_bucket(client)
357+
bucket = self._make_bucket(client, user_project=USER_PROJECT)
352358
alt_client = self._make_client()
353359
notification = self._make_one(bucket, self.TOPIC_NAME)
354360
notification._properties['id'] = self.NOTIFICATION_ID
@@ -365,6 +371,7 @@ def test_exists_hit(self):
365371
api_request.assert_called_once_with(
366372
method='GET',
367373
path=self.NOTIFICATION_PATH,
374+
query_params={'userProject': USER_PROJECT},
368375
)
369376

370377
def test_reload_wo_notification_id(self):
@@ -392,13 +399,15 @@ def test_reload_miss(self):
392399
api_request.assert_called_once_with(
393400
method='GET',
394401
path=self.NOTIFICATION_PATH,
402+
query_params={},
395403
)
396404

397405
def test_reload_hit(self):
398406
from google.cloud.storage.notification import NONE_PAYLOAD_FORMAT
399407

408+
USER_PROJECT = 'user-project-123'
400409
client = self._make_client()
401-
bucket = self._make_bucket(client)
410+
bucket = self._make_bucket(client, user_project=USER_PROJECT)
402411
alt_client = self._make_client()
403412
notification = self._make_one(bucket, self.TOPIC_NAME)
404413
notification._properties['id'] = self.NOTIFICATION_ID
@@ -423,6 +432,7 @@ def test_reload_hit(self):
423432
api_request.assert_called_once_with(
424433
method='GET',
425434
path=self.NOTIFICATION_PATH,
435+
query_params={'userProject': USER_PROJECT},
426436
)
427437

428438
def test_delete_wo_notification_id(self):
@@ -450,11 +460,13 @@ def test_delete_miss(self):
450460
api_request.assert_called_once_with(
451461
method='DELETE',
452462
path=self.NOTIFICATION_PATH,
463+
query_params={},
453464
)
454465

455466
def test_delete_hit(self):
467+
USER_PROJECT = 'user-project-123'
456468
client = self._make_client()
457-
bucket = self._make_bucket(client)
469+
bucket = self._make_bucket(client, user_project=USER_PROJECT)
458470
alt_client = self._make_client()
459471
notification = self._make_one(bucket, self.TOPIC_NAME)
460472
notification._properties['id'] = self.NOTIFICATION_ID
@@ -466,4 +478,5 @@ def test_delete_hit(self):
466478
api_request.assert_called_once_with(
467479
method='DELETE',
468480
path=self.NOTIFICATION_PATH,
481+
query_params={'userProject': USER_PROJECT},
469482
)

0 commit comments

Comments
 (0)