1
2
3
4
5
6
7
8
9
10
11
12
13
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
29
30 type Notification struct {
31
32 ID string
33
34
35 TopicID string
36
37
38 TopicProjectID string
39
40
41
42
43 EventTypes []string
44
45
46
47 ObjectNamePrefix string
48
49
50
51 CustomAttributes map[string]string
52
53
54
55 PayloadFormat string
56 }
57
58
59 const (
60
61 NoPayload = "NONE"
62
63
64 JSONPayload = "JSON_API_V1"
65 )
66
67
68 const (
69
70 ObjectFinalizeEvent = "OBJECT_FINALIZE"
71
72
73 ObjectMetadataUpdateEvent = "OBJECT_METADATA_UPDATE"
74
75
76 ObjectDeleteEvent = "OBJECT_DELETE"
77
78
79
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
122
123
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
145
146
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
167
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
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