~juju-qa/ubuntu/yakkety/juju/juju-1.25.8

« back to all changes in this revision

Viewing changes to src/google.golang.org/cloud/examples/storage/appenginevm/app.go

  • Committer: Nicholas Skaggs
  • Date: 2016-12-02 17:28:37 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161202172837-jkrbdlyjcxtrii2n
Initial commit of 1.25.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2014 Google Inc. All Rights Reserved.
 
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 gcsdemo is an example App Engine or Mananged VM app using the Google Cloud Storage API.
 
16
package gcsdemo
 
17
 
 
18
import (
 
19
        "bytes"
 
20
        "fmt"
 
21
        "io"
 
22
        "io/ioutil"
 
23
        "net/http"
 
24
        "strings"
 
25
 
 
26
        "golang.org/x/net/context"
 
27
        "golang.org/x/oauth2"
 
28
        "golang.org/x/oauth2/google"
 
29
        "google.golang.org/appengine"
 
30
        "google.golang.org/appengine/file"
 
31
        "google.golang.org/appengine/log"
 
32
        "google.golang.org/appengine/urlfetch"
 
33
        "google.golang.org/cloud"
 
34
        "google.golang.org/cloud/storage"
 
35
)
 
36
 
 
37
// bucket is a local cache of the app's default bucket name.
 
38
var bucket string // or: var bucket = "<your-app-id>.appspot.com"
 
39
 
 
40
func init() {
 
41
        http.HandleFunc("/", handler)
 
42
}
 
43
 
 
44
// demo struct holds information needed to run the various demo functions.
 
45
type demo struct {
 
46
        c   context.Context
 
47
        w   http.ResponseWriter
 
48
        ctx context.Context
 
49
        // cleanUp is a list of filenames that need cleaning up at the end of the demo.
 
50
        cleanUp []string
 
51
        // failed indicates that one or more of the demo steps failed.
 
52
        failed bool
 
53
}
 
54
 
 
55
func (d *demo) errorf(format string, args ...interface{}) {
 
56
        d.failed = true
 
57
        log.Errorf(d.c, format, args...)
 
58
}
 
59
 
 
60
// handler is the main demo entry point that calls the GCS operations.
 
61
func handler(w http.ResponseWriter, r *http.Request) {
 
62
        if r.URL.Path != "/" {
 
63
                http.NotFound(w, r)
 
64
                return
 
65
        }
 
66
        c := appengine.NewContext(r)
 
67
        if bucket == "" {
 
68
                var err error
 
69
                if bucket, err = file.DefaultBucketName(c); err != nil {
 
70
                        log.Errorf(c, "failed to get default GCS bucket name: %v", err)
 
71
                        return
 
72
                }
 
73
        }
 
74
        hc := &http.Client{
 
75
                Transport: &oauth2.Transport{
 
76
                        Source: google.AppEngineTokenSource(c, storage.ScopeFullControl),
 
77
                        Base:   &urlfetch.Transport{Context: c},
 
78
                },
 
79
        }
 
80
        ctx := cloud.NewContext(appengine.AppID(c), hc)
 
81
        w.Header().Set("Content-Type", "text/plain; charset=utf-8")
 
82
        fmt.Fprintf(w, "Demo GCS Application running from Version: %v\n", appengine.VersionID(c))
 
83
        fmt.Fprintf(w, "Using bucket name: %v\n\n", bucket)
 
84
 
 
85
        d := &demo{
 
86
                c:   c,
 
87
                w:   w,
 
88
                ctx: ctx,
 
89
        }
 
90
 
 
91
        n := "demo-testfile-go"
 
92
        d.createFile(n)
 
93
        d.readFile(n)
 
94
        d.copyFile(n)
 
95
        d.statFile(n)
 
96
        d.createListFiles()
 
97
        d.listBucket()
 
98
        d.listBucketDirMode()
 
99
        d.defaultACL()
 
100
        d.putDefaultACLRule()
 
101
        d.deleteDefaultACLRule()
 
102
        d.bucketACL()
 
103
        d.putBucketACLRule()
 
104
        d.deleteBucketACLRule()
 
105
        d.acl(n)
 
106
        d.putACLRule(n)
 
107
        d.deleteACLRule(n)
 
108
        d.deleteFiles()
 
109
 
 
110
        if d.failed {
 
111
                io.WriteString(w, "\nDemo failed.\n")
 
112
        } else {
 
113
                io.WriteString(w, "\nDemo succeeded.\n")
 
114
        }
 
115
}
 
116
 
 
117
// createFile creates a file in Google Cloud Storage.
 
118
func (d *demo) createFile(fileName string) {
 
119
        fmt.Fprintf(d.w, "Creating file /%v/%v\n", bucket, fileName)
 
120
 
 
121
        wc := storage.NewWriter(d.ctx, bucket, fileName)
 
122
        wc.ContentType = "text/plain"
 
123
        wc.Metadata = map[string]string{
 
124
                "x-goog-meta-foo": "foo",
 
125
                "x-goog-meta-bar": "bar",
 
126
        }
 
127
        d.cleanUp = append(d.cleanUp, fileName)
 
128
 
 
129
        if _, err := wc.Write([]byte("abcde\n")); err != nil {
 
130
                d.errorf("createFile: unable to write data to bucket %q, file %q: %v", bucket, fileName, err)
 
131
                return
 
132
        }
 
133
        if _, err := wc.Write([]byte(strings.Repeat("f", 1024*4) + "\n")); err != nil {
 
134
                d.errorf("createFile: unable to write data to bucket %q, file %q: %v", bucket, fileName, err)
 
135
                return
 
136
        }
 
137
        if err := wc.Close(); err != nil {
 
138
                d.errorf("createFile: unable to close bucket %q, file %q: %v", bucket, fileName, err)
 
139
                return
 
140
        }
 
141
}
 
142
 
 
143
// readFile reads the named file in Google Cloud Storage.
 
144
func (d *demo) readFile(fileName string) {
 
145
        io.WriteString(d.w, "\nAbbreviated file content (first line and last 1K):\n")
 
146
 
 
147
        rc, err := storage.NewReader(d.ctx, bucket, fileName)
 
148
        if err != nil {
 
149
                d.errorf("readFile: unable to open file from bucket %q, file %q: %v", bucket, fileName, err)
 
150
                return
 
151
        }
 
152
        defer rc.Close()
 
153
        slurp, err := ioutil.ReadAll(rc)
 
154
        if err != nil {
 
155
                d.errorf("readFile: unable to read data from bucket %q, file %q: %v", bucket, fileName, err)
 
156
                return
 
157
        }
 
158
 
 
159
        fmt.Fprintf(d.w, "%s\n", bytes.SplitN(slurp, []byte("\n"), 2)[0])
 
160
        if len(slurp) > 1024 {
 
161
                fmt.Fprintf(d.w, "...%s\n", slurp[len(slurp)-1024:])
 
162
        } else {
 
163
                fmt.Fprintf(d.w, "%s\n", slurp)
 
164
        }
 
165
}
 
166
 
 
167
// copyFile copies a file in Google Cloud Storage.
 
168
func (d *demo) copyFile(fileName string) {
 
169
        copyName := fileName + "-copy"
 
170
        fmt.Fprintf(d.w, "Copying file /%v/%v to /%v/%v:\n", bucket, fileName, bucket, copyName)
 
171
 
 
172
        attrs := storage.ObjectAttrs{
 
173
                Name:        copyName,
 
174
                ContentType: "text/plain",
 
175
                Metadata: map[string]string{
 
176
                        "x-goog-meta-foo-copy": "foo-copy",
 
177
                        "x-goog-meta-bar-copy": "bar-copy",
 
178
                },
 
179
        }
 
180
        obj, err := storage.CopyObject(d.ctx, bucket, fileName, bucket, attrs)
 
181
        if err != nil {
 
182
                d.errorf("copyFile: unable to copy /%v/%v to bucket %q, file %q: %v", bucket, fileName, bucket, copyName, err)
 
183
                return
 
184
        }
 
185
        d.cleanUp = append(d.cleanUp, copyName)
 
186
 
 
187
        d.dumpStats(obj)
 
188
}
 
189
 
 
190
func (d *demo) dumpStats(obj *storage.Object) {
 
191
        fmt.Fprintf(d.w, "(filename: /%v/%v, ", obj.Bucket, obj.Name)
 
192
        fmt.Fprintf(d.w, "ContentType: %q, ", obj.ContentType)
 
193
        fmt.Fprintf(d.w, "ACL: %#v, ", obj.ACL)
 
194
        fmt.Fprintf(d.w, "Owner: %v, ", obj.Owner)
 
195
        fmt.Fprintf(d.w, "ContentEncoding: %q, ", obj.ContentEncoding)
 
196
        fmt.Fprintf(d.w, "Size: %v, ", obj.Size)
 
197
        fmt.Fprintf(d.w, "MD5: %q, ", obj.MD5)
 
198
        fmt.Fprintf(d.w, "CRC32C: %q, ", obj.CRC32C)
 
199
        fmt.Fprintf(d.w, "Metadata: %#v, ", obj.Metadata)
 
200
        fmt.Fprintf(d.w, "MediaLink: %q, ", obj.MediaLink)
 
201
        fmt.Fprintf(d.w, "StorageClass: %q, ", obj.StorageClass)
 
202
        if !obj.Deleted.IsZero() {
 
203
                fmt.Fprintf(d.w, "Deleted: %v, ", obj.Deleted)
 
204
        }
 
205
        fmt.Fprintf(d.w, "Updated: %v)\n", obj.Updated)
 
206
}
 
207
 
 
208
// statFile reads the stats of the named file in Google Cloud Storage.
 
209
func (d *demo) statFile(fileName string) {
 
210
        io.WriteString(d.w, "\nFile stat:\n")
 
211
 
 
212
        obj, err := storage.StatObject(d.ctx, bucket, fileName)
 
213
        if err != nil {
 
214
                d.errorf("statFile: unable to stat file from bucket %q, file %q: %v", bucket, fileName, err)
 
215
                return
 
216
        }
 
217
 
 
218
        d.dumpStats(obj)
 
219
}
 
220
 
 
221
// createListFiles creates files that will be used by listBucket.
 
222
func (d *demo) createListFiles() {
 
223
        io.WriteString(d.w, "\nCreating more files for listbucket...\n")
 
224
        for _, n := range []string{"foo1", "foo2", "bar", "bar/1", "bar/2", "boo/"} {
 
225
                d.createFile(n)
 
226
        }
 
227
}
 
228
 
 
229
// listBucket lists the contents of a bucket in Google Cloud Storage.
 
230
func (d *demo) listBucket() {
 
231
        io.WriteString(d.w, "\nListbucket result:\n")
 
232
 
 
233
        query := &storage.Query{Prefix: "foo"}
 
234
        for query != nil {
 
235
                objs, err := storage.ListObjects(d.ctx, bucket, query)
 
236
                if err != nil {
 
237
                        d.errorf("listBucket: unable to list bucket %q: %v", bucket, err)
 
238
                        return
 
239
                }
 
240
                query = objs.Next
 
241
 
 
242
                for _, obj := range objs.Results {
 
243
                        d.dumpStats(obj)
 
244
                }
 
245
        }
 
246
}
 
247
 
 
248
func (d *demo) listDir(name, indent string) {
 
249
        query := &storage.Query{Prefix: name, Delimiter: "/"}
 
250
        for query != nil {
 
251
                objs, err := storage.ListObjects(d.ctx, bucket, query)
 
252
                if err != nil {
 
253
                        d.errorf("listBucketDirMode: unable to list bucket %q: %v", bucket, err)
 
254
                        return
 
255
                }
 
256
                query = objs.Next
 
257
 
 
258
                for _, obj := range objs.Results {
 
259
                        fmt.Fprint(d.w, indent)
 
260
                        d.dumpStats(obj)
 
261
                }
 
262
                for _, dir := range objs.Prefixes {
 
263
                        fmt.Fprintf(d.w, "%v(directory: /%v/%v)\n", indent, bucket, dir)
 
264
                        d.listDir(dir, indent+"  ")
 
265
                }
 
266
        }
 
267
}
 
268
 
 
269
// listBucketDirMode lists the contents of a bucket in dir mode in Google Cloud Storage.
 
270
func (d *demo) listBucketDirMode() {
 
271
        io.WriteString(d.w, "\nListbucket directory mode result:\n")
 
272
        d.listDir("b", "")
 
273
}
 
274
 
 
275
// dumpDefaultACL prints out the default object ACL for this bucket.
 
276
func (d *demo) dumpDefaultACL() {
 
277
        acl, err := storage.DefaultACL(d.ctx, bucket)
 
278
        if err != nil {
 
279
                d.errorf("defaultACL: unable to list default object ACL for bucket %q: %v", bucket, err)
 
280
                return
 
281
        }
 
282
        for _, v := range acl {
 
283
                fmt.Fprintf(d.w, "Entity: %q, Role: %q\n", v.Entity, v.Role)
 
284
        }
 
285
}
 
286
 
 
287
// defaultACL displays the default object ACL for this bucket.
 
288
func (d *demo) defaultACL() {
 
289
        io.WriteString(d.w, "\nDefault object ACL:\n")
 
290
        d.dumpDefaultACL()
 
291
}
 
292
 
 
293
// putDefaultACLRule adds the "allUsers" default object ACL rule for this bucket.
 
294
func (d *demo) putDefaultACLRule() {
 
295
        io.WriteString(d.w, "\nPut Default object ACL Rule:\n")
 
296
        err := storage.PutDefaultACLRule(d.ctx, bucket, "allUsers", storage.RoleReader)
 
297
        if err != nil {
 
298
                d.errorf("putDefaultACLRule: unable to save default object ACL rule for bucket %q: %v", bucket, err)
 
299
                return
 
300
        }
 
301
        d.dumpDefaultACL()
 
302
}
 
303
 
 
304
// deleteDefaultACLRule deleted the "allUsers" default object ACL rule for this bucket.
 
305
func (d *demo) deleteDefaultACLRule() {
 
306
        io.WriteString(d.w, "\nDelete Default object ACL Rule:\n")
 
307
        err := storage.DeleteDefaultACLRule(d.ctx, bucket, "allUsers")
 
308
        if err != nil {
 
309
                d.errorf("deleteDefaultACLRule: unable to delete default object ACL rule for bucket %q: %v", bucket, err)
 
310
                return
 
311
        }
 
312
        d.dumpDefaultACL()
 
313
}
 
314
 
 
315
// dumpBucketACL prints out the bucket ACL.
 
316
func (d *demo) dumpBucketACL() {
 
317
        acl, err := storage.BucketACL(d.ctx, bucket)
 
318
        if err != nil {
 
319
                d.errorf("dumpBucketACL: unable to list bucket ACL for bucket %q: %v", bucket, err)
 
320
                return
 
321
        }
 
322
        for _, v := range acl {
 
323
                fmt.Fprintf(d.w, "Entity: %q, Role: %q\n", v.Entity, v.Role)
 
324
        }
 
325
}
 
326
 
 
327
// bucketACL displays the bucket ACL for this bucket.
 
328
func (d *demo) bucketACL() {
 
329
        io.WriteString(d.w, "\nBucket ACL:\n")
 
330
        d.dumpBucketACL()
 
331
}
 
332
 
 
333
// putBucketACLRule adds the "allUsers" bucket ACL rule for this bucket.
 
334
func (d *demo) putBucketACLRule() {
 
335
        io.WriteString(d.w, "\nPut Bucket ACL Rule:\n")
 
336
        err := storage.PutBucketACLRule(d.ctx, bucket, "allUsers", storage.RoleReader)
 
337
        if err != nil {
 
338
                d.errorf("putBucketACLRule: unable to save bucket ACL rule for bucket %q: %v", bucket, err)
 
339
                return
 
340
        }
 
341
        d.dumpBucketACL()
 
342
}
 
343
 
 
344
// deleteBucketACLRule deleted the "allUsers" bucket ACL rule for this bucket.
 
345
func (d *demo) deleteBucketACLRule() {
 
346
        io.WriteString(d.w, "\nDelete Bucket ACL Rule:\n")
 
347
        err := storage.DeleteBucketACLRule(d.ctx, bucket, "allUsers")
 
348
        if err != nil {
 
349
                d.errorf("deleteBucketACLRule: unable to delete bucket ACL rule for bucket %q: %v", bucket, err)
 
350
                return
 
351
        }
 
352
        d.dumpBucketACL()
 
353
}
 
354
 
 
355
// dumpACL prints out the ACL of the named file.
 
356
func (d *demo) dumpACL(fileName string) {
 
357
        acl, err := storage.ACL(d.ctx, bucket, fileName)
 
358
        if err != nil {
 
359
                d.errorf("dumpACL: unable to list file ACL for bucket %q, file %q: %v", bucket, fileName, err)
 
360
                return
 
361
        }
 
362
        for _, v := range acl {
 
363
                fmt.Fprintf(d.w, "Entity: %q, Role: %q\n", v.Entity, v.Role)
 
364
        }
 
365
}
 
366
 
 
367
// acl displays the ACL for the named file.
 
368
func (d *demo) acl(fileName string) {
 
369
        fmt.Fprintf(d.w, "\nACL for file %v:\n", fileName)
 
370
        d.dumpACL(fileName)
 
371
}
 
372
 
 
373
// putACLRule adds the "allUsers" ACL rule for the named file.
 
374
func (d *demo) putACLRule(fileName string) {
 
375
        fmt.Fprintf(d.w, "\nPut ACL rule for file %v:\n", fileName)
 
376
        err := storage.PutACLRule(d.ctx, bucket, fileName, "allUsers", storage.RoleReader)
 
377
        if err != nil {
 
378
                d.errorf("putACLRule: unable to save ACL rule for bucket %q, file %q: %v", bucket, fileName, err)
 
379
                return
 
380
        }
 
381
        d.dumpACL(fileName)
 
382
}
 
383
 
 
384
// deleteACLRule deleted the "allUsers" ACL rule for the named file.
 
385
func (d *demo) deleteACLRule(fileName string) {
 
386
        fmt.Fprintf(d.w, "\nDelete ACL rule for file %v:\n", fileName)
 
387
        err := storage.DeleteACLRule(d.ctx, bucket, fileName, "allUsers")
 
388
        if err != nil {
 
389
                d.errorf("deleteACLRule: unable to delete ACL rule for bucket %q, file %q: %v", bucket, fileName, err)
 
390
                return
 
391
        }
 
392
        d.dumpACL(fileName)
 
393
}
 
394
 
 
395
// deleteFiles deletes all the temporary files from a bucket created by this demo.
 
396
func (d *demo) deleteFiles() {
 
397
        io.WriteString(d.w, "\nDeleting files...\n")
 
398
        for _, v := range d.cleanUp {
 
399
                fmt.Fprintf(d.w, "Deleting file %v\n", v)
 
400
                if err := storage.DeleteObject(d.ctx, bucket, v); err != nil {
 
401
                        d.errorf("deleteFiles: unable to delete bucket %q, file %q: %v", bucket, v, err)
 
402
                        return
 
403
                }
 
404
        }
 
405
}