Skip to content

Commit

Permalink
ListBlobs is more complete and easier to use (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
mcardosos committed May 4, 2017
1 parent bd1bc2c commit fef9baa
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 15 deletions.
5 changes: 3 additions & 2 deletions storage/blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
type Blob struct {
Container *Container
Name string `xml:"Name"`
Snapshot time.Time `xml:"Snapshot"`
Properties BlobProperties `xml:"Properties"`
Metadata BlobMetadata `xml:"Metadata"`
}
Expand Down Expand Up @@ -246,9 +247,9 @@ type SnapshotOptions struct {
RequestID string `header:"x-ms-client-request-id"`
}

// Snapshot creates a snapshot for a blob
// CreateSnapshot creates a snapshot for a blob
// See https://msdn.microsoft.com/en-us/library/azure/ee691971.aspx
func (b *Blob) Snapshot(options *SnapshotOptions) (snapshotTimestamp *time.Time, err error) {
func (b *Blob) CreateSnapshot(options *SnapshotOptions) (snapshotTimestamp *time.Time, err error) {
params := url.Values{"comp": {"snapshot"}}
headers := b.Container.bsc.client.getStandardHeaders()
headers = b.Container.bsc.client.addMetadataToHeaders(headers, b.Metadata)
Expand Down
8 changes: 4 additions & 4 deletions storage/blob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ func (s *StorageBlobSuite) TestSnapshotBlob(c *chk.C) {

c.Assert(b.putSingleBlockBlob([]byte{}), chk.IsNil)

snapshotTime, err := b.Snapshot(nil)
snapshotTime, err := b.CreateSnapshot(nil)
c.Assert(err, chk.IsNil)
c.Assert(snapshotTime, chk.NotNil)
}
Expand All @@ -314,7 +314,7 @@ func (s *StorageBlobSuite) TestSnapshotBlobWithTimeout(c *chk.C) {
options := SnapshotOptions{
Timeout: 0,
}
snapshotTime, err := b.Snapshot(&options)
snapshotTime, err := b.CreateSnapshot(&options)
c.Assert(err, chk.IsNil)
c.Assert(snapshotTime, chk.NotNil)
}
Expand All @@ -335,7 +335,7 @@ func (s *StorageBlobSuite) TestSnapshotBlobWithValidLease(c *chk.C) {
options := SnapshotOptions{
LeaseID: currentLeaseID,
}
snapshotTime, err := b.Snapshot(&options)
snapshotTime, err := b.CreateSnapshot(&options)
c.Assert(err, chk.IsNil)
c.Assert(snapshotTime, chk.NotNil)
}
Expand All @@ -357,7 +357,7 @@ func (s *StorageBlobSuite) TestSnapshotBlobWithInvalidLease(c *chk.C) {
options := SnapshotOptions{
LeaseID: "GolangRocksOnAzure",
}
snapshotTime, err := b.Snapshot(&options)
snapshotTime, err := b.CreateSnapshot(&options)
c.Assert(err, chk.NotNil)
c.Assert(snapshotTime, chk.IsNil)
}
Expand Down
28 changes: 25 additions & 3 deletions storage/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net/http"
"net/url"
"strconv"
"strings"
"time"
)

Expand Down Expand Up @@ -70,6 +71,14 @@ type BlobListResponse struct {
Delimiter string `xml:"Delimiter"`
}

// IncludeBlobDataset has options to include in a list blobs operation
type IncludeBlobDataset struct {
Snapshots bool
Metadata bool
UncommittedBlobs bool
Copy bool
}

// ListBlobsParameters defines the set of customizable
// parameters to make a List Blobs call.
//
Expand All @@ -78,7 +87,7 @@ type ListBlobsParameters struct {
Prefix string
Delimiter string
Marker string
Include string
Include *IncludeBlobDataset
MaxResults uint
Timeout uint
RequestID string
Expand All @@ -96,8 +105,14 @@ func (p ListBlobsParameters) getParameters() url.Values {
if p.Marker != "" {
out.Set("marker", p.Marker)
}
if p.Include != "" {
out.Set("include", p.Include)
if p.Include != nil {
include := []string{}
include = addString(include, p.Include.Snapshots, "snapshots")
include = addString(include, p.Include.Metadata, "metadata")
include = addString(include, p.Include.UncommittedBlobs, "uncommittedblobs")
include = addString(include, p.Include.Copy, "copy")
fullInclude := strings.Join(include, ",")
out.Set("include", fullInclude)
}
if p.MaxResults != 0 {
out.Set("maxresults", strconv.FormatUint(uint64(p.MaxResults), 10))
Expand All @@ -109,6 +124,13 @@ func (p ListBlobsParameters) getParameters() url.Values {
return out
}

func addString(datasets []string, include bool, text string) []string {
if include {
datasets = append(datasets, text)
}
return datasets
}

// ContainerAccessType defines the access level to the container from a public
// request.
//
Expand Down
26 changes: 20 additions & 6 deletions storage/container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,27 +318,41 @@ func (s *ContainerSuite) TestListBlobsWithMetadata(c *chk.C) {
"lol": name,
"rofl_baz": "Waz Qux",
}
_, err := b.CreateSnapshot(nil)
c.Assert(err, chk.IsNil)
}

// Put one more blob with no metadata
b := cnt.GetBlobReference(randName(5))
c.Assert(b.putSingleBlockBlob([]byte("Hello, world!")), chk.IsNil)
expectMeta[b.Name] = nil

// Get ListBlobs with include:"metadata"
// Get ListBlobs with include: metadata and snapshots
resp, err := cnt.ListBlobs(ListBlobsParameters{
MaxResults: 5,
Include: "metadata"})
Include: &IncludeBlobDataset{
Metadata: true,
Snapshots: true,
},
})
c.Assert(err, chk.IsNil)

respBlobs := make(map[string]Blob)
originalBlobs := make(map[string]Blob)
snapshotBlobs := make(map[string]Blob)
for _, v := range resp.Blobs {
respBlobs[v.Name] = v
if v.Snapshot == (time.Time{}) {
originalBlobs[v.Name] = v
} else {
snapshotBlobs[v.Name] = v

}
}
c.Assert(originalBlobs, chk.HasLen, 5)
c.Assert(snapshotBlobs, chk.HasLen, 4)

// Verify the metadata is as expected
for name := range expectMeta {
c.Check(respBlobs[name].Metadata, chk.DeepEquals, expectMeta[name])
c.Check(originalBlobs[name].Metadata, chk.DeepEquals, expectMeta[name])
c.Check(snapshotBlobs[name].Metadata, chk.DeepEquals, expectMeta[name])
}
}

Expand Down

0 comments on commit fef9baa

Please sign in to comment.