Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return storage package to this repository. #597

Merged
merged 24 commits into from
Apr 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
8323b44
Responding to review feedback.
marstr Apr 7, 2017
7af26be
Support for larger block blobs (#19)
mcardosos Mar 2, 2017
fe4c57b
Merge pull request #563 from AYLIEN/fix-table-entities-error-checking…
mcardosos Mar 2, 2017
6248e8f
Blobs as receivers, divided blob file (#14)
mcardosos Mar 3, 2017
13e3e08
Updating User Agent (#15)
marstr Mar 8, 2017
225a45a
Return correct status code when unmarshal fails
mcardosos Mar 10, 2017
9cc3bda
Getting rid of extraHeaders in blob (#22)
mcardosos Mar 10, 2017
3d4c1c8
Different funcs for write and clear blob pages (#28)
mcardosos Mar 14, 2017
cc88187
Adding a "Getting Started" section to the README. (#26)
marstr Mar 16, 2017
4e25734
ListBlobs is more complete and easier to use (#31)
mcardosos Mar 23, 2017
4f352f0
Added missing parameters (#29)
mcardosos Mar 23, 2017
732c420
Table params (#32)
mcardosos Mar 28, 2017
80c3ecf
Including date and API version in AzureStorageServiceError (#33)
mcardosos Mar 28, 2017
3cc07dc
Incremental Copy (#38)
kpfaulkner Apr 4, 2017
41dda2b
Queue (#27)
mcardosos Apr 4, 2017
ceb7e01
Table Batch Operations (#37)
kpfaulkner Apr 10, 2017
0d6b7d4
Recorded tests (#44)
mcardosos Apr 12, 2017
1268659
Include property response headers in get blob operation too (#46)
mcardosos Apr 20, 2017
af9d631
Queueacl (#45)
kpfaulkner Apr 21, 2017
25575bc
Added test for inifinite lease (#47)
mcardosos Apr 21, 2017
4d876b9
Get entity and table without using query funcs (#48)
mcardosos Apr 21, 2017
0285d15
Added retry logic (#49)
mcardosos Apr 26, 2017
973f690
Adding storage tests to travis
marstr Apr 27, 2017
9c2aaec
Removing pre-refactor table_entities.go file.
marstr Apr 28, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@ script:
- bash rungas.sh
- test -z "$(gofmt -s -l $(find ./arm/* -type d -print) | tee /dev/stderr)"
- test -z "$(gofmt -s -l -w management | tee /dev/stderr)"
- test -z "$(gofmt -s -l -w storage | tee /dev/stderr)"
- test -z "$(gofmt -s -l -w Gododir | tee /dev/stderr)"
- test -z "$(go build $(find ./* -type d -print | grep -v '^./vendor$' | grep -v '^./storage$') | tee /dev/stderr)"
- test -z "$(go vet $(find ./arm/* -type d -print) | tee /dev/stderr)"
- test -z "$(golint ./arm/... | tee /dev/stderr)"
- go test -v ./management/...
- go test -v ./storage/...
- test -z "$(golint ./management/... | grep -v 'should have comment' | grep -v 'stutters' | tee /dev/stderr)"
- go vet ./management/...
- go vet ./storage/...
- test -z "$(golint ./Gododir/... | tee /dev/stderr)"
- go vet ./Gododir/...
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
[![Build Status](https://travis-ci.org/Azure/azure-sdk-for-go.svg?branch=master)](https://travis-ci.org/Azure/azure-sdk-for-go)
[![Go Report Card](https://goreportcard.com/badge/github.com/Azure/azure-sdk-for-go)](https://goreportcard.com/report/github.com/Azure/azure-sdk-for-go)


This is Microsoft Azure's core repository for hosting Go packages which offer a more convenient way of targeting Azure
REST endpoints. Here, you'll find a mix of code generated by [Autorest](https://github.com/Azure/autorest) and hand
maintained packages.
Expand Down
37 changes: 29 additions & 8 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion glide.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ import:
- package: golang.org/x/crypto
subpackages:
- /pkcs12
- package: gopkg.in/check.v1
- package: gopkg.in/check.v1
70 changes: 70 additions & 0 deletions storage/appendblob.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package storage

import (
"bytes"
"fmt"
"net/http"
"net/url"
"time"
)

// PutAppendBlob initializes an empty append blob with specified name. An
// append blob must be created using this method before appending blocks.
//
// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Put-Blob
func (b *Blob) PutAppendBlob(options *PutBlobOptions) error {
params := url.Values{}
headers := b.Container.bsc.client.getStandardHeaders()
headers["x-ms-blob-type"] = string(BlobTypeAppend)
headers = mergeHeaders(headers, headersFromStruct(b.Properties))
headers = b.Container.bsc.client.addMetadataToHeaders(headers, b.Metadata)

if options != nil {
params = addTimeout(params, options.Timeout)
headers = mergeHeaders(headers, headersFromStruct(*options))
}
uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), params)

resp, err := b.Container.bsc.client.exec(http.MethodPut, uri, headers, nil, b.Container.bsc.auth)
if err != nil {
return err
}
readAndCloseBody(resp.body)
return checkRespCode(resp.statusCode, []int{http.StatusCreated})
}

// AppendBlockOptions includes the options for an append block operation
type AppendBlockOptions struct {
Timeout uint
LeaseID string `header:"x-ms-lease-id"`
MaxSize *uint `header:"x-ms-blob-condition-maxsize"`
AppendPosition *uint `header:"x-ms-blob-condition-appendpos"`
IfModifiedSince *time.Time `header:"If-Modified-Since"`
IfUnmodifiedSince *time.Time `header:"If-Unmodified-Since"`
IfMatch string `header:"If-Match"`
IfNoneMatch string `header:"If-None-Match"`
RequestID string `header:"x-ms-client-request-id"`
}

// AppendBlock appends a block to an append blob.
//
// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Append-Block
func (b *Blob) AppendBlock(chunk []byte, options *AppendBlockOptions) error {
params := url.Values{"comp": {"appendblock"}}
headers := b.Container.bsc.client.getStandardHeaders()
headers["x-ms-blob-type"] = string(BlobTypeAppend)
headers["Content-Length"] = fmt.Sprintf("%v", len(chunk))

if options != nil {
params = addTimeout(params, options.Timeout)
headers = mergeHeaders(headers, headersFromStruct(*options))
}
uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), params)

resp, err := b.Container.bsc.client.exec(http.MethodPut, uri, headers, bytes.NewReader(chunk), b.Container.bsc.auth)
if err != nil {
return err
}
readAndCloseBody(resp.body)
return checkRespCode(resp.statusCode, []int{http.StatusCreated})
}
126 changes: 126 additions & 0 deletions storage/appendblob_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package storage

import (
"io/ioutil"

chk "gopkg.in/check.v1"
)

type AppendBlobSuite struct{}

var _ = chk.Suite(&AppendBlobSuite{})

func (s *AppendBlobSuite) TestPutAppendBlob(c *chk.C) {
cli := getBlobClient(c)
rec := cli.client.appendRecorder(c)
defer rec.Stop()

cnt := cli.GetContainerReference(containerName(c))
b := cnt.GetBlobReference(blobName(c))
c.Assert(cnt.Create(nil), chk.IsNil)
defer cnt.Delete(nil)

c.Assert(b.PutAppendBlob(nil), chk.IsNil)

// Verify
err := b.GetProperties(nil)
c.Assert(err, chk.IsNil)
c.Assert(b.Properties.ContentLength, chk.Equals, int64(0))
c.Assert(b.Properties.BlobType, chk.Equals, BlobTypeAppend)
}

func (s *AppendBlobSuite) TestPutAppendBlobAppendBlocks(c *chk.C) {
cli := getBlobClient(c)
rec := cli.client.appendRecorder(c)
defer rec.Stop()

cnt := cli.GetContainerReference(containerName(c))
b := cnt.GetBlobReference(blobName(c))
c.Assert(cnt.Create(nil), chk.IsNil)
defer cnt.Delete(nil)

c.Assert(b.PutAppendBlob(nil), chk.IsNil)

chunk1 := content(1024)
chunk2 := content(512)

// Append first block
c.Assert(b.AppendBlock(chunk1, nil), chk.IsNil)

// Verify contents
options := GetBlobRangeOptions{
Range: &BlobRange{
Start: 0,
End: uint64(len(chunk1) - 1),
},
}
out, err := b.GetRange(&options)
c.Assert(err, chk.IsNil)
defer out.Close()
blobContents, err := ioutil.ReadAll(out)
c.Assert(err, chk.IsNil)
c.Assert(blobContents, chk.DeepEquals, chunk1)

// Append second block
c.Assert(b.AppendBlock(chunk2, nil), chk.IsNil)

// Verify contents
options.Range.End = uint64(len(chunk1) + len(chunk2) - 1)
out, err = b.GetRange(&options)
c.Assert(err, chk.IsNil)
defer out.Close()
blobContents, err = ioutil.ReadAll(out)
c.Assert(err, chk.IsNil)
c.Assert(blobContents, chk.DeepEquals, append(chunk1, chunk2...))
}

func (s *StorageBlobSuite) TestPutAppendBlobSpecialChars(c *chk.C) {
cli := getBlobClient(c)
rec := cli.client.appendRecorder(c)
defer rec.Stop()

cnt := cli.GetContainerReference(containerName(c))
b := cnt.GetBlobReference(blobName(c))
c.Assert(cnt.Create(nil), chk.IsNil)
defer cnt.Delete(nil)

c.Assert(b.PutAppendBlob(nil), chk.IsNil)

// Verify metadata
err := b.GetProperties(nil)
c.Assert(err, chk.IsNil)
c.Assert(b.Properties.ContentLength, chk.Equals, int64(0))
c.Assert(b.Properties.BlobType, chk.Equals, BlobTypeAppend)

chunk1 := content(1024)
chunk2 := content(512)

// Append first block
c.Assert(b.AppendBlock(chunk1, nil), chk.IsNil)

// Verify contents
options := GetBlobRangeOptions{
Range: &BlobRange{
Start: 0,
End: uint64(len(chunk1) - 1),
},
}
out, err := b.GetRange(&options)
c.Assert(err, chk.IsNil)
defer out.Close()
blobContents, err := ioutil.ReadAll(out)
c.Assert(err, chk.IsNil)
c.Assert(blobContents, chk.DeepEquals, chunk1)

// Append second block
c.Assert(b.AppendBlock(chunk2, nil), chk.IsNil)

// Verify contents
options.Range.End = uint64(len(chunk1) + len(chunk2) - 1)
out, err = b.GetRange(&options)
c.Assert(err, chk.IsNil)
defer out.Close()
blobContents, err = ioutil.ReadAll(out)
c.Assert(err, chk.IsNil)
c.Assert(blobContents, chk.DeepEquals, append(chunk1, chunk2...))
}
32 changes: 18 additions & 14 deletions storage/authorization.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,24 @@ const (
sharedKeyLiteForTable authentication = "sharedKeyLiteTable"

// headers
headerAuthorization = "Authorization"
headerContentLength = "Content-Length"
headerDate = "Date"
headerXmsDate = "x-ms-date"
headerXmsVersion = "x-ms-version"
headerContentEncoding = "Content-Encoding"
headerContentLanguage = "Content-Language"
headerContentType = "Content-Type"
headerContentMD5 = "Content-MD5"
headerIfModifiedSince = "If-Modified-Since"
headerIfMatch = "If-Match"
headerIfNoneMatch = "If-None-Match"
headerIfUnmodifiedSince = "If-Unmodified-Since"
headerRange = "Range"
headerAcceptCharset = "Accept-Charset"
headerAuthorization = "Authorization"
headerContentLength = "Content-Length"
headerDate = "Date"
headerXmsDate = "x-ms-date"
headerXmsVersion = "x-ms-version"
headerContentEncoding = "Content-Encoding"
headerContentLanguage = "Content-Language"
headerContentType = "Content-Type"
headerContentMD5 = "Content-MD5"
headerIfModifiedSince = "If-Modified-Since"
headerIfMatch = "If-Match"
headerIfNoneMatch = "If-None-Match"
headerIfUnmodifiedSince = "If-Unmodified-Since"
headerRange = "Range"
headerDataServiceVersion = "DataServiceVersion"
headerMaxDataServiceVersion = "MaxDataServiceVersion"
headerContentTransferEncoding = "Content-Transfer-Encoding"
)

func (c *Client) addAuthorizationHeader(verb, url string, headers map[string]string, auth authentication) (map[string]string, error) {
Expand Down
Loading