~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/state/storage/storage.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2014 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package storage
 
5
 
 
6
import (
 
7
        "io"
 
8
 
 
9
        "gopkg.in/juju/blobstore.v2"
 
10
        "gopkg.in/mgo.v2"
 
11
)
 
12
 
 
13
const (
 
14
        // metadataDB is the name of the blobstore metadata database.
 
15
        metadataDB = "juju"
 
16
 
 
17
        // blobstoreDB is the name of the blobstore GridFS database.
 
18
        blobstoreDB = "blobstore"
 
19
)
 
20
 
 
21
// Storage is an interface providing methods for storing and retrieving
 
22
// data by path.
 
23
type Storage interface {
 
24
        // Get returns an io.ReadCloser for data at path, namespaced to the
 
25
        // model.
 
26
        //
 
27
        // If the data is still being uploaded and is not fully written yet, a
 
28
        // blobstore.ErrUploadPending error is returned. This means the path is
 
29
        // valid but the caller should try again later to retrieve the data.
 
30
        Get(path string) (r io.ReadCloser, length int64, err error)
 
31
 
 
32
        // Put stores data from reader at path, namespaced to the model.
 
33
        Put(path string, r io.Reader, length int64) error
 
34
 
 
35
        // PutAndCheckHash stores data from reader at path, namespaced to
 
36
        // the model. It also ensures the stored data has the correct
 
37
        // hash.
 
38
        PutAndCheckHash(path string, r io.Reader, length int64, hash string) error
 
39
 
 
40
        // Remove removes data at path, namespaced to the model.
 
41
        Remove(path string) error
 
42
}
 
43
 
 
44
// Storage returns a Storage for the model with the specified UUID.
 
45
func NewStorage(modelUUID string, session *mgo.Session) Storage {
 
46
        return stateStorage{modelUUID, session}
 
47
}
 
48
 
 
49
type stateStorage struct {
 
50
        modelUUID string
 
51
        session   *mgo.Session
 
52
}
 
53
 
 
54
func (s stateStorage) blobstore() (*mgo.Session, blobstore.ManagedStorage) {
 
55
        session := s.session.Copy()
 
56
        rs := blobstore.NewGridFS(blobstoreDB, blobstoreDB, session)
 
57
        db := session.DB(metadataDB)
 
58
        return session, blobstore.NewManagedStorage(db, rs)
 
59
}
 
60
 
 
61
func (s stateStorage) Get(path string) (r io.ReadCloser, length int64, err error) {
 
62
        session, ms := s.blobstore()
 
63
        r, length, err = ms.GetForBucket(s.modelUUID, path)
 
64
        if err != nil {
 
65
                session.Close()
 
66
                return nil, -1, err
 
67
        }
 
68
        return &stateStorageReadCloser{r, session}, length, nil
 
69
}
 
70
 
 
71
func (s stateStorage) Put(path string, r io.Reader, length int64) error {
 
72
        session, ms := s.blobstore()
 
73
        defer session.Close()
 
74
        return ms.PutForBucket(s.modelUUID, path, r, length)
 
75
}
 
76
 
 
77
func (s stateStorage) PutAndCheckHash(path string, r io.Reader, length int64, hash string) error {
 
78
        session, ms := s.blobstore()
 
79
        defer session.Close()
 
80
        return ms.PutForBucketAndCheckHash(s.modelUUID, path, r, length, hash)
 
81
}
 
82
 
 
83
func (s stateStorage) Remove(path string) error {
 
84
        session, ms := s.blobstore()
 
85
        defer session.Close()
 
86
        return ms.RemoveForBucket(s.modelUUID, path)
 
87
}
 
88
 
 
89
type stateStorageReadCloser struct {
 
90
        io.ReadCloser
 
91
        session *mgo.Session
 
92
}
 
93
 
 
94
func (r *stateStorageReadCloser) Close() error {
 
95
        r.session.Close()
 
96
        return r.ReadCloser.Close()
 
97
}