...

Source file src/cloud.google.com/go/storage/notifications.go

Documentation: cloud.google.com/go/storage

     1  // Copyright 2017 Google LLC
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package storage
    16  
    17  import (
    18  	"context"
    19  	"errors"
    20  	"fmt"
    21  	"regexp"
    22  
    23  	"cloud.google.com/go/internal/trace"
    24  	"cloud.google.com/go/storage/internal/apiv2/storagepb"
    25  	raw "google.golang.org/api/storage/v1"
    26  )
    27  
    28  // A Notification describes how to send Cloud PubSub messages when certain
    29  // events occur in a bucket.
    30  type Notification struct {
    31  	//The ID of the notification.
    32  	ID string
    33  
    34  	// The ID of the topic to which this subscription publishes.
    35  	TopicID string
    36  
    37  	// The ID of the project to which the topic belongs.
    38  	TopicProjectID string
    39  
    40  	// Only send notifications about listed event types. If empty, send notifications
    41  	// for all event types.
    42  	// See https://cloud.google.com/storage/docs/pubsub-notifications#events.
    43  	EventTypes []string
    44  
    45  	// If present, only apply this notification configuration to object names that
    46  	// begin with this prefix.
    47  	ObjectNamePrefix string
    48  
    49  	// An optional list of additional attributes to attach to each Cloud PubSub
    50  	// message published for this notification subscription.
    51  	CustomAttributes map[string]string
    52  
    53  	// The contents of the message payload.
    54  	// See https://cloud.google.com/storage/docs/pubsub-notifications#payload.
    55  	PayloadFormat string
    56  }
    57  
    58  // Values for Notification.PayloadFormat.
    59  const (
    60  	// Send no payload with notification messages.
    61  	NoPayload = "NONE"
    62  
    63  	// Send object metadata as JSON with notification messages.
    64  	JSONPayload = "JSON_API_V1"
    65  )
    66  
    67  // Values for Notification.EventTypes.
    68  const (
    69  	// Event that occurs when an object is successfully created.
    70  	ObjectFinalizeEvent = "OBJECT_FINALIZE"
    71  
    72  	// Event that occurs when the metadata of an existing object changes.
    73  	ObjectMetadataUpdateEvent = "OBJECT_METADATA_UPDATE"
    74  
    75  	// Event that occurs when an object is permanently deleted.
    76  	ObjectDeleteEvent = "OBJECT_DELETE"
    77  
    78  	// Event that occurs when the live version of an object becomes an
    79  	// archived version.
    80  	ObjectArchiveEvent = "OBJECT_ARCHIVE"
    81  )
    82  
    83  func toNotification(rn *raw.Notification) *Notification {
    84  	n := &Notification{
    85  		ID:               rn.Id,
    86  		EventTypes:       rn.EventTypes,
    87  		ObjectNamePrefix: rn.ObjectNamePrefix,
    88  		CustomAttributes: rn.CustomAttributes,
    89  		PayloadFormat:    rn.PayloadFormat,
    90  	}
    91  	n.TopicProjectID, n.TopicID = parseNotificationTopic(rn.Topic)
    92  	return n
    93  }
    94  
    95  func toNotificationFromProto(pbn *storagepb.NotificationConfig) *Notification {
    96  	n := &Notification{
    97  		ID:               pbn.GetName(),
    98  		EventTypes:       pbn.GetEventTypes(),
    99  		ObjectNamePrefix: pbn.GetObjectNamePrefix(),
   100  		CustomAttributes: pbn.GetCustomAttributes(),
   101  		PayloadFormat:    pbn.GetPayloadFormat(),
   102  	}
   103  	n.TopicProjectID, n.TopicID = parseNotificationTopic(pbn.Topic)
   104  	return n
   105  }
   106  
   107  func toProtoNotification(n *Notification) *storagepb.NotificationConfig {
   108  	return &storagepb.NotificationConfig{
   109  		Name: n.ID,
   110  		Topic: fmt.Sprintf("//pubsub.googleapis.com/projects/%s/topics/%s",
   111  			n.TopicProjectID, n.TopicID),
   112  		EventTypes:       n.EventTypes,
   113  		ObjectNamePrefix: n.ObjectNamePrefix,
   114  		CustomAttributes: n.CustomAttributes,
   115  		PayloadFormat:    n.PayloadFormat,
   116  	}
   117  }
   118  
   119  var topicRE = regexp.MustCompile(`^//pubsub\.googleapis\.com/projects/([^/]+)/topics/([^/]+)`)
   120  
   121  // parseNotificationTopic extracts the project and topic IDs from from the full
   122  // resource name returned by the service. If the name is malformed, it returns
   123  // "?" for both IDs.
   124  func parseNotificationTopic(nt string) (projectID, topicID string) {
   125  	matches := topicRE.FindStringSubmatch(nt)
   126  	if matches == nil {
   127  		return "?", "?"
   128  	}
   129  	return matches[1], matches[2]
   130  }
   131  
   132  func toRawNotification(n *Notification) *raw.Notification {
   133  	return &raw.Notification{
   134  		Id: n.ID,
   135  		Topic: fmt.Sprintf("//pubsub.googleapis.com/projects/%s/topics/%s",
   136  			n.TopicProjectID, n.TopicID),
   137  		EventTypes:       n.EventTypes,
   138  		ObjectNamePrefix: n.ObjectNamePrefix,
   139  		CustomAttributes: n.CustomAttributes,
   140  		PayloadFormat:    string(n.PayloadFormat),
   141  	}
   142  }
   143  
   144  // AddNotification adds a notification to b. You must set n's TopicProjectID, TopicID
   145  // and PayloadFormat, and must not set its ID. The other fields are all optional. The
   146  // returned Notification's ID can be used to refer to it.
   147  func (b *BucketHandle) AddNotification(ctx context.Context, n *Notification) (ret *Notification, err error) {
   148  	ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.AddNotification")
   149  	defer func() { trace.EndSpan(ctx, err) }()
   150  
   151  	if n.ID != "" {
   152  		return nil, errors.New("storage: AddNotification: ID must not be set")
   153  	}
   154  	if n.TopicProjectID == "" {
   155  		return nil, errors.New("storage: AddNotification: missing TopicProjectID")
   156  	}
   157  	if n.TopicID == "" {
   158  		return nil, errors.New("storage: AddNotification: missing TopicID")
   159  	}
   160  
   161  	opts := makeStorageOpts(false, b.retry, b.userProject)
   162  	ret, err = b.c.tc.CreateNotification(ctx, b.name, n, opts...)
   163  	return ret, err
   164  }
   165  
   166  // Notifications returns all the Notifications configured for this bucket, as a map
   167  // indexed by notification ID.
   168  func (b *BucketHandle) Notifications(ctx context.Context) (n map[string]*Notification, err error) {
   169  	ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.Notifications")
   170  	defer func() { trace.EndSpan(ctx, err) }()
   171  
   172  	opts := makeStorageOpts(true, b.retry, b.userProject)
   173  	n, err = b.c.tc.ListNotifications(ctx, b.name, opts...)
   174  	return n, err
   175  }
   176  
   177  func notificationsToMap(rns []*raw.Notification) map[string]*Notification {
   178  	m := map[string]*Notification{}
   179  	for _, rn := range rns {
   180  		m[rn.Id] = toNotification(rn)
   181  	}
   182  	return m
   183  }
   184  
   185  func notificationsToMapFromProto(ns []*storagepb.NotificationConfig) map[string]*Notification {
   186  	m := map[string]*Notification{}
   187  	for _, n := range ns {
   188  		m[n.Name] = toNotificationFromProto(n)
   189  	}
   190  	return m
   191  }
   192  
   193  // DeleteNotification deletes the notification with the given ID.
   194  func (b *BucketHandle) DeleteNotification(ctx context.Context, id string) (err error) {
   195  	ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.Bucket.DeleteNotification")
   196  	defer func() { trace.EndSpan(ctx, err) }()
   197  
   198  	opts := makeStorageOpts(true, b.retry, b.userProject)
   199  	return b.c.tc.DeleteNotification(ctx, b.name, id, opts...)
   200  }
   201  

View as plain text