-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore(storage): implement Notification methods #6138
Changes from 7 commits
b9f8ea2
09eb7a6
ee59533
90815c3
d085bd1
40f6fe4
139c853
c9797d8
b2a03d0
4acd6ab
66f3ecf
f898d0a
a615ecd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -935,6 +935,83 @@ func (c *httpStorageClient) DeleteHMACKey(ctx context.Context, desc *hmacKeyDesc | |
return errMethodNotSupported | ||
} | ||
|
||
// Notification methods. | ||
|
||
// ListNotifications returns all the Notifications configured for this bucket, as a map indexed by notification ID. | ||
// | ||
// Note: Pagination is not currently supported. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would amend this to say something like: Note: This API does not support pagination. However, entity limits cap the number of notifications on a single bucket, so all results will be returned in the first response. See https://cloud.google.com/storage/quotas#buckets There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. updated, thanks! |
||
func (c *httpStorageClient) ListNotifications(ctx context.Context, bucket string, opts ...storageOption) (n map[string]*Notification, err error) { | ||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.httpStorageClient.ListNotifications") | ||
defer func() { trace.EndSpan(ctx, err) }() | ||
|
||
s := callSettings(c.settings, opts...) | ||
call := c.raw.Notifications.List(bucket) | ||
if s.userProject != "" { | ||
call.UserProject(s.userProject) | ||
} | ||
var res *raw.Notifications | ||
err = run(ctx, func() error { | ||
res, err = call.Context(ctx).Do() | ||
return err | ||
}, s.retry, true, setRetryHeaderHTTP(call)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return notificationsToMap(res.Items), nil | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interestingly it seems like this implementation doesn't use page tokens-- so if there are more than 1000 notifications you won't get all of them. (I think this would be very uncommon though) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might be worth adding a Note or TODO for later mentioning this. I too was surprised to see an un-paginated list api, even if it predates the design standards. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah so I did a bit of digging and found the following:
I'm not sure how this would effect gRPC, if at all. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should keep page size unspecified. The server will "do the right thing" and if for some reason that quota is raised to 500, we won't have to change our code or be worried about what might happen - it will "just work". Can we add a comment that the server will use a default page_size (just sent an email to inquire what the default actually is), and that our code will not set a page_size? We could leave the param just in case we want to set it later. WDYT? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds fine to me! Agreed that we don't want to depend of behavior that may change going forward. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Gotcha... IIUC, based on the same block of code, So I've added a comment but no change in our code. PTAL and let me know if my understanding is correct. |
||
} | ||
|
||
func (c *httpStorageClient) CreateNotification(ctx context.Context, bucket string, n *Notification, opts ...storageOption) (ret *Notification, err error) { | ||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.httpStorageClient.CreateNotification") | ||
defer func() { trace.EndSpan(ctx, err) }() | ||
|
||
if n.ID != "" { | ||
return nil, errors.New("storage: AddNotification: ID must not be set") | ||
} | ||
if n.TopicProjectID == "" { | ||
return nil, errors.New("storage: AddNotification: missing TopicProjectID") | ||
} | ||
if n.TopicID == "" { | ||
return nil, errors.New("storage: AddNotification: missing TopicID") | ||
} | ||
cojenco marked this conversation as resolved.
Show resolved
Hide resolved
|
||
s := callSettings(c.settings, opts...) | ||
call := c.raw.Notifications.Insert(bucket, toRawNotification(n)) | ||
if s.userProject != "" { | ||
call.UserProject(s.userProject) | ||
} | ||
|
||
var rn *raw.Notification | ||
err = run(ctx, func() error { | ||
rn, err = call.Context(ctx).Do() | ||
return err | ||
}, s.retry, s.idempotent, setRetryHeaderHTTP(call)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return toNotification(rn), nil | ||
} | ||
|
||
func (c *httpStorageClient) DeleteNotification(ctx context.Context, bucket string, id string, opts ...storageOption) (err error) { | ||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.httpStorageClient.DeleteNotification") | ||
defer func() { trace.EndSpan(ctx, err) }() | ||
|
||
s := callSettings(c.settings, opts...) | ||
call := c.raw.Notifications.Delete(bucket, id) | ||
if s.userProject != "" { | ||
call.UserProject(s.userProject) | ||
} | ||
return run(ctx, func() error { | ||
return call.Context(ctx).Do() | ||
}, s.retry, s.idempotent, setRetryHeaderHTTP(call)) | ||
} | ||
|
||
func (c *httpStorageClient) GetNotification(ctx context.Context, bucket string, id string, opts ...storageOption) (*Notification, error) { | ||
cojenco marked this conversation as resolved.
Show resolved
Hide resolved
|
||
notifications, err := c.ListNotifications(ctx, bucket, opts...) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return notifications[id], nil | ||
} | ||
|
||
type httpReader struct { | ||
body io.ReadCloser | ||
seen int64 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove client-side validation here as well (to be left above the interface).