123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- // Copyright 2017 Google Inc. All Rights Reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package storage
- import (
- "errors"
- "fmt"
- "regexp"
- "cloud.google.com/go/internal/trace"
- "golang.org/x/net/context"
- raw "google.golang.org/api/storage/v1"
- )
- // A Notification describes how to send Cloud PubSub messages when certain
- // events occur in a bucket.
- type Notification struct {
- //The ID of the notification.
- ID string
- // The ID of the topic to which this subscription publishes.
- TopicID string
- // The ID of the project to which the topic belongs.
- TopicProjectID string
- // Only send notifications about listed event types. If empty, send notifications
- // for all event types.
- // See https://cloud.google.com/storage/docs/pubsub-notifications#events.
- EventTypes []string
- // If present, only apply this notification configuration to object names that
- // begin with this prefix.
- ObjectNamePrefix string
- // An optional list of additional attributes to attach to each Cloud PubSub
- // message published for this notification subscription.
- CustomAttributes map[string]string
- // The contents of the message payload.
- // See https://cloud.google.com/storage/docs/pubsub-notifications#payload.
- PayloadFormat string
- }
- // Values for Notification.PayloadFormat.
- const (
- // Send no payload with notification messages.
- NoPayload = "NONE"
- // Send object metadata as JSON with notification messages.
- JSONPayload = "JSON_API_V1"
- )
- // Values for Notification.EventTypes.
- const (
- // Event that occurs when an object is successfully created.
- ObjectFinalizeEvent = "OBJECT_FINALIZE"
- // Event that occurs when the metadata of an existing object changes.
- ObjectMetadataUpdateEvent = "OBJECT_METADATA_UPDATE"
- // Event that occurs when an object is permanently deleted.
- ObjectDeleteEvent = "OBJECT_DELETE"
- // Event that occurs when the live version of an object becomes an
- // archived version.
- ObjectArchiveEvent = "OBJECT_ARCHIVE"
- )
- func toNotification(rn *raw.Notification) *Notification {
- n := &Notification{
- ID: rn.Id,
- EventTypes: rn.EventTypes,
- ObjectNamePrefix: rn.ObjectNamePrefix,
- CustomAttributes: rn.CustomAttributes,
- PayloadFormat: rn.PayloadFormat,
- }
- n.TopicProjectID, n.TopicID = parseNotificationTopic(rn.Topic)
- return n
- }
- var topicRE = regexp.MustCompile("^//pubsub.googleapis.com/projects/([^/]+)/topics/([^/]+)")
- // parseNotificationTopic extracts the project and topic IDs from from the full
- // resource name returned by the service. If the name is malformed, it returns
- // "?" for both IDs.
- func parseNotificationTopic(nt string) (projectID, topicID string) {
- matches := topicRE.FindStringSubmatch(nt)
- if matches == nil {
- return "?", "?"
- }
- return matches[1], matches[2]
- }
- func toRawNotification(n *Notification) *raw.Notification {
- return &raw.Notification{
- Id: n.ID,
- Topic: fmt.Sprintf("//pubsub.googleapis.com/projects/%s/topics/%s",
- n.TopicProjectID, n.TopicID),
- EventTypes: n.EventTypes,
- ObjectNamePrefix: n.ObjectNamePrefix,
- CustomAttributes: n.CustomAttributes,
- PayloadFormat: string(n.PayloadFormat),
- }
- }
- // AddNotification adds a notification to b. You must set n's TopicProjectID, TopicID
- // and PayloadFormat, and must not set its ID. The other fields are all optional. The
- // returned Notification's ID can be used to refer to it.
- func (b *BucketHandle) AddNotification(ctx context.Context, n *Notification) (ret *Notification, err error) {
- ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.AddNotification")
- 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")
- }
- call := b.c.raw.Notifications.Insert(b.name, toRawNotification(n))
- setClientHeader(call.Header())
- if b.userProject != "" {
- call.UserProject(b.userProject)
- }
- rn, err := call.Context(ctx).Do()
- if err != nil {
- return nil, err
- }
- return toNotification(rn), nil
- }
- // Notifications returns all the Notifications configured for this bucket, as a map
- // indexed by notification ID.
- func (b *BucketHandle) Notifications(ctx context.Context) (n map[string]*Notification, err error) {
- ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.Notifications")
- defer func() { trace.EndSpan(ctx, err) }()
- call := b.c.raw.Notifications.List(b.name)
- setClientHeader(call.Header())
- if b.userProject != "" {
- call.UserProject(b.userProject)
- }
- var res *raw.Notifications
- err = runWithRetry(ctx, func() error {
- res, err = call.Context(ctx).Do()
- return err
- })
- if err != nil {
- return nil, err
- }
- return notificationsToMap(res.Items), nil
- }
- func notificationsToMap(rns []*raw.Notification) map[string]*Notification {
- m := map[string]*Notification{}
- for _, rn := range rns {
- m[rn.Id] = toNotification(rn)
- }
- return m
- }
- // DeleteNotification deletes the notification with the given ID.
- func (b *BucketHandle) DeleteNotification(ctx context.Context, id string) (err error) {
- ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.DeleteNotification")
- defer func() { trace.EndSpan(ctx, err) }()
- call := b.c.raw.Notifications.Delete(b.name, id)
- setClientHeader(call.Header())
- if b.userProject != "" {
- call.UserProject(b.userProject)
- }
- return call.Context(ctx).Do()
- }
|