diff --git a/.travis.yml b/.travis.yml index 2b7f4a2f675c..0a6a1c1e4e80 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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/... diff --git a/README.md b/README.md index 8de42e2d922d..949327424ebd 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/glide.lock b/glide.lock index 13d0ad67138e..272143cb58e8 100644 --- a/glide.lock +++ b/glide.lock @@ -1,8 +1,22 @@ hash: 5a5e74f8be7a721d3ea9c2e36d994d2754f15087f89ba8342c4ec9ed4cbedf7b -updated: 2017-03-01T16:08:43.5505724-08:00 +updated: 2017-04-26T14:49:24.0346028-07:00 imports: +- name: github.com/Azure/azure-sdk-for-go + version: 8dd1f3ff407c300cff0a4bfedd969111ca5a7903 + subpackages: + - arm/examples/helpers + - arm/storage + - management + - management/virtualmachinedisk + - management/location + - management/virtualmachine + - management/testutils + - management/hostedservice + - management/osimage + - management/storageservice + - management/virtualmachineimage - name: github.com/Azure/go-autorest - version: ec5f4903f77ed9927ac95b19ab8e44ada64c1356 + version: a2fdd780c9a50455cecd249b00bdc3eb73a78e31 subpackages: - autorest - autorest/azure @@ -14,9 +28,9 @@ imports: - name: github.com/howeyc/gopass version: bf9dde6d0d2c004a008c27aaee91170c786f6db8 - name: github.com/mattn/go-colorable - version: d898aa9fb31c91f35dd28ca75db377eff023c076 + version: ded68f7a9561c023e790de24279db7ebf473ea80 - name: github.com/mattn/go-isatty - version: dda3de49cbfcec471bd7a70e6cc01fcc3ff90109 + version: fc9e8d8ef48496124e79ae0df75490096eccf6fe - name: github.com/mgutz/ansi version: 9520e82c474b0a04dd04f8a40959027271bab992 - name: github.com/mgutz/minimist @@ -30,17 +44,17 @@ imports: - name: github.com/nozzle/throttler version: d9b45f19996c645d38c9266d1f5cf1990e930119 - name: github.com/satori/uuid - version: b061729afc07e77a8aa4fad0a2fd840958f1942a + version: 5bf94b69c6b68ee1b541973bb8e1144db23a194b - name: github.com/shopspring/decimal version: 3526cd0bdb7f64e1178943b7dee81a0cc3d86a69 - name: golang.org/x/crypto - version: 453249f01cfeb54c3d549ddb75ff152ca243f9d8 + version: c7af5bf2638a1164f2eb5467c39c6cffbd13a02e subpackages: - pkcs12 - pkcs12/internal/rc2 - ssh/terminal - name: golang.org/x/sys - version: 76cc09b634294339fa19ec41b5f2a0b3932cea8b + version: 9f30dcbe5be197894515a338a9bda9253567ea8f subpackages: - unix - name: gopkg.in/check.v1 @@ -52,4 +66,11 @@ imports: - util - watcher - watcher/fswatch -testImports: [] +testImports: +- name: github.com/dnaeon/go-vcr + version: 87d4990451a858cc210399285be976e63bc3c364 + subpackages: + - cassette + - recorder +- name: gopkg.in/yaml.v2 + version: cd8b52f8269e0feb286dfeef29f8fe4d5b397e0b diff --git a/glide.yaml b/glide.yaml index 945d9c031ba1..66bcdd67d69d 100644 --- a/glide.yaml +++ b/glide.yaml @@ -10,4 +10,4 @@ import: - package: golang.org/x/crypto subpackages: - /pkcs12 -- package: gopkg.in/check.v1 \ No newline at end of file +- package: gopkg.in/check.v1 diff --git a/storage/appendblob.go b/storage/appendblob.go new file mode 100644 index 000000000000..3292cb556951 --- /dev/null +++ b/storage/appendblob.go @@ -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}) +} diff --git a/storage/appendblob_test.go b/storage/appendblob_test.go new file mode 100644 index 000000000000..23f2a6e08a27 --- /dev/null +++ b/storage/appendblob_test.go @@ -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...)) +} diff --git a/storage/authorization.go b/storage/authorization.go index 89a0d0b3cdf8..608bf3133866 100644 --- a/storage/authorization.go +++ b/storage/authorization.go @@ -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) { diff --git a/storage/authorization_test.go b/storage/authorization_test.go index d6e753760c59..420868acfb71 100644 --- a/storage/authorization_test.go +++ b/storage/authorization_test.go @@ -12,7 +12,7 @@ type AuthorizationSuite struct{} var _ = chk.Suite(&AuthorizationSuite{}) func (a *AuthorizationSuite) Test_addAuthorizationHeader(c *chk.C) { - cli, err := NewBasicClient("mindgotest", "zHDHGs7C+Di9pZSDMuarxJJz3xRBzAHBYaobxpLEc7kwTptR/hPEa9j93hIfb2Tbe9IA50MViGmjQ6nUF/OVvA==") + cli, err := NewBasicClient(dummyStorageAccount, dummyMiniStorageKey) c.Assert(err, chk.IsNil) cli.UseSharedKeyLite = true tableCli := cli.GetTableService() @@ -25,16 +25,16 @@ func (a *AuthorizationSuite) Test_addAuthorizationHeader(c *chk.C) { headerXmsVersion: "2015-02-21", "Accept": "application/json;odata=nometadata", } - url := "https://mindgotest.table.core.windows.net/tquery()" + url := "https://golangrocksonazure.table.core.windows.net/tquery()" headers, err = tableCli.client.addAuthorizationHeader("", url, headers, tableCli.auth) c.Assert(err, chk.IsNil) - c.Assert(headers[headerAuthorization], chk.Equals, "SharedKeyLite mindgotest:+32DTgsPUgXPo/O7RYaTs0DllA6FTXMj3uK4Qst8y/E=") + c.Assert(headers[headerAuthorization], chk.Equals, "SharedKeyLite golangrocksonazure:NusXSFXAvHqr6EQNXnZZ50CvU1sX0iP/FFDHehnixLc=") } func (a *AuthorizationSuite) Test_getSharedKey(c *chk.C) { // Shared Key Lite for Tables - cli, err := NewBasicClient("mindgotest", "zHDHGs7C+Di9pZSDMuarxJJz3xRBzAHBYaobxpLEc7kwTptR/hPEa9j93hIfb2Tbe9IA50MViGmjQ6nUF/OVvA==") + cli, err := NewBasicClient(dummyStorageAccount, dummyMiniStorageKey) c.Assert(err, chk.IsNil) headers := map[string]string{ @@ -45,15 +45,15 @@ func (a *AuthorizationSuite) Test_getSharedKey(c *chk.C) { headerXmsVersion: "2015-02-21", "Accept": "application/json;odata=nometadata", } - url := "https://mindgotest.table.core.windows.net/tquery()" + url := "https://golangrocksonazure.table.core.windows.net/tquery()" key, err := cli.getSharedKey("", url, headers, sharedKeyLiteForTable) c.Assert(err, chk.IsNil) - c.Assert(key, chk.Equals, "SharedKeyLite mindgotest:+32DTgsPUgXPo/O7RYaTs0DllA6FTXMj3uK4Qst8y/E=") + c.Assert(key, chk.Equals, "SharedKeyLite golangrocksonazure:NusXSFXAvHqr6EQNXnZZ50CvU1sX0iP/FFDHehnixLc=") } func (a *AuthorizationSuite) Test_buildCanonicalizedResource(c *chk.C) { - cli, err := NewBasicClient("foo", "YmFy") + cli, err := NewBasicClient(dummyStorageAccount, dummyMiniStorageKey) c.Assert(err, chk.IsNil) type test struct { @@ -63,19 +63,19 @@ func (a *AuthorizationSuite) Test_buildCanonicalizedResource(c *chk.C) { } tests := []test{ // Shared Key - {"https://foo.blob.core.windows.net/path?a=b&c=d", sharedKey, "/foo/path\na:b\nc:d"}, - {"https://foo.blob.core.windows.net/?comp=list", sharedKey, "/foo/\ncomp:list"}, - {"https://foo.blob.core.windows.net/cnt/blob", sharedKey, "/foo/cnt/blob"}, - {"https://foo.blob.core.windows.net/cnt/bl ob", sharedKey, "/foo/cnt/bl%20ob"}, - {"https://foo.blob.core.windows.net/c nt/blob", sharedKey, "/foo/c%20nt/blob"}, - {"https://foo.blob.core.windows.net/cnt/blob%3F%23%5B%5D%21$&%27%28%29%2A blob", sharedKey, "/foo/cnt/blob%3F%23%5B%5D%21$&%27%28%29%2A%20blob"}, - {"https://foo.blob.core.windows.net/cnt/blob-._~:,@;+=blob", sharedKey, "/foo/cnt/blob-._~:,@;+=blob"}, - {"https://foo.blob.core.windows.net/c nt/blob-._~:%3F%23%5B%5D@%21$&%27%28%29%2A,;+=/blob", sharedKey, "/foo/c%20nt/blob-._~:%3F%23%5B%5D@%21$&%27%28%29%2A,;+=/blob"}, + {"https://golangrocksonazure.blob.core.windows.net/path?a=b&c=d", sharedKey, "/golangrocksonazure/path\na:b\nc:d"}, + {"https://golangrocksonazure.blob.core.windows.net/?comp=list", sharedKey, "/golangrocksonazure/\ncomp:list"}, + {"https://golangrocksonazure.blob.core.windows.net/cnt/blob", sharedKey, "/golangrocksonazure/cnt/blob"}, + {"https://golangrocksonazure.blob.core.windows.net/cnt/bl ob", sharedKey, "/golangrocksonazure/cnt/bl%20ob"}, + {"https://golangrocksonazure.blob.core.windows.net/c nt/blob", sharedKey, "/golangrocksonazure/c%20nt/blob"}, + {"https://golangrocksonazure.blob.core.windows.net/cnt/blob%3F%23%5B%5D%21$&%27%28%29%2A blob", sharedKey, "/golangrocksonazure/cnt/blob%3F%23%5B%5D%21$&%27%28%29%2A%20blob"}, + {"https://golangrocksonazure.blob.core.windows.net/cnt/blob-._~:,@;+=blob", sharedKey, "/golangrocksonazure/cnt/blob-._~:,@;+=blob"}, + {"https://golangrocksonazure.blob.core.windows.net/c nt/blob-._~:%3F%23%5B%5D@%21$&%27%28%29%2A,;+=/blob", sharedKey, "/golangrocksonazure/c%20nt/blob-._~:%3F%23%5B%5D@%21$&%27%28%29%2A,;+=/blob"}, // Shared Key Lite for Table - {"https://foo.table.core.windows.net/mytable", sharedKeyLiteForTable, "/foo/mytable"}, - {"https://foo.table.core.windows.net/mytable?comp=acl", sharedKeyLiteForTable, "/foo/mytable?comp=acl"}, - {"https://foo.table.core.windows.net/mytable?comp=acl&timeout=10", sharedKeyForTable, "/foo/mytable?comp=acl"}, - {"https://foo.table.core.windows.net/mytable(PartitionKey='pkey',RowKey='rowkey%3D')", sharedKeyForTable, "/foo/mytable(PartitionKey='pkey',RowKey='rowkey%3D')"}, + {"https://golangrocksonazure.table.core.windows.net/mytable", sharedKeyLiteForTable, "/golangrocksonazure/mytable"}, + {"https://golangrocksonazure.table.core.windows.net/mytable?comp=acl", sharedKeyLiteForTable, "/golangrocksonazure/mytable?comp=acl"}, + {"https://golangrocksonazure.table.core.windows.net/mytable?comp=acl&timeout=10", sharedKeyForTable, "/golangrocksonazure/mytable?comp=acl"}, + {"https://golangrocksonazure.table.core.windows.net/mytable(PartitionKey='pkey',RowKey='rowkey%3D')", sharedKeyForTable, "/golangrocksonazure/mytable(PartitionKey='pkey',RowKey='rowkey%3D')"}, } for _, t := range tests { @@ -156,15 +156,15 @@ func (a *AuthorizationSuite) Test_buildCanonicalizedHeader(c *chk.C) { {map[string]string{}, ""}, {map[string]string{ - "x-ms-foo": "bar"}, - "x-ms-foo:bar"}, + "x-ms-lol": "rofl"}, + "x-ms-lol:rofl"}, {map[string]string{ - "foo:": "bar"}, + "lol:": "rofl"}, ""}, {map[string]string{ - "foo:": "bar", - "x-ms-foo": "bar"}, - "x-ms-foo:bar"}, + "lol:": "rofl", + "x-ms-lol": "rofl"}, + "x-ms-lol:rofl"}, {map[string]string{ "x-ms-version": "9999-99-99", "x-ms-blob-type": "BlockBlob"}, @@ -176,38 +176,39 @@ func (a *AuthorizationSuite) Test_buildCanonicalizedHeader(c *chk.C) { } func (a *AuthorizationSuite) Test_createAuthorizationHeader(c *chk.C) { - cli, err := NewBasicClient("foo", base64.StdEncoding.EncodeToString([]byte("bar"))) + cli, err := NewBasicClient(dummyStorageAccount, base64.StdEncoding.EncodeToString([]byte("bar"))) c.Assert(err, chk.IsNil) canonicalizedString := `foobarzoo` c.Assert(cli.createAuthorizationHeader(canonicalizedString, sharedKey), - chk.Equals, `SharedKey foo:h5U0ATVX6SpbFX1H6GNuxIMeXXCILLoIvhflPtuQZ30=`) + chk.Equals, `SharedKey golangrocksonazure:h5U0ATVX6SpbFX1H6GNuxIMeXXCILLoIvhflPtuQZ30=`) c.Assert(cli.createAuthorizationHeader(canonicalizedString, sharedKeyLite), - chk.Equals, `SharedKeyLite foo:h5U0ATVX6SpbFX1H6GNuxIMeXXCILLoIvhflPtuQZ30=`) + chk.Equals, `SharedKeyLite golangrocksonazure:h5U0ATVX6SpbFX1H6GNuxIMeXXCILLoIvhflPtuQZ30=`) } func (a *AuthorizationSuite) Test_allSharedKeys(c *chk.C) { cli := getBasicClient(c) + rec := cli.appendRecorder(c) + defer rec.Stop() blobCli := cli.GetBlobService() tableCli := cli.GetTableService() - cnt1 := blobCli.GetContainerReference(randContainer()) - cnt2 := blobCli.GetContainerReference(randContainer()) - - tn1 := AzureTable(randTable()) - tn2 := AzureTable(randTable()) + cnt1 := blobCli.GetContainerReference(containerName(c, "1")) + cnt2 := blobCli.GetContainerReference(containerName(c, "2")) // Shared Key c.Assert(blobCli.auth, chk.Equals, sharedKey) - c.Assert(cnt1.Create(), chk.IsNil) - c.Assert(cnt1.Delete(), chk.IsNil) + c.Assert(cnt1.Create(nil), chk.IsNil) + c.Assert(cnt1.Delete(nil), chk.IsNil) // Shared Key for Tables c.Assert(tableCli.auth, chk.Equals, sharedKeyForTable) - c.Assert(tableCli.CreateTable(tn1), chk.IsNil) - c.Assert(tableCli.DeleteTable(tn1), chk.IsNil) + table1 := tableCli.GetTableReference(tableName(c, "1")) + c.Assert(table1.tsc.auth, chk.Equals, sharedKeyForTable) + c.Assert(table1.Create(30, EmptyPayload, nil), chk.IsNil) + c.Assert(table1.Delete(30, nil), chk.IsNil) // Change to Lite cli.UseSharedKeyLite = true @@ -216,11 +217,14 @@ func (a *AuthorizationSuite) Test_allSharedKeys(c *chk.C) { // Shared Key Lite c.Assert(blobCli.auth, chk.Equals, sharedKeyLite) - c.Assert(cnt2.Create(), chk.IsNil) - c.Assert(cnt2.Delete(), chk.IsNil) + c.Assert(cnt2.Create(nil), chk.IsNil) + c.Assert(cnt2.Delete(nil), chk.IsNil) // Shared Key Lite for Tables + tableCli = cli.GetTableService() c.Assert(tableCli.auth, chk.Equals, sharedKeyLiteForTable) - c.Assert(tableCli.CreateTable(tn2), chk.IsNil) - c.Assert(tableCli.DeleteTable(tn2), chk.IsNil) + table2 := tableCli.GetTableReference(tableName(c, "2")) + c.Assert(table2.tsc.auth, chk.Equals, sharedKeyLiteForTable) + c.Assert(table2.Create(30, EmptyPayload, nil), chk.IsNil) + c.Assert(table2.Delete(30, nil), chk.IsNil) } diff --git a/storage/blob.go b/storage/blob.go index 6b332ea41eeb..dd9eb386cb5a 100644 --- a/storage/blob.go +++ b/storage/blob.go @@ -1,7 +1,6 @@ package storage import ( - "bytes" "encoding/xml" "errors" "fmt" @@ -15,11 +14,26 @@ import ( // A Blob is an entry in BlobListResponse. type Blob struct { + Container *Container Name string `xml:"Name"` + Snapshot time.Time `xml:"Snapshot"` Properties BlobProperties `xml:"Properties"` Metadata BlobMetadata `xml:"Metadata"` } +// PutBlobOptions includes the options any put blob operation +// (page, block, append) +type PutBlobOptions struct { + Timeout uint + LeaseID string `header:"x-ms-lease-id"` + Origin string `header:"Origin"` + 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"` +} + // BlobMetadata is a set of custom name/value pairs. // // See https://msdn.microsoft.com/en-us/library/azure/dd179404.aspx @@ -67,34 +81,28 @@ func (bm BlobMetadata) MarshalXML(enc *xml.Encoder, start xml.StartElement) erro // BlobProperties contains various properties of a blob // returned in various endpoints like ListBlobs or GetBlobProperties. type BlobProperties struct { - LastModified string `xml:"Last-Modified"` - Etag string `xml:"Etag"` - ContentMD5 string `xml:"Content-MD5"` - ContentLength int64 `xml:"Content-Length"` - ContentType string `xml:"Content-Type"` - ContentEncoding string `xml:"Content-Encoding"` - CacheControl string `xml:"Cache-Control"` - ContentLanguage string `xml:"Cache-Language"` - BlobType BlobType `xml:"x-ms-blob-blob-type"` - SequenceNumber int64 `xml:"x-ms-blob-sequence-number"` - CopyID string `xml:"CopyId"` - CopyStatus string `xml:"CopyStatus"` - CopySource string `xml:"CopySource"` - CopyProgress string `xml:"CopyProgress"` - CopyCompletionTime string `xml:"CopyCompletionTime"` - CopyStatusDescription string `xml:"CopyStatusDescription"` - LeaseStatus string `xml:"LeaseStatus"` - LeaseState string `xml:"LeaseState"` -} - -// BlobHeaders contains various properties of a blob and is an entry -// in SetBlobProperties -type BlobHeaders struct { - ContentMD5 string `header:"x-ms-blob-content-md5"` - ContentLanguage string `header:"x-ms-blob-content-language"` - ContentEncoding string `header:"x-ms-blob-content-encoding"` - ContentType string `header:"x-ms-blob-content-type"` - CacheControl string `header:"x-ms-blob-cache-control"` + LastModified TimeRFC1123 `xml:"Last-Modified"` + Etag string `xml:"Etag"` + ContentMD5 string `xml:"Content-MD5" header:"x-ms-blob-content-md5"` + ContentLength int64 `xml:"Content-Length"` + ContentType string `xml:"Content-Type" header:"x-ms-blob-content-type"` + ContentEncoding string `xml:"Content-Encoding" header:"x-ms-blob-content-encoding"` + CacheControl string `xml:"Cache-Control" header:"x-ms-blob-cache-control"` + ContentLanguage string `xml:"Cache-Language" header:"x-ms-blob-content-language"` + ContentDisposition string `xml:"Content-Disposition" header:"x-ms-blob-content-disposition"` + BlobType BlobType `xml:"x-ms-blob-blob-type"` + SequenceNumber int64 `xml:"x-ms-blob-sequence-number"` + CopyID string `xml:"CopyId"` + CopyStatus string `xml:"CopyStatus"` + CopySource string `xml:"CopySource"` + CopyProgress string `xml:"CopyProgress"` + CopyCompletionTime TimeRFC1123 `xml:"CopyCompletionTime"` + CopyStatusDescription string `xml:"CopyStatusDescription"` + LeaseStatus string `xml:"LeaseStatus"` + LeaseState string `xml:"LeaseState"` + LeaseDuration string `xml:"LeaseDuration"` + ServerEncrypted bool `xml:"ServerEncrypted"` + IncrementalCopy bool `xml:"IncrementalCopy"` } // BlobType defines the type of the Azure Blob. @@ -107,123 +115,16 @@ const ( BlobTypeAppend BlobType = "AppendBlob" ) -// PageWriteType defines the type updates that are going to be -// done on the page blob. -type PageWriteType string - -// Types of operations on page blobs -const ( - PageWriteTypeUpdate PageWriteType = "update" - PageWriteTypeClear PageWriteType = "clear" -) - -const ( - blobCopyStatusPending = "pending" - blobCopyStatusSuccess = "success" - blobCopyStatusAborted = "aborted" - blobCopyStatusFailed = "failed" -) - -// lease constants. -const ( - leaseHeaderPrefix = "x-ms-lease-" - headerLeaseID = "x-ms-lease-id" - leaseAction = "x-ms-lease-action" - leaseBreakPeriod = "x-ms-lease-break-period" - leaseDuration = "x-ms-lease-duration" - leaseProposedID = "x-ms-proposed-lease-id" - leaseTime = "x-ms-lease-time" - - acquireLease = "acquire" - renewLease = "renew" - changeLease = "change" - releaseLease = "release" - breakLease = "break" -) - -// BlockListType is used to filter out types of blocks in a Get Blocks List call -// for a block blob. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179400.aspx for all -// block types. -type BlockListType string - -// Filters for listing blocks in block blobs -const ( - BlockListTypeAll BlockListType = "all" - BlockListTypeCommitted BlockListType = "committed" - BlockListTypeUncommitted BlockListType = "uncommitted" -) - -// Maximum sizes (per REST API) for various concepts -const ( - MaxBlobBlockSize = 4 * 1024 * 1024 - MaxBlobPageSize = 4 * 1024 * 1024 -) - -// BlockStatus defines states a block for a block blob can -// be in. -type BlockStatus string - -// List of statuses that can be used to refer to a block in a block list -const ( - BlockStatusUncommitted BlockStatus = "Uncommitted" - BlockStatusCommitted BlockStatus = "Committed" - BlockStatusLatest BlockStatus = "Latest" -) - -// Block is used to create Block entities for Put Block List -// call. -type Block struct { - ID string - Status BlockStatus +func (b *Blob) buildPath() string { + return b.Container.buildPath() + "/" + b.Name } -// BlockListResponse contains the response fields from Get Block List call. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179400.aspx -type BlockListResponse struct { - XMLName xml.Name `xml:"BlockList"` - CommittedBlocks []BlockResponse `xml:"CommittedBlocks>Block"` - UncommittedBlocks []BlockResponse `xml:"UncommittedBlocks>Block"` -} - -// BlockResponse contains the block information returned -// in the GetBlockListCall. -type BlockResponse struct { - Name string `xml:"Name"` - Size int64 `xml:"Size"` -} - -// GetPageRangesResponse contains the response fields from -// Get Page Ranges call. -// -// See https://msdn.microsoft.com/en-us/library/azure/ee691973.aspx -type GetPageRangesResponse struct { - XMLName xml.Name `xml:"PageList"` - PageList []PageRange `xml:"PageRange"` -} - -// PageRange contains information about a page of a page blob from -// Get Pages Range call. -// -// See https://msdn.microsoft.com/en-us/library/azure/ee691973.aspx -type PageRange struct { - Start int64 `xml:"Start"` - End int64 `xml:"End"` -} - -var ( - errBlobCopyAborted = errors.New("storage: blob copy is aborted") - errBlobCopyIDMismatch = errors.New("storage: blob copy id is a mismatch") -) - -// BlobExists returns true if a blob with given name exists on the specified +// Exists returns true if a blob with given name exists on the specified // container of the storage account. -func (b BlobStorageClient) BlobExists(container, name string) (bool, error) { - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) - headers := b.client.getStandardHeaders() - resp, err := b.client.exec(http.MethodHead, uri, headers, nil, b.auth) +func (b *Blob) Exists() (bool, error) { + uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), nil) + headers := b.Container.bsc.client.getStandardHeaders() + resp, err := b.Container.bsc.client.exec(http.MethodHead, uri, headers, nil, b.Container.bsc.auth) if resp != nil { defer readAndCloseBody(resp.body) if resp.statusCode == http.StatusOK || resp.statusCode == http.StatusNotFound { @@ -233,24 +134,57 @@ func (b BlobStorageClient) BlobExists(container, name string) (bool, error) { return false, err } -// GetBlobURL gets the canonical URL to the blob with the specified name in the +// GetURL gets the canonical URL to the blob with the specified name in the // specified container. If name is not specified, the canonical URL for the entire // container is obtained. // This method does not create a publicly accessible URL if the blob or container // is private and this method does not check if the blob exists. -func (b BlobStorageClient) GetBlobURL(container, name string) string { +func (b *Blob) GetURL() string { + container := b.Container.Name if container == "" { container = "$root" } - return b.client.getEndpoint(blobServiceName, pathForResource(container, name), url.Values{}) + return b.Container.bsc.client.getEndpoint(blobServiceName, pathForResource(container, b.Name), nil) } -// GetBlob returns a stream to read the blob. Caller must call Close() the -// reader to close on the underlying connection. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179440.aspx -func (b BlobStorageClient) GetBlob(container, name string) (io.ReadCloser, error) { - resp, err := b.getBlobRange(container, name, "", nil) +// GetBlobRangeOptions includes the options for a get blob range operation +type GetBlobRangeOptions struct { + Range *BlobRange + GetRangeContentMD5 bool + *GetBlobOptions +} + +// GetBlobOptions includes the options for a get blob operation +type GetBlobOptions struct { + Timeout uint + Snapshot *time.Time + LeaseID string `header:"x-ms-lease-id"` + Origin string `header:"Origin"` + 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"` +} + +// BlobRange represents the bytes range to be get +type BlobRange struct { + Start uint64 + End uint64 +} + +func (br BlobRange) String() string { + return fmt.Sprintf("bytes=%d-%d", br.Start, br.End) +} + +// Get returns a stream to read the blob. Caller must call both Read and Close() +// to correctly close the underlying connection. +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Get-Blob +func (b *Blob) Get(options *GetBlobOptions) (io.ReadCloser, error) { + rangeOptions := GetBlobRangeOptions{ + GetBlobOptions: options, + } + resp, err := b.getRange(&rangeOptions) if err != nil { return nil, err } @@ -258,15 +192,19 @@ func (b BlobStorageClient) GetBlob(container, name string) (io.ReadCloser, error if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { return nil, err } + if err := b.writePropoerties(resp.headers); err != nil { + return resp.body, err + } return resp.body, nil } -// GetBlobRange reads the specified range of a blob to a stream. The bytesRange +// GetRange reads the specified range of a blob to a stream. The bytesRange // string must be in a format like "0-", "10-100" as defined in HTTP 1.1 spec. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179440.aspx -func (b BlobStorageClient) GetBlobRange(container, name, bytesRange string, extraHeaders map[string]string) (io.ReadCloser, error) { - resp, err := b.getBlobRange(container, name, bytesRange, extraHeaders) +// Caller must call both Read and Close()// to correctly close the underlying +// connection. +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Get-Blob +func (b *Blob) GetRange(options *GetBlobRangeOptions) (io.ReadCloser, error) { + resp, err := b.getRange(options) if err != nil { return nil, err } @@ -274,67 +212,64 @@ func (b BlobStorageClient) GetBlobRange(container, name, bytesRange string, extr if err := checkRespCode(resp.statusCode, []int{http.StatusPartialContent}); err != nil { return nil, err } + if err := b.writePropoerties(resp.headers); err != nil { + return resp.body, err + } return resp.body, nil } -func (b BlobStorageClient) getBlobRange(container, name, bytesRange string, extraHeaders map[string]string) (*storageResponse, error) { - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) +func (b *Blob) getRange(options *GetBlobRangeOptions) (*storageResponse, error) { + params := url.Values{} + headers := b.Container.bsc.client.getStandardHeaders() - extraHeaders = b.client.protectUserAgent(extraHeaders) - headers := b.client.getStandardHeaders() - if bytesRange != "" { - headers["Range"] = fmt.Sprintf("bytes=%s", bytesRange) - } - - for k, v := range extraHeaders { - headers[k] = v + if options != nil { + if options.Range != nil { + headers["Range"] = options.Range.String() + headers["x-ms-range-get-content-md5"] = fmt.Sprintf("%v", options.GetRangeContentMD5) + } + if options.GetBlobOptions != nil { + headers = mergeHeaders(headers, headersFromStruct(*options.GetBlobOptions)) + params = addTimeout(params, options.Timeout) + params = addSnapshot(params, options.Snapshot) + } } + uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), params) - resp, err := b.client.exec(http.MethodGet, uri, headers, nil, b.auth) + resp, err := b.Container.bsc.client.exec(http.MethodGet, uri, headers, nil, b.Container.bsc.auth) if err != nil { return nil, err } return resp, err } -// leasePut is common PUT code for the various acquire/release/break etc functions. -func (b BlobStorageClient) leaseCommonPut(container string, name string, headers map[string]string, expectedStatus int) (http.Header, error) { - params := url.Values{"comp": {"lease"}} - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) - - resp, err := b.client.exec(http.MethodPut, uri, headers, nil, b.auth) - if err != nil { - return nil, err - } - defer readAndCloseBody(resp.body) - - if err := checkRespCode(resp.statusCode, []int{expectedStatus}); err != nil { - return nil, err - } - - return resp.headers, nil +// SnapshotOptions includes the options for a snapshot blob operation +type SnapshotOptions struct { + Timeout uint + LeaseID string `header:"x-ms-lease-id"` + 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"` } -// SnapshotBlob creates a snapshot for a blob as per https://msdn.microsoft.com/en-us/library/azure/ee691971.aspx -func (b BlobStorageClient) SnapshotBlob(container string, name string, timeout int, extraHeaders map[string]string) (snapshotTimestamp *time.Time, err error) { - extraHeaders = b.client.protectUserAgent(extraHeaders) - headers := b.client.getStandardHeaders() +// CreateSnapshot creates a snapshot for a blob +// See https://msdn.microsoft.com/en-us/library/azure/ee691971.aspx +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) - if timeout > 0 { - params.Add("timeout", strconv.Itoa(timeout)) - } - - for k, v := range extraHeaders { - headers[k] = v + if options != nil { + params = addTimeout(params, options.Timeout) + headers = mergeHeaders(headers, headersFromStruct(*options)) } + uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), params) - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) - resp, err := b.client.exec(http.MethodPut, uri, headers, nil, b.auth) + resp, err := b.Container.bsc.client.exec(http.MethodPut, uri, headers, nil, b.Container.bsc.auth) if err != nil || resp == nil { return nil, err } - defer readAndCloseBody(resp.body) if err := checkRespCode(resp.statusCode, []int{http.StatusCreated}); err != nil { @@ -347,220 +282,178 @@ func (b BlobStorageClient) SnapshotBlob(container string, name string, timeout i if err != nil { return nil, err } - return &snapshotTimestamp, nil } return nil, errors.New("Snapshot not created") } -// AcquireLease creates a lease for a blob as per https://msdn.microsoft.com/en-us/library/azure/ee691972.aspx -// returns leaseID acquired -// In API Versions starting on 2012-02-12, the minimum leaseTimeInSeconds is 15, the maximum -// non-infinite leaseTimeInSeconds is 60. To specify an infinite lease, provide the value -1. -func (b BlobStorageClient) AcquireLease(container string, name string, leaseTimeInSeconds int, proposedLeaseID string) (returnedLeaseID string, err error) { - headers := b.client.getStandardHeaders() - headers[leaseAction] = acquireLease - - if leaseTimeInSeconds == -1 { - // Do nothing, but don't trigger the following clauses. - } else if leaseTimeInSeconds > 60 || b.client.apiVersion < "2012-02-12" { - leaseTimeInSeconds = 60 - } else if leaseTimeInSeconds < 15 { - leaseTimeInSeconds = 15 - } - - headers[leaseDuration] = strconv.Itoa(leaseTimeInSeconds) - - if proposedLeaseID != "" { - headers[leaseProposedID] = proposedLeaseID - } - - respHeaders, err := b.leaseCommonPut(container, name, headers, http.StatusCreated) - if err != nil { - return "", err - } - - returnedLeaseID = respHeaders.Get(http.CanonicalHeaderKey(headerLeaseID)) - - if returnedLeaseID != "" { - return returnedLeaseID, nil - } - - return "", errors.New("LeaseID not returned") -} - -// BreakLease breaks the lease for a blob as per https://msdn.microsoft.com/en-us/library/azure/ee691972.aspx -// Returns the timeout remaining in the lease in seconds -func (b BlobStorageClient) BreakLease(container string, name string) (breakTimeout int, err error) { - headers := b.client.getStandardHeaders() - headers[leaseAction] = breakLease - return b.breakLeaseCommon(container, name, headers) -} - -// BreakLeaseWithBreakPeriod breaks the lease for a blob as per https://msdn.microsoft.com/en-us/library/azure/ee691972.aspx -// breakPeriodInSeconds is used to determine how long until new lease can be created. -// Returns the timeout remaining in the lease in seconds -func (b BlobStorageClient) BreakLeaseWithBreakPeriod(container string, name string, breakPeriodInSeconds int) (breakTimeout int, err error) { - headers := b.client.getStandardHeaders() - headers[leaseAction] = breakLease - headers[leaseBreakPeriod] = strconv.Itoa(breakPeriodInSeconds) - return b.breakLeaseCommon(container, name, headers) +// GetBlobPropertiesOptions includes the options for a get blob properties operation +type GetBlobPropertiesOptions struct { + Timeout uint + Snapshot *time.Time + LeaseID string `header:"x-ms-lease-id"` + 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"` } -// breakLeaseCommon is common code for both version of BreakLease (with and without break period) -func (b BlobStorageClient) breakLeaseCommon(container string, name string, headers map[string]string) (breakTimeout int, err error) { +// GetProperties provides various information about the specified blob. +// See https://msdn.microsoft.com/en-us/library/azure/dd179394.aspx +func (b *Blob) GetProperties(options *GetBlobPropertiesOptions) error { + params := url.Values{} + headers := b.Container.bsc.client.getStandardHeaders() - respHeaders, err := b.leaseCommonPut(container, name, headers, http.StatusAccepted) - if err != nil { - return 0, err - } - - breakTimeoutStr := respHeaders.Get(http.CanonicalHeaderKey(leaseTime)) - if breakTimeoutStr != "" { - breakTimeout, err = strconv.Atoi(breakTimeoutStr) - if err != nil { - return 0, err - } + if options != nil { + params = addTimeout(params, options.Timeout) + params = addSnapshot(params, options.Snapshot) + headers = mergeHeaders(headers, headersFromStruct(*options)) } + uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), params) - return breakTimeout, nil -} - -// ChangeLease changes a lease ID for a blob as per https://msdn.microsoft.com/en-us/library/azure/ee691972.aspx -// Returns the new LeaseID acquired -func (b BlobStorageClient) ChangeLease(container string, name string, currentLeaseID string, proposedLeaseID string) (newLeaseID string, err error) { - headers := b.client.getStandardHeaders() - headers[leaseAction] = changeLease - headers[headerLeaseID] = currentLeaseID - headers[leaseProposedID] = proposedLeaseID - - respHeaders, err := b.leaseCommonPut(container, name, headers, http.StatusOK) - if err != nil { - return "", err - } - - newLeaseID = respHeaders.Get(http.CanonicalHeaderKey(headerLeaseID)) - if newLeaseID != "" { - return newLeaseID, nil - } - - return "", errors.New("LeaseID not returned") -} - -// ReleaseLease releases the lease for a blob as per https://msdn.microsoft.com/en-us/library/azure/ee691972.aspx -func (b BlobStorageClient) ReleaseLease(container string, name string, currentLeaseID string) error { - headers := b.client.getStandardHeaders() - headers[leaseAction] = releaseLease - headers[headerLeaseID] = currentLeaseID - - _, err := b.leaseCommonPut(container, name, headers, http.StatusOK) + resp, err := b.Container.bsc.client.exec(http.MethodHead, uri, headers, nil, b.Container.bsc.auth) if err != nil { return err } + defer readAndCloseBody(resp.body) - return nil -} - -// RenewLease renews the lease for a blob as per https://msdn.microsoft.com/en-us/library/azure/ee691972.aspx -func (b BlobStorageClient) RenewLease(container string, name string, currentLeaseID string) error { - headers := b.client.getStandardHeaders() - headers[leaseAction] = renewLease - headers[headerLeaseID] = currentLeaseID - - _, err := b.leaseCommonPut(container, name, headers, http.StatusOK) - if err != nil { + if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { return err } - - return nil + return b.writePropoerties(resp.headers) } -// GetBlobProperties provides various information about the specified -// blob. See https://msdn.microsoft.com/en-us/library/azure/dd179394.aspx -func (b BlobStorageClient) GetBlobProperties(container, name string) (*BlobProperties, error) { - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) - - headers := b.client.getStandardHeaders() - resp, err := b.client.exec(http.MethodHead, uri, headers, nil, b.auth) - if err != nil { - return nil, err - } - defer readAndCloseBody(resp.body) - - if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { - return nil, err - } +func (b *Blob) writePropoerties(h http.Header) error { + var err error var contentLength int64 - contentLengthStr := resp.headers.Get("Content-Length") + contentLengthStr := h.Get("Content-Length") if contentLengthStr != "" { contentLength, err = strconv.ParseInt(contentLengthStr, 0, 64) if err != nil { - return nil, err + return err } } var sequenceNum int64 - sequenceNumStr := resp.headers.Get("x-ms-blob-sequence-number") + sequenceNumStr := h.Get("x-ms-blob-sequence-number") if sequenceNumStr != "" { sequenceNum, err = strconv.ParseInt(sequenceNumStr, 0, 64) if err != nil { - return nil, err + return err } } - return &BlobProperties{ - LastModified: resp.headers.Get("Last-Modified"), - Etag: resp.headers.Get("Etag"), - ContentMD5: resp.headers.Get("Content-MD5"), + lastModified, err := getTimeFromHeaders(h, "Last-Modified") + if err != nil { + return err + } + + copyCompletionTime, err := getTimeFromHeaders(h, "x-ms-copy-completion-time") + if err != nil { + return err + } + + b.Properties = BlobProperties{ + LastModified: TimeRFC1123(*lastModified), + Etag: h.Get("Etag"), + ContentMD5: h.Get("Content-MD5"), ContentLength: contentLength, - ContentEncoding: resp.headers.Get("Content-Encoding"), - ContentType: resp.headers.Get("Content-Type"), - CacheControl: resp.headers.Get("Cache-Control"), - ContentLanguage: resp.headers.Get("Content-Language"), + ContentEncoding: h.Get("Content-Encoding"), + ContentType: h.Get("Content-Type"), + ContentDisposition: h.Get("Content-Disposition"), + CacheControl: h.Get("Cache-Control"), + ContentLanguage: h.Get("Content-Language"), SequenceNumber: sequenceNum, - CopyCompletionTime: resp.headers.Get("x-ms-copy-completion-time"), - CopyStatusDescription: resp.headers.Get("x-ms-copy-status-description"), - CopyID: resp.headers.Get("x-ms-copy-id"), - CopyProgress: resp.headers.Get("x-ms-copy-progress"), - CopySource: resp.headers.Get("x-ms-copy-source"), - CopyStatus: resp.headers.Get("x-ms-copy-status"), - BlobType: BlobType(resp.headers.Get("x-ms-blob-type")), - LeaseStatus: resp.headers.Get("x-ms-lease-status"), - LeaseState: resp.headers.Get("x-ms-lease-state"), - }, nil + CopyCompletionTime: TimeRFC1123(*copyCompletionTime), + CopyStatusDescription: h.Get("x-ms-copy-status-description"), + CopyID: h.Get("x-ms-copy-id"), + CopyProgress: h.Get("x-ms-copy-progress"), + CopySource: h.Get("x-ms-copy-source"), + CopyStatus: h.Get("x-ms-copy-status"), + BlobType: BlobType(h.Get("x-ms-blob-type")), + LeaseStatus: h.Get("x-ms-lease-status"), + LeaseState: h.Get("x-ms-lease-state"), + } + b.writeMetadata(h) + return nil } -// SetBlobProperties replaces the BlobHeaders for the specified blob. +// SetBlobPropertiesOptions contains various properties of a blob and is an entry +// in SetProperties +type SetBlobPropertiesOptions struct { + Timeout uint + LeaseID string `header:"x-ms-lease-id"` + Origin string `header:"Origin"` + 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"` + SequenceNumberAction *SequenceNumberAction + RequestID string `header:"x-ms-client-request-id"` +} + +// SequenceNumberAction defines how the blob's sequence number should be modified +type SequenceNumberAction string + +// Options for sequence number action +const ( + SequenceNumberActionMax SequenceNumberAction = "max" + SequenceNumberActionUpdate SequenceNumberAction = "update" + SequenceNumberActionIncrement SequenceNumberAction = "increment" +) + +// SetProperties replaces the BlobHeaders for the specified blob. // // Some keys may be converted to Camel-Case before sending. All keys // are returned in lower case by GetBlobProperties. HTTP header names // are case-insensitive so case munging should not matter to other // applications either. // -// See https://msdn.microsoft.com/en-us/library/azure/ee691966.aspx -func (b BlobStorageClient) SetBlobProperties(container, name string, blobHeaders BlobHeaders) error { +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Set-Blob-Properties +func (b *Blob) SetProperties(options *SetBlobPropertiesOptions) error { params := url.Values{"comp": {"properties"}} - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) - headers := b.client.getStandardHeaders() - - extraHeaders := headersFromStruct(blobHeaders) - - for k, v := range extraHeaders { - headers[k] = v + headers := b.Container.bsc.client.getStandardHeaders() + headers = mergeHeaders(headers, headersFromStruct(b.Properties)) + + if options != nil { + params = addTimeout(params, options.Timeout) + headers = mergeHeaders(headers, headersFromStruct(*options)) + } + uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), params) + + if b.Properties.BlobType == BlobTypePage { + headers = addToHeaders(headers, "x-ms-blob-content-length", fmt.Sprintf("byte %v", b.Properties.ContentLength)) + if options != nil || options.SequenceNumberAction != nil { + headers = addToHeaders(headers, "x-ms-sequence-number-action", string(*options.SequenceNumberAction)) + if *options.SequenceNumberAction != SequenceNumberActionIncrement { + headers = addToHeaders(headers, "x-ms-blob-sequence-number", fmt.Sprintf("%v", b.Properties.SequenceNumber)) + } + } } - resp, err := b.client.exec(http.MethodPut, uri, headers, nil, b.auth) + resp, err := b.Container.bsc.client.exec(http.MethodPut, uri, headers, nil, b.Container.bsc.auth) if err != nil { return err } - defer readAndCloseBody(resp.body) - + readAndCloseBody(resp.body) return checkRespCode(resp.statusCode, []int{http.StatusOK}) } -// SetBlobMetadata replaces the metadata for the specified blob. +// SetBlobMetadataOptions includes the options for a set blob metadata operation +type SetBlobMetadataOptions struct { + Timeout uint + LeaseID string `header:"x-ms-lease-id"` + 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"` +} + +// SetMetadata replaces the metadata for the specified blob. // // Some keys may be converted to Camel-Case before sending. All keys // are returned in lower case by GetBlobMetadata. HTTP header names @@ -568,52 +461,71 @@ func (b BlobStorageClient) SetBlobProperties(container, name string, blobHeaders // applications either. // // See https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx -func (b BlobStorageClient) SetBlobMetadata(container, name string, metadata map[string]string, extraHeaders map[string]string) error { +func (b *Blob) SetMetadata(options *SetBlobMetadataOptions) error { params := url.Values{"comp": {"metadata"}} - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) - metadata = b.client.protectUserAgent(metadata) - extraHeaders = b.client.protectUserAgent(extraHeaders) - headers := b.client.getStandardHeaders() - for k, v := range metadata { - headers[userDefinedMetadataHeaderPrefix+k] = v - } + headers := b.Container.bsc.client.getStandardHeaders() + headers = b.Container.bsc.client.addMetadataToHeaders(headers, b.Metadata) - for k, v := range extraHeaders { - headers[k] = v + 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.client.exec(http.MethodPut, uri, headers, nil, b.auth) + resp, err := b.Container.bsc.client.exec(http.MethodPut, uri, headers, nil, b.Container.bsc.auth) if err != nil { return err } - defer readAndCloseBody(resp.body) - + readAndCloseBody(resp.body) return checkRespCode(resp.statusCode, []int{http.StatusOK}) } -// GetBlobMetadata returns all user-defined metadata for the specified blob. +// GetBlobMetadataOptions includes the options for a get blob metadata operation +type GetBlobMetadataOptions struct { + Timeout uint + Snapshot *time.Time + LeaseID string `header:"x-ms-lease-id"` + 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"` +} + +// GetMetadata returns all user-defined metadata for the specified blob. // // All metadata keys will be returned in lower case. (HTTP header // names are case-insensitive.) // // See https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx -func (b BlobStorageClient) GetBlobMetadata(container, name string) (map[string]string, error) { +func (b *Blob) GetMetadata(options *GetBlobMetadataOptions) error { params := url.Values{"comp": {"metadata"}} - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) - headers := b.client.getStandardHeaders() + headers := b.Container.bsc.client.getStandardHeaders() + + if options != nil { + params = addTimeout(params, options.Timeout) + params = addSnapshot(params, options.Snapshot) + headers = mergeHeaders(headers, headersFromStruct(*options)) + } + uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), params) - resp, err := b.client.exec(http.MethodGet, uri, headers, nil, b.auth) + resp, err := b.Container.bsc.client.exec(http.MethodGet, uri, headers, nil, b.Container.bsc.auth) if err != nil { - return nil, err + return err } defer readAndCloseBody(resp.body) if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { - return nil, err + return err } + b.writeMetadata(resp.headers) + return nil +} + +func (b *Blob) writeMetadata(h http.Header) { metadata := make(map[string]string) - for k, v := range resp.headers { + for k, v := range h { // Can't trust CanonicalHeaderKey() to munge case // reliably. "_" is allowed in identifiers: // https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx @@ -622,381 +534,51 @@ func (b BlobStorageClient) GetBlobMetadata(container, name string) (map[string]s // ...but "_" is considered invalid by // CanonicalMIMEHeaderKey in // https://golang.org/src/net/textproto/reader.go?s=14615:14659#L542 - // so k can be "X-Ms-Meta-Foo" or "x-ms-meta-foo_bar". + // so k can be "X-Ms-Meta-Lol" or "x-ms-meta-lol_rofl". k = strings.ToLower(k) if len(v) == 0 || !strings.HasPrefix(k, strings.ToLower(userDefinedMetadataHeaderPrefix)) { continue } - // metadata["foo"] = content of the last X-Ms-Meta-Foo header + // metadata["lol"] = content of the last X-Ms-Meta-Lol header k = k[len(userDefinedMetadataHeaderPrefix):] metadata[k] = v[len(v)-1] } - return metadata, nil -} -// CreateBlockBlob initializes an empty block blob with no blocks. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179451.aspx -func (b BlobStorageClient) CreateBlockBlob(container, name string) error { - return b.CreateBlockBlobFromReader(container, name, 0, nil, nil) + b.Metadata = BlobMetadata(metadata) } -// CreateBlockBlobFromReader initializes a block blob using data from -// reader. Size must be the number of bytes read from reader. To -// create an empty blob, use size==0 and reader==nil. -// -// The API rejects requests with size > 64 MiB (but this limit is not -// checked by the SDK). To write a larger blob, use CreateBlockBlob, -// PutBlock, and PutBlockList. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179451.aspx -func (b BlobStorageClient) CreateBlockBlobFromReader(container, name string, size uint64, blob io.Reader, extraHeaders map[string]string) error { - path := fmt.Sprintf("%s/%s", container, name) - uri := b.client.getEndpoint(blobServiceName, path, url.Values{}) - extraHeaders = b.client.protectUserAgent(extraHeaders) - headers := b.client.getStandardHeaders() - headers["x-ms-blob-type"] = string(BlobTypeBlock) - headers["Content-Length"] = fmt.Sprintf("%d", size) - - for k, v := range extraHeaders { - headers[k] = v - } - - resp, err := b.client.exec(http.MethodPut, uri, headers, blob, b.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +// DeleteBlobOptions includes the options for a delete blob operation +type DeleteBlobOptions struct { + Timeout uint + Snapshot *time.Time + LeaseID string `header:"x-ms-lease-id"` + DeleteSnapshots *bool + 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"` } -// PutBlock saves the given data chunk to the specified block blob with -// given ID. -// -// The API rejects chunks larger than 4 MiB (but this limit is not -// checked by the SDK). -// -// See https://msdn.microsoft.com/en-us/library/azure/dd135726.aspx -func (b BlobStorageClient) PutBlock(container, name, blockID string, chunk []byte) error { - return b.PutBlockWithLength(container, name, blockID, uint64(len(chunk)), bytes.NewReader(chunk), nil) -} - -// PutBlockWithLength saves the given data stream of exactly specified size to -// the block blob with given ID. It is an alternative to PutBlocks where data -// comes as stream but the length is known in advance. -// -// The API rejects requests with size > 4 MiB (but this limit is not -// checked by the SDK). -// -// See https://msdn.microsoft.com/en-us/library/azure/dd135726.aspx -func (b BlobStorageClient) PutBlockWithLength(container, name, blockID string, size uint64, blob io.Reader, extraHeaders map[string]string) error { - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{"comp": {"block"}, "blockid": {blockID}}) - extraHeaders = b.client.protectUserAgent(extraHeaders) - headers := b.client.getStandardHeaders() - headers["x-ms-blob-type"] = string(BlobTypeBlock) - headers["Content-Length"] = fmt.Sprintf("%v", size) - - for k, v := range extraHeaders { - headers[k] = v - } - - resp, err := b.client.exec(http.MethodPut, uri, headers, blob, b.auth) - if err != nil { - return err - } - - defer readAndCloseBody(resp.body) - return checkRespCode(resp.statusCode, []int{http.StatusCreated}) -} - -// PutBlockList saves list of blocks to the specified block blob. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179467.aspx -func (b BlobStorageClient) PutBlockList(container, name string, blocks []Block) error { - blockListXML := prepareBlockListRequest(blocks) - - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{"comp": {"blocklist"}}) - headers := b.client.getStandardHeaders() - headers["Content-Length"] = fmt.Sprintf("%v", len(blockListXML)) - - resp, err := b.client.exec(http.MethodPut, uri, headers, strings.NewReader(blockListXML), b.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - return checkRespCode(resp.statusCode, []int{http.StatusCreated}) -} - -// GetBlockList retrieves list of blocks in the specified block blob. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179400.aspx -func (b BlobStorageClient) GetBlockList(container, name string, blockType BlockListType) (BlockListResponse, error) { - params := url.Values{"comp": {"blocklist"}, "blocklisttype": {string(blockType)}} - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) - headers := b.client.getStandardHeaders() - - var out BlockListResponse - resp, err := b.client.exec(http.MethodGet, uri, headers, nil, b.auth) - if err != nil { - return out, err - } - defer resp.body.Close() - - err = xmlUnmarshal(resp.body, &out) - return out, err -} - -// PutPageBlob initializes an empty page blob with specified name and maximum -// size in bytes (size must be aligned to a 512-byte boundary). A page blob must -// be created using this method before writing pages. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179451.aspx -func (b BlobStorageClient) PutPageBlob(container, name string, size int64, extraHeaders map[string]string) error { - path := fmt.Sprintf("%s/%s", container, name) - uri := b.client.getEndpoint(blobServiceName, path, url.Values{}) - extraHeaders = b.client.protectUserAgent(extraHeaders) - headers := b.client.getStandardHeaders() - headers["x-ms-blob-type"] = string(BlobTypePage) - headers["x-ms-blob-content-length"] = fmt.Sprintf("%v", size) - - for k, v := range extraHeaders { - headers[k] = v - } - - resp, err := b.client.exec(http.MethodPut, uri, headers, nil, b.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - - return checkRespCode(resp.statusCode, []int{http.StatusCreated}) -} - -// PutPage writes a range of pages to a page blob or clears the given range. -// In case of 'clear' writes, given chunk is discarded. Ranges must be aligned -// with 512-byte boundaries and chunk must be of size multiplies by 512. -// -// See https://msdn.microsoft.com/en-us/library/ee691975.aspx -func (b BlobStorageClient) PutPage(container, name string, startByte, endByte int64, writeType PageWriteType, chunk []byte, extraHeaders map[string]string) error { - path := fmt.Sprintf("%s/%s", container, name) - uri := b.client.getEndpoint(blobServiceName, path, url.Values{"comp": {"page"}}) - extraHeaders = b.client.protectUserAgent(extraHeaders) - headers := b.client.getStandardHeaders() - headers["x-ms-blob-type"] = string(BlobTypePage) - headers["x-ms-page-write"] = string(writeType) - headers["x-ms-range"] = fmt.Sprintf("bytes=%v-%v", startByte, endByte) - for k, v := range extraHeaders { - headers[k] = v - } - var contentLength int64 - var data io.Reader - if writeType == PageWriteTypeClear { - contentLength = 0 - data = bytes.NewReader([]byte{}) - } else { - contentLength = int64(len(chunk)) - data = bytes.NewReader(chunk) - } - headers["Content-Length"] = fmt.Sprintf("%v", contentLength) - - resp, err := b.client.exec(http.MethodPut, uri, headers, data, b.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - - return checkRespCode(resp.statusCode, []int{http.StatusCreated}) -} - -// GetPageRanges returns the list of valid page ranges for a page blob. -// -// See https://msdn.microsoft.com/en-us/library/azure/ee691973.aspx -func (b BlobStorageClient) GetPageRanges(container, name string) (GetPageRangesResponse, error) { - path := fmt.Sprintf("%s/%s", container, name) - uri := b.client.getEndpoint(blobServiceName, path, url.Values{"comp": {"pagelist"}}) - headers := b.client.getStandardHeaders() - - var out GetPageRangesResponse - resp, err := b.client.exec(http.MethodGet, uri, headers, nil, b.auth) - if err != nil { - return out, err - } - defer resp.body.Close() - - if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { - return out, err - } - err = xmlUnmarshal(resp.body, &out) - return out, err -} - -// PutAppendBlob initializes an empty append blob with specified name. An -// append blob must be created using this method before appending blocks. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179451.aspx -func (b BlobStorageClient) PutAppendBlob(container, name string, extraHeaders map[string]string) error { - path := fmt.Sprintf("%s/%s", container, name) - uri := b.client.getEndpoint(blobServiceName, path, url.Values{}) - extraHeaders = b.client.protectUserAgent(extraHeaders) - headers := b.client.getStandardHeaders() - headers["x-ms-blob-type"] = string(BlobTypeAppend) - - for k, v := range extraHeaders { - headers[k] = v - } - - resp, err := b.client.exec(http.MethodPut, uri, headers, nil, b.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - - return checkRespCode(resp.statusCode, []int{http.StatusCreated}) -} - -// AppendBlock appends a block to an append blob. -// -// See https://msdn.microsoft.com/en-us/library/azure/mt427365.aspx -func (b BlobStorageClient) AppendBlock(container, name string, chunk []byte, extraHeaders map[string]string) error { - path := fmt.Sprintf("%s/%s", container, name) - uri := b.client.getEndpoint(blobServiceName, path, url.Values{"comp": {"appendblock"}}) - extraHeaders = b.client.protectUserAgent(extraHeaders) - headers := b.client.getStandardHeaders() - headers["x-ms-blob-type"] = string(BlobTypeAppend) - headers["Content-Length"] = fmt.Sprintf("%v", len(chunk)) - - for k, v := range extraHeaders { - headers[k] = v - } - - resp, err := b.client.exec(http.MethodPut, uri, headers, bytes.NewReader(chunk), b.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - - return checkRespCode(resp.statusCode, []int{http.StatusCreated}) -} - -// CopyBlob starts a blob copy operation and waits for the operation to -// complete. sourceBlob parameter must be a canonical URL to the blob (can be -// obtained using GetBlobURL method.) There is no SLA on blob copy and therefore -// this helper method works faster on smaller files. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd894037.aspx -func (b BlobStorageClient) CopyBlob(container, name, sourceBlob string) error { - copyID, err := b.StartBlobCopy(container, name, sourceBlob) - if err != nil { - return err - } - - return b.WaitForBlobCopy(container, name, copyID) -} - -// StartBlobCopy starts a blob copy operation. -// sourceBlob parameter must be a canonical URL to the blob (can be -// obtained using GetBlobURL method.) -// -// See https://msdn.microsoft.com/en-us/library/azure/dd894037.aspx -func (b BlobStorageClient) StartBlobCopy(container, name, sourceBlob string) (string, error) { - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) - - headers := b.client.getStandardHeaders() - headers["x-ms-copy-source"] = sourceBlob - - resp, err := b.client.exec(http.MethodPut, uri, headers, nil, b.auth) - if err != nil { - return "", err - } - defer readAndCloseBody(resp.body) - - if err := checkRespCode(resp.statusCode, []int{http.StatusAccepted, http.StatusCreated}); err != nil { - return "", err - } - - copyID := resp.headers.Get("x-ms-copy-id") - if copyID == "" { - return "", errors.New("Got empty copy id header") - } - return copyID, nil -} - -// AbortBlobCopy aborts a BlobCopy which has already been triggered by the StartBlobCopy function. -// copyID is generated from StartBlobCopy function. -// currentLeaseID is required IF the destination blob has an active lease on it. -// As defined in https://msdn.microsoft.com/en-us/library/azure/jj159098.aspx -func (b BlobStorageClient) AbortBlobCopy(container, name, copyID, currentLeaseID string, timeout int) error { - params := url.Values{"comp": {"copy"}, "copyid": {copyID}} - if timeout > 0 { - params.Add("timeout", strconv.Itoa(timeout)) - } - - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) - headers := b.client.getStandardHeaders() - headers["x-ms-copy-action"] = "abort" - - if currentLeaseID != "" { - headers[headerLeaseID] = currentLeaseID - } - - resp, err := b.client.exec(http.MethodPut, uri, headers, nil, b.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - - if err := checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil { - return err - } - - return nil -} - -// WaitForBlobCopy loops until a BlobCopy operation is completed (or fails with error) -func (b BlobStorageClient) WaitForBlobCopy(container, name, copyID string) error { - for { - props, err := b.GetBlobProperties(container, name) - if err != nil { - return err - } - - if props.CopyID != copyID { - return errBlobCopyIDMismatch - } - - switch props.CopyStatus { - case blobCopyStatusSuccess: - return nil - case blobCopyStatusPending: - continue - case blobCopyStatusAborted: - return errBlobCopyAborted - case blobCopyStatusFailed: - return fmt.Errorf("storage: blob copy failed. Id=%s Description=%s", props.CopyID, props.CopyStatusDescription) - default: - return fmt.Errorf("storage: unhandled blob copy status: '%s'", props.CopyStatus) - } - } -} - -// DeleteBlob deletes the given blob from the specified container. +// Delete deletes the given blob from the specified container. // If the blob does not exists at the time of the Delete Blob operation, it -// returns error. See https://msdn.microsoft.com/en-us/library/azure/dd179413.aspx -func (b BlobStorageClient) DeleteBlob(container, name string, extraHeaders map[string]string) error { - resp, err := b.deleteBlob(container, name, extraHeaders) +// returns error. +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Delete-Blob +func (b *Blob) Delete(options *DeleteBlobOptions) error { + resp, err := b.delete(options) if err != nil { return err } - defer readAndCloseBody(resp.body) + readAndCloseBody(resp.body) return checkRespCode(resp.statusCode, []int{http.StatusAccepted}) } -// DeleteBlobIfExists deletes the given blob from the specified container If the +// DeleteIfExists deletes the given blob from the specified container If the // blob is deleted with this call, returns true. Otherwise returns false. // -// See https://msdn.microsoft.com/en-us/library/azure/dd179413.aspx -func (b BlobStorageClient) DeleteBlobIfExists(container, name string, extraHeaders map[string]string) (bool, error) { - resp, err := b.deleteBlob(container, name, extraHeaders) +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Delete-Blob +func (b *Blob) DeleteIfExists(options *DeleteBlobOptions) (bool, error) { + resp, err := b.delete(options) if resp != nil { defer readAndCloseBody(resp.body) if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound { @@ -1006,125 +588,30 @@ func (b BlobStorageClient) DeleteBlobIfExists(container, name string, extraHeade return false, err } -func (b BlobStorageClient) deleteBlob(container, name string, extraHeaders map[string]string) (*storageResponse, error) { - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) - extraHeaders = b.client.protectUserAgent(extraHeaders) - headers := b.client.getStandardHeaders() - for k, v := range extraHeaders { - headers[k] = v +func (b *Blob) delete(options *DeleteBlobOptions) (*storageResponse, error) { + params := url.Values{} + headers := b.Container.bsc.client.getStandardHeaders() + + if options != nil { + params = addTimeout(params, options.Timeout) + params = addSnapshot(params, options.Snapshot) + headers = mergeHeaders(headers, headersFromStruct(*options)) + if options.DeleteSnapshots != nil { + if *options.DeleteSnapshots { + headers["x-ms-delete-snapshots"] = "include" + } else { + headers["x-ms-delete-snapshots"] = "only" + } + } } - - return b.client.exec(http.MethodDelete, uri, headers, nil, b.auth) -} - -// helper method to construct the path to a blob given its container and blob -// name -func pathForBlob(container, name string) string { - return fmt.Sprintf("/%s/%s", container, name) + uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), params) + return b.Container.bsc.client.exec(http.MethodDelete, uri, headers, nil, b.Container.bsc.auth) } // helper method to construct the path to either a blob or container func pathForResource(container, name string) string { - if len(name) > 0 { + if name != "" { return fmt.Sprintf("/%s/%s", container, name) } return fmt.Sprintf("/%s", container) } - -// GetBlobSASURIWithSignedIPAndProtocol creates an URL to the specified blob which contains the Shared -// Access Signature with specified permissions and expiration time. Also includes signedIPRange and allowed protocols. -// If old API version is used but no signedIP is passed (ie empty string) then this should still work. -// We only populate the signedIP when it non-empty. -// -// See https://msdn.microsoft.com/en-us/library/azure/ee395415.aspx -func (b BlobStorageClient) GetBlobSASURIWithSignedIPAndProtocol(container, name string, expiry time.Time, permissions string, signedIPRange string, HTTPSOnly bool) (string, error) { - var ( - signedPermissions = permissions - blobURL = b.GetBlobURL(container, name) - ) - canonicalizedResource, err := b.client.buildCanonicalizedResource(blobURL, b.auth) - if err != nil { - return "", err - } - - // "The canonicalizedresouce portion of the string is a canonical path to the signed resource. - // It must include the service name (blob, table, queue or file) for version 2015-02-21 or - // later, the storage account name, and the resource name, and must be URL-decoded. - // -- https://msdn.microsoft.com/en-us/library/azure/dn140255.aspx - - // We need to replace + with %2b first to avoid being treated as a space (which is correct for query strings, but not the path component). - canonicalizedResource = strings.Replace(canonicalizedResource, "+", "%2b", -1) - canonicalizedResource, err = url.QueryUnescape(canonicalizedResource) - if err != nil { - return "", err - } - - signedExpiry := expiry.UTC().Format(time.RFC3339) - - //If blob name is missing, resource is a container - signedResource := "c" - if len(name) > 0 { - signedResource = "b" - } - - protocols := "https,http" - if HTTPSOnly { - protocols = "https" - } - stringToSign, err := blobSASStringToSign(b.client.apiVersion, canonicalizedResource, signedExpiry, signedPermissions, signedIPRange, protocols) - if err != nil { - return "", err - } - - sig := b.client.computeHmac256(stringToSign) - sasParams := url.Values{ - "sv": {b.client.apiVersion}, - "se": {signedExpiry}, - "sr": {signedResource}, - "sp": {signedPermissions}, - "sig": {sig}, - } - - if b.client.apiVersion >= "2015-04-05" { - sasParams.Add("spr", protocols) - if signedIPRange != "" { - sasParams.Add("sip", signedIPRange) - } - } - - sasURL, err := url.Parse(blobURL) - if err != nil { - return "", err - } - sasURL.RawQuery = sasParams.Encode() - return sasURL.String(), nil -} - -// GetBlobSASURI creates an URL to the specified blob which contains the Shared -// Access Signature with specified permissions and expiration time. -// -// See https://msdn.microsoft.com/en-us/library/azure/ee395415.aspx -func (b BlobStorageClient) GetBlobSASURI(container, name string, expiry time.Time, permissions string) (string, error) { - url, err := b.GetBlobSASURIWithSignedIPAndProtocol(container, name, expiry, permissions, "", false) - return url, err -} - -func blobSASStringToSign(signedVersion, canonicalizedResource, signedExpiry, signedPermissions string, signedIP string, protocols string) (string, error) { - var signedStart, signedIdentifier, rscc, rscd, rsce, rscl, rsct string - - if signedVersion >= "2015-02-21" { - canonicalizedResource = "/blob" + canonicalizedResource - } - - // https://msdn.microsoft.com/en-us/library/azure/dn140255.aspx#Anchor_12 - if signedVersion >= "2015-04-05" { - return fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s", signedPermissions, signedStart, signedExpiry, canonicalizedResource, signedIdentifier, signedIP, protocols, signedVersion, rscc, rscd, rsce, rscl, rsct), nil - } - - // reference: http://msdn.microsoft.com/en-us/library/azure/dn140255.aspx - if signedVersion >= "2013-08-15" { - return fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s", signedPermissions, signedStart, signedExpiry, canonicalizedResource, signedIdentifier, signedVersion, rscc, rscd, rsce, rscl, rsct), nil - } - - return "", errors.New("storage: not implemented SAS for versions earlier than 2013-08-15") -} diff --git a/storage/blob_test.go b/storage/blob_test.go index b4d65e4d4562..a70b518bf4fe 100644 --- a/storage/blob_test.go +++ b/storage/blob_test.go @@ -2,16 +2,12 @@ package storage import ( "bytes" - "crypto/rand" - "encoding/base64" "encoding/xml" "fmt" - "io" "io/ioutil" "net/http" - "net/url" - "testing" - "time" + "strconv" + "strings" chk "gopkg.in/check.v1" ) @@ -20,1111 +16,509 @@ type StorageBlobSuite struct{} var _ = chk.Suite(&StorageBlobSuite{}) -const testContainerPrefix = "zzzztest-" - func getBlobClient(c *chk.C) BlobStorageClient { return getBasicClient(c).GetBlobService() } -func (s *StorageBlobSuite) Test_pathForBlob(c *chk.C) { - c.Assert(pathForBlob("foo", "blob"), chk.Equals, "/foo/blob") +func (s *StorageBlobSuite) Test_buildPath(c *chk.C) { + cli := getBlobClient(c) + cnt := cli.GetContainerReference("lol") + b := cnt.GetBlobReference("rofl") + c.Assert(b.buildPath(), chk.Equals, "/lol/rofl") } func (s *StorageBlobSuite) Test_pathForResource(c *chk.C) { - c.Assert(pathForResource("foo", ""), chk.Equals, "/foo") - c.Assert(pathForResource("foo", "blob"), chk.Equals, "/foo/blob") -} - -func (s *StorageBlobSuite) Test_blobSASStringToSign(c *chk.C) { - _, err := blobSASStringToSign("2012-02-12", "CS", "SE", "SP", "", "") - c.Assert(err, chk.NotNil) // not implemented SAS for versions earlier than 2013-08-15 - - out, err := blobSASStringToSign("2013-08-15", "CS", "SE", "SP", "", "") - c.Assert(err, chk.IsNil) - c.Assert(out, chk.Equals, "SP\n\nSE\nCS\n\n2013-08-15\n\n\n\n\n") - - // check format for 2015-04-05 version - out, err = blobSASStringToSign("2015-04-05", "CS", "SE", "SP", "127.0.0.1", "https,http") - c.Assert(err, chk.IsNil) - c.Assert(out, chk.Equals, "SP\n\nSE\n/blobCS\n\n127.0.0.1\nhttps,http\n2015-04-05\n\n\n\n\n") -} - -func (s *StorageBlobSuite) TestGetBlobSASURI(c *chk.C) { - api, err := NewClient("foo", "YmFy", DefaultBaseURL, "2013-08-15", true) - c.Assert(err, chk.IsNil) - cli := api.GetBlobService() - expiry := time.Time{} - - expectedParts := url.URL{ - Scheme: "https", - Host: "foo.blob.core.windows.net", - Path: "container/name", - RawQuery: url.Values{ - "sv": {"2013-08-15"}, - "sig": {"/OXG7rWh08jYwtU03GzJM0DHZtidRGpC6g69rSGm3I0="}, - "sr": {"b"}, - "sp": {"r"}, - "se": {"0001-01-01T00:00:00Z"}, - }.Encode()} - - u, err := cli.GetBlobSASURI("container", "name", expiry, "r") - c.Assert(err, chk.IsNil) - sasParts, err := url.Parse(u) - c.Assert(err, chk.IsNil) - c.Assert(expectedParts.String(), chk.Equals, sasParts.String()) - c.Assert(expectedParts.Query(), chk.DeepEquals, sasParts.Query()) -} - -//Gets a SASURI for the entire container -func (s *StorageBlobSuite) TestGetBlobSASURIContainer(c *chk.C) { - api, err := NewClient("foo", "YmFy", DefaultBaseURL, "2013-08-15", true) - c.Assert(err, chk.IsNil) - cli := api.GetBlobService() - expiry := time.Time{} - - expectedParts := url.URL{ - Scheme: "https", - Host: "foo.blob.core.windows.net", - Path: "container", - RawQuery: url.Values{ - "sv": {"2013-08-15"}, - "sig": {"KMjYyQODKp6uK9EKR3yGhO2M84e1LfoztypU32kHj4s="}, - "sr": {"c"}, - "sp": {"r"}, - "se": {"0001-01-01T00:00:00Z"}, - }.Encode()} - - u, err := cli.GetBlobSASURI("container", "", expiry, "r") - c.Assert(err, chk.IsNil) - sasParts, err := url.Parse(u) - c.Assert(err, chk.IsNil) - c.Assert(expectedParts.String(), chk.Equals, sasParts.String()) - c.Assert(expectedParts.Query(), chk.DeepEquals, sasParts.Query()) -} - -func (s *StorageBlobSuite) TestGetBlobSASURIWithSignedIPAndProtocolValidAPIVersionPassed(c *chk.C) { - api, err := NewClient("foo", "YmFy", DefaultBaseURL, "2015-04-05", true) - c.Assert(err, chk.IsNil) - cli := api.GetBlobService() - expiry := time.Time{} - - expectedParts := url.URL{ - Scheme: "https", - Host: "foo.blob.core.windows.net", - Path: "/container/name", - RawQuery: url.Values{ - "sv": {"2015-04-05"}, - "sig": {"VBOYJmt89UuBRXrxNzmsCMoC+8PXX2yklV71QcL1BfM="}, - "sr": {"b"}, - "sip": {"127.0.0.1"}, - "sp": {"r"}, - "se": {"0001-01-01T00:00:00Z"}, - "spr": {"https"}, - }.Encode()} - - u, err := cli.GetBlobSASURIWithSignedIPAndProtocol("container", "name", expiry, "r", "127.0.0.1", true) - c.Assert(err, chk.IsNil) - sasParts, err := url.Parse(u) - c.Assert(err, chk.IsNil) - c.Assert(sasParts.Query(), chk.DeepEquals, expectedParts.Query()) -} - -// Trying to use SignedIP and Protocol but using an older version of the API. -// Should ignore the signedIP/protocol and just use what the older version requires. -func (s *StorageBlobSuite) TestGetBlobSASURIWithSignedIPAndProtocolUsingOldAPIVersion(c *chk.C) { - api, err := NewClient("foo", "YmFy", DefaultBaseURL, "2013-08-15", true) - c.Assert(err, chk.IsNil) - cli := api.GetBlobService() - expiry := time.Time{} - - expectedParts := url.URL{ - Scheme: "https", - Host: "foo.blob.core.windows.net", - Path: "/container/name", - RawQuery: url.Values{ - "sv": {"2013-08-15"}, - "sig": {"/OXG7rWh08jYwtU03GzJM0DHZtidRGpC6g69rSGm3I0="}, - "sr": {"b"}, - "sp": {"r"}, - "se": {"0001-01-01T00:00:00Z"}, - }.Encode()} - - u, err := cli.GetBlobSASURIWithSignedIPAndProtocol("container", "name", expiry, "r", "", true) - c.Assert(err, chk.IsNil) - sasParts, err := url.Parse(u) - c.Assert(err, chk.IsNil) - c.Assert(expectedParts.String(), chk.Equals, sasParts.String()) - c.Assert(expectedParts.Query(), chk.DeepEquals, sasParts.Query()) -} - -func (s *StorageBlobSuite) TestBlobSASURICorrectness(c *chk.C) { - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - blob := randNameWithSpecialChars(5) - body := []byte(randString(100)) - expiry := now.UTC().Add(time.Hour) - permissions := "r" - - c.Assert(cli.putSingleBlockBlob(cnt.Name, blob, body), chk.IsNil) - - sasURI, err := cli.GetBlobSASURI(cnt.Name, blob, expiry, permissions) - c.Assert(err, chk.IsNil) - - resp, err := http.Get(sasURI) - c.Assert(err, chk.IsNil) - - blobResp, err := ioutil.ReadAll(resp.Body) - defer resp.Body.Close() - c.Assert(err, chk.IsNil) - - c.Assert(resp.StatusCode, chk.Equals, http.StatusOK) - c.Assert(len(blobResp), chk.Equals, len(body)) + c.Assert(pathForResource("lol", ""), chk.Equals, "/lol") + c.Assert(pathForResource("lol", "blob"), chk.Equals, "/lol/blob") } func (s *StorageBlobSuite) TestBlobExists(c *chk.C) { - blob := randName(5) - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() + rec := cli.client.appendRecorder(c) + defer rec.Stop() - c.Assert(cli.putSingleBlockBlob(cnt.Name, blob, []byte("Hello!")), chk.IsNil) - defer cli.DeleteBlob(cnt.Name, blob, nil) + cnt := cli.GetContainerReference(containerName(c)) + c.Assert(cnt.Create(nil), chk.IsNil) + b := cnt.GetBlobReference(blobName(c)) + defer cnt.Delete(nil) - ok, err := cli.BlobExists(cnt.Name, blob+".foo") - c.Assert(err, chk.IsNil) - c.Assert(ok, chk.Equals, false) + c.Assert(b.putSingleBlockBlob([]byte("Hello!")), chk.IsNil) + defer b.Delete(nil) - ok, err = cli.BlobExists(cnt.Name, blob) + ok, err := b.Exists() c.Assert(err, chk.IsNil) c.Assert(ok, chk.Equals, true) -} - -func (s *StorageBlobSuite) TestGetBlobURL(c *chk.C) { - api, err := NewBasicClient("foo", "YmFy") + b.Name += ".lol" + ok, err = b.Exists() c.Assert(err, chk.IsNil) - cli := api.GetBlobService() - - c.Assert(cli.GetBlobURL("c", "nested/blob"), chk.Equals, "https://foo.blob.core.windows.net/c/nested/blob") - c.Assert(cli.GetBlobURL("", "blob"), chk.Equals, "https://foo.blob.core.windows.net/$root/blob") - c.Assert(cli.GetBlobURL("", "nested/blob"), chk.Equals, "https://foo.blob.core.windows.net/$root/nested/blob") -} - -func (s *StorageBlobSuite) TestGetBlobContainerURL(c *chk.C) { - api, err := NewBasicClient("foo", "YmFy") - c.Assert(err, chk.IsNil) - cli := api.GetBlobService() + c.Assert(ok, chk.Equals, false) - c.Assert(cli.GetBlobURL("c", ""), chk.Equals, "https://foo.blob.core.windows.net/c") - c.Assert(cli.GetBlobURL("", ""), chk.Equals, "https://foo.blob.core.windows.net/$root") } -func (s *StorageBlobSuite) TestBlobCopy(c *chk.C) { - if testing.Short() { - c.Skip("skipping blob copy in short mode, no SLA on async operation") - } - - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - src := randName(5) - dst := randName(5) - body := []byte(randString(1024)) - - c.Assert(cli.putSingleBlockBlob(cnt.Name, src, body), chk.IsNil) - defer cli.DeleteBlob(cnt.Name, src, nil) - - c.Assert(cli.CopyBlob(cnt.Name, dst, cli.GetBlobURL(cnt.Name, src)), chk.IsNil) - defer cli.DeleteBlob(cnt.Name, dst, nil) - - blobBody, err := cli.GetBlob(cnt.Name, dst) - c.Assert(err, chk.IsNil) - - b, err := ioutil.ReadAll(blobBody) - defer blobBody.Close() +func (s *StorageBlobSuite) TestGetBlobURL(c *chk.C) { + cli, err := NewBasicClient(dummyStorageAccount, dummyMiniStorageKey) c.Assert(err, chk.IsNil) - c.Assert(b, chk.DeepEquals, body) -} - -func (s *StorageBlobSuite) TestStartBlobCopy(c *chk.C) { - if testing.Short() { - c.Skip("skipping blob copy in short mode, no SLA on async operation") - } + blobCli := cli.GetBlobService() - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() + cnt := blobCli.GetContainerReference("c") + b := cnt.GetBlobReference("nested/blob") + c.Assert(b.GetURL(), chk.Equals, "https://golangrocksonazure.blob.core.windows.net/c/nested/blob") - src := randName(5) - dst := randName(5) - body := []byte(randString(1024)) + cnt.Name = "" + c.Assert(b.GetURL(), chk.Equals, "https://golangrocksonazure.blob.core.windows.net/$root/nested/blob") - c.Assert(cli.putSingleBlockBlob(cnt.Name, src, body), chk.IsNil) - defer cli.DeleteBlob(cnt.Name, src, nil) + b.Name = "blob" + c.Assert(b.GetURL(), chk.Equals, "https://golangrocksonazure.blob.core.windows.net/$root/blob") - // given we dont know when it will start, can we even test destination creation? - // will just test that an error wasn't thrown for now. - copyID, err := cli.StartBlobCopy(cnt.Name, dst, cli.GetBlobURL(cnt.Name, src)) - c.Assert(copyID, chk.NotNil) - c.Assert(err, chk.IsNil) } -// Tests abort of blobcopy. Given the blobcopy is usually over before we can actually trigger an abort -// it is agreed that we perform a copy then try and perform an abort. It should result in a HTTP status of 409. -// So basically we're testing negative scenario (as good as we can do for now) -func (s *StorageBlobSuite) TestAbortBlobCopy(c *chk.C) { - if testing.Short() { - c.Skip("skipping blob copy in short mode, no SLA on async operation") - } - - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - src := randName(5) - dst := randName(5) - body := []byte(randString(1024)) - - c.Assert(cli.putSingleBlockBlob(cnt.Name, src, body), chk.IsNil) - defer cli.DeleteBlob(cnt.Name, src, nil) - - // given we dont know when it will start, can we even test destination creation? - // will just test that an error wasn't thrown for now. - copyID, err := cli.StartBlobCopy(cnt.Name, dst, cli.GetBlobURL(cnt.Name, src)) - c.Assert(copyID, chk.NotNil) - c.Assert(err, chk.IsNil) - - err = cli.WaitForBlobCopy(cnt.Name, dst, copyID) +func (s *StorageBlobSuite) TestGetBlobContainerURL(c *chk.C) { + cli, err := NewBasicClient(dummyStorageAccount, dummyMiniStorageKey) c.Assert(err, chk.IsNil) + blobCli := cli.GetBlobService() - // abort abort abort, but we *know* its already completed. - err = cli.AbortBlobCopy(cnt.Name, dst, copyID, "", 0) + cnt := blobCli.GetContainerReference("c") + b := cnt.GetBlobReference("") + c.Assert(b.GetURL(), chk.Equals, "https://golangrocksonazure.blob.core.windows.net/c") - // abort should fail (over already) - c.Assert(err.(AzureStorageServiceError).StatusCode, chk.Equals, http.StatusConflict) + cnt.Name = "" + c.Assert(b.GetURL(), chk.Equals, "https://golangrocksonazure.blob.core.windows.net/$root") } func (s *StorageBlobSuite) TestDeleteBlobIfExists(c *chk.C) { - blob := randName(5) - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() + rec := cli.client.appendRecorder(c) + defer rec.Stop() - c.Assert(cli.DeleteBlob(cnt.Name, blob, nil), chk.NotNil) + cnt := cli.GetContainerReference(containerName(c)) + b := cnt.GetBlobReference(blobName(c)) + c.Assert(cnt.Create(nil), chk.IsNil) + defer cnt.Delete(nil) - ok, err := cli.DeleteBlobIfExists(cnt.Name, blob, nil) + c.Assert(b.Delete(nil), chk.NotNil) + + ok, err := b.DeleteIfExists(nil) c.Assert(err, chk.IsNil) c.Assert(ok, chk.Equals, false) } func (s *StorageBlobSuite) TestDeleteBlobWithConditions(c *chk.C) { - blob := randName(5) - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() + rec := cli.client.appendRecorder(c) + defer rec.Stop() - c.Assert(cli.CreateBlockBlob(cnt.Name, blob), chk.IsNil) - oldProps, err := cli.GetBlobProperties(cnt.Name, blob) - c.Assert(err, chk.IsNil) + cnt := cli.GetContainerReference(containerName(c)) + b := cnt.GetBlobReference(blobName(c)) + c.Assert(cnt.Create(nil), chk.IsNil) + defer cnt.Delete(nil) - // Update metadata, so Etag changes - c.Assert(cli.SetBlobMetadata(cnt.Name, blob, map[string]string{}, nil), chk.IsNil) - newProps, err := cli.GetBlobProperties(cnt.Name, blob) + c.Assert(b.CreateBlockBlob(nil), chk.IsNil) + err := b.GetProperties(nil) c.Assert(err, chk.IsNil) + etag := b.Properties.Etag - // "Delete if matches old Etag" should fail without deleting. - err = cli.DeleteBlob(cnt.Name, blob, map[string]string{ - "If-Match": oldProps.Etag, - }) + // "Delete if matches incorrect or old Etag" should fail without deleting. + options := DeleteBlobOptions{ + IfMatch: "GolangRocksOnAzure", + } + err = b.Delete(&options) c.Assert(err, chk.FitsTypeOf, AzureStorageServiceError{}) c.Assert(err.(AzureStorageServiceError).StatusCode, chk.Equals, http.StatusPreconditionFailed) - _, err = cli.GetBlob(cnt.Name, blob) + ok, err := b.Exists() c.Assert(err, chk.IsNil) + c.Assert(ok, chk.Equals, true) // "Delete if matches new Etag" should succeed. - err = cli.DeleteBlob(cnt.Name, blob, map[string]string{ - "If-Match": newProps.Etag, - }) + options.IfMatch = etag + ok, err = b.DeleteIfExists(&options) c.Assert(err, chk.IsNil) - _, err = cli.GetBlob(cnt.Name, blob) - c.Assert(err, chk.Not(chk.IsNil)) + c.Assert(ok, chk.Equals, true) } func (s *StorageBlobSuite) TestGetBlobProperties(c *chk.C) { - blob := randName(5) - contents := randString(64) - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + cnt := cli.GetContainerReference(containerName(c)) + c.Assert(cnt.Create(nil), chk.IsNil) + defer cnt.Delete(nil) - // Nonexisting blob - _, err := cli.GetBlobProperties(cnt.Name, blob) + // try to get properties on a nonexisting blob + blob1 := cnt.GetBlobReference(blobName(c, "1")) + err := blob1.GetProperties(nil) c.Assert(err, chk.NotNil) - // Put the blob - c.Assert(cli.putSingleBlockBlob(cnt.Name, blob, []byte(contents)), chk.IsNil) + // Put a blob + blob2 := cnt.GetBlobReference(blobName(c, "2")) + contents := content(64) + c.Assert(blob2.putSingleBlockBlob(contents), chk.IsNil) // Get blob properties - props, err := cli.GetBlobProperties(cnt.Name, blob) + err = blob2.GetProperties(nil) c.Assert(err, chk.IsNil) - c.Assert(props.ContentLength, chk.Equals, int64(len(contents))) - c.Assert(props.ContentType, chk.Equals, "application/octet-stream") - c.Assert(props.BlobType, chk.Equals, BlobTypeBlock) + c.Assert(blob2.Properties.ContentLength, chk.Equals, int64(len(contents))) + c.Assert(blob2.Properties.ContentType, chk.Equals, "application/octet-stream") + c.Assert(blob2.Properties.BlobType, chk.Equals, BlobTypeBlock) } // Ensure it's possible to generate a ListBlobs response with // metadata, e.g., for a stub server. func (s *StorageBlobSuite) TestMarshalBlobMetadata(c *chk.C) { buf, err := xml.Marshal(Blob{ - Name: randName(5), + Name: blobName(c), Properties: BlobProperties{}, - Metadata: BlobMetadata{"foo": "baz < waz"}, + Metadata: map[string]string{ + "lol": "baz < waz", + }, }) c.Assert(err, chk.IsNil) - c.Assert(string(buf), chk.Matches, `.*baz < waz.*`) + c.Assert(string(buf), chk.Matches, `.*baz < waz.*`) } -func (s *StorageBlobSuite) TestGetAndSetMetadata(c *chk.C) { +func (s *StorageBlobSuite) TestGetAndSetBlobMetadata(c *chk.C) { cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() + rec := cli.client.appendRecorder(c) + defer rec.Stop() - blob := randName(5) - c.Assert(cli.putSingleBlockBlob(cnt.Name, blob, []byte{}), chk.IsNil) + cnt := cli.GetContainerReference(containerName(c)) + c.Assert(cnt.Create(nil), chk.IsNil) + defer cnt.Delete(nil) - m, err := cli.GetBlobMetadata(cnt.Name, blob) + // Get empty metadata + blob1 := cnt.GetBlobReference(blobName(c, "1")) + c.Assert(blob1.putSingleBlockBlob([]byte("Hello!")), chk.IsNil) + + err := blob1.GetMetadata(nil) c.Assert(err, chk.IsNil) - c.Assert(m, chk.Not(chk.Equals), nil) - c.Assert(len(m), chk.Equals, 0) + c.Assert(blob1.Metadata, chk.HasLen, 0) - mPut := map[string]string{ - "foo": "bar", - "bar_baz": "waz qux", + // Get and set the metadata + blob2 := cnt.GetBlobReference(blobName(c, "2")) + c.Assert(blob2.putSingleBlockBlob([]byte("Hello!")), chk.IsNil) + metaPut := BlobMetadata{ + "lol": "rofl", + "rofl_baz": "waz qux", } + blob2.Metadata = metaPut - err = cli.SetBlobMetadata(cnt.Name, blob, mPut, nil) + err = blob2.SetMetadata(nil) c.Assert(err, chk.IsNil) - m, err = cli.GetBlobMetadata(cnt.Name, blob) + err = blob2.GetMetadata(nil) c.Assert(err, chk.IsNil) - c.Check(m, chk.DeepEquals, mPut) + c.Check(blob2.Metadata, chk.DeepEquals, metaPut) +} - // Case munging +func (s *StorageBlobSuite) TestMetadataCaseMunging(c *chk.C) { + cli := getBlobClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + cnt := cli.GetContainerReference(containerName(c)) + c.Assert(cnt.Create(nil), chk.IsNil) + defer cnt.Delete(nil) + + b := cnt.GetBlobReference(blobName(c)) + c.Assert(b.putSingleBlockBlob([]byte("Hello!")), chk.IsNil) - mPutUpper := map[string]string{ - "Foo": "different bar", - "bar_BAZ": "different waz qux", + // Case munging + metaPutUpper := BlobMetadata{ + "Lol": "different rofl", + "rofl_BAZ": "different waz qux", } - mExpectLower := map[string]string{ - "foo": "different bar", - "bar_baz": "different waz qux", + metaExpectLower := BlobMetadata{ + "lol": "different rofl", + "rofl_baz": "different waz qux", } - err = cli.SetBlobMetadata(cnt.Name, blob, mPutUpper, nil) + b.Metadata = metaPutUpper + err := b.SetMetadata(nil) c.Assert(err, chk.IsNil) - m, err = cli.GetBlobMetadata(cnt.Name, blob) + err = b.GetMetadata(nil) c.Assert(err, chk.IsNil) - c.Check(m, chk.DeepEquals, mExpectLower) + c.Check(b.Metadata, chk.DeepEquals, metaExpectLower) } func (s *StorageBlobSuite) TestSetMetadataWithExtraHeaders(c *chk.C) { cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() + 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) - blob := randName(5) - c.Assert(cli.putSingleBlockBlob(cnt.Name, blob, []byte{}), chk.IsNil) + c.Assert(b.putSingleBlockBlob([]byte("Hello!")), chk.IsNil) - mPut := map[string]string{ - "foo": "bar", - "bar_baz": "waz qux", + meta := BlobMetadata{ + "lol": "rofl", + "rofl_baz": "waz qux", } + b.Metadata = meta - extraHeaders := map[string]string{ - "If-Match": "incorrect-etag", + options := SetBlobMetadataOptions{ + IfMatch: "incorrect-etag", } // Set with incorrect If-Match in extra headers should result in error - err := cli.SetBlobMetadata(cnt.Name, blob, mPut, extraHeaders) + err := b.SetMetadata(&options) c.Assert(err, chk.NotNil) - props, err := cli.GetBlobProperties(cnt.Name, blob) - extraHeaders = map[string]string{ - "If-Match": props.Etag, - } + err = b.GetProperties(nil) + c.Assert(err, chk.IsNil) // Set with matching If-Match in extra headers should succeed - err = cli.SetBlobMetadata(cnt.Name, blob, mPut, extraHeaders) + options.IfMatch = b.Properties.Etag + b.Metadata = meta + err = b.SetMetadata(&options) c.Assert(err, chk.IsNil) } func (s *StorageBlobSuite) TestSetBlobProperties(c *chk.C) { cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() + 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) - blob := randName(5) - c.Assert(cli.putSingleBlockBlob(cnt.Name, blob, []byte{}), chk.IsNil) + c.Assert(b.putSingleBlockBlob([]byte("Hello!")), chk.IsNil) - mPut := BlobHeaders{ + input := BlobProperties{ CacheControl: "private, max-age=0, no-cache", ContentMD5: "oBATU+oaDduHWbVZLuzIJw==", ContentType: "application/json", ContentEncoding: "gzip", ContentLanguage: "de-DE", } + b.Properties = input - err := cli.SetBlobProperties(cnt.Name, blob, mPut) + err := b.SetProperties(nil) c.Assert(err, chk.IsNil) - props, err := cli.GetBlobProperties(cnt.Name, blob) + err = b.GetProperties(nil) c.Assert(err, chk.IsNil) - c.Check(mPut.CacheControl, chk.Equals, props.CacheControl) - c.Check(mPut.ContentType, chk.Equals, props.ContentType) - c.Check(mPut.ContentMD5, chk.Equals, props.ContentMD5) - c.Check(mPut.ContentEncoding, chk.Equals, props.ContentEncoding) - c.Check(mPut.ContentLanguage, chk.Equals, props.ContentLanguage) + c.Check(b.Properties.CacheControl, chk.Equals, input.CacheControl) + c.Check(b.Properties.ContentType, chk.Equals, input.ContentType) + c.Check(b.Properties.ContentMD5, chk.Equals, input.ContentMD5) + c.Check(b.Properties.ContentEncoding, chk.Equals, input.ContentEncoding) + c.Check(b.Properties.ContentLanguage, chk.Equals, input.ContentLanguage) } func (s *StorageBlobSuite) TestSnapshotBlob(c *chk.C) { cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() + rec := cli.client.appendRecorder(c) + defer rec.Stop() - blob := randName(5) - c.Assert(cli.putSingleBlockBlob(cnt.Name, blob, []byte{}), chk.IsNil) + cnt := cli.GetContainerReference(containerName(c)) + b := cnt.GetBlobReference(blobName(c)) + c.Assert(cnt.Create(nil), chk.IsNil) + defer cnt.Delete(nil) - snapshotTime, err := cli.SnapshotBlob(cnt.Name, blob, 0, nil) + c.Assert(b.putSingleBlockBlob([]byte("Hello!")), chk.IsNil) + + snapshotTime, err := b.CreateSnapshot(nil) c.Assert(err, chk.IsNil) c.Assert(snapshotTime, chk.NotNil) } func (s *StorageBlobSuite) TestSnapshotBlobWithTimeout(c *chk.C) { cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() + 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) - blob := randName(5) - c.Assert(cli.putSingleBlockBlob(cnt.Name, blob, []byte{}), chk.IsNil) + c.Assert(b.putSingleBlockBlob([]byte("Hello!")), chk.IsNil) - snapshotTime, err := cli.SnapshotBlob(cnt.Name, blob, 30, nil) + options := SnapshotOptions{ + Timeout: 0, + } + snapshotTime, err := b.CreateSnapshot(&options) c.Assert(err, chk.IsNil) c.Assert(snapshotTime, chk.NotNil) } func (s *StorageBlobSuite) TestSnapshotBlobWithValidLease(c *chk.C) { cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() + 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) - blob := randName(5) - c.Assert(cli.putSingleBlockBlob(cnt.Name, blob, []byte{}), chk.IsNil) + c.Assert(b.putSingleBlockBlob([]byte("Hello!")), chk.IsNil) // generate lease. - currentLeaseID, err := cli.AcquireLease(cnt.Name, blob, 30, "") + currentLeaseID, err := b.AcquireLease(30, "", nil) c.Assert(err, chk.IsNil) - extraHeaders := map[string]string{ - headerLeaseID: currentLeaseID, + options := SnapshotOptions{ + LeaseID: currentLeaseID, } - - snapshotTime, err := cli.SnapshotBlob(cnt.Name, blob, 0, extraHeaders) + snapshotTime, err := b.CreateSnapshot(&options) c.Assert(err, chk.IsNil) c.Assert(snapshotTime, chk.NotNil) } func (s *StorageBlobSuite) TestSnapshotBlobWithInvalidLease(c *chk.C) { cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() + 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) - blob := randName(5) - c.Assert(cli.putSingleBlockBlob(cnt.Name, blob, []byte{}), chk.IsNil) + c.Assert(b.putSingleBlockBlob([]byte("Hello!")), chk.IsNil) // generate lease. - leaseID, err := cli.AcquireLease(cnt.Name, blob, 30, "") + leaseID, err := b.AcquireLease(30, "", nil) c.Assert(err, chk.IsNil) c.Assert(leaseID, chk.Not(chk.Equals), "") - extraHeaders := map[string]string{ - headerLeaseID: "GolangRocksOnAzure", + options := SnapshotOptions{ + LeaseID: "GolangRocksOnAzure", } - - snapshotTime, err := cli.SnapshotBlob(cnt.Name, blob, 0, extraHeaders) + snapshotTime, err := b.CreateSnapshot(&options) c.Assert(err, chk.NotNil) c.Assert(snapshotTime, chk.IsNil) } -func (s *StorageBlobSuite) TestAcquireLeaseWithNoProposedLeaseID(c *chk.C) { - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - blob := randName(5) - c.Assert(cli.putSingleBlockBlob(cnt.Name, blob, []byte{}), chk.IsNil) - - _, err := cli.AcquireLease(cnt.Name, blob, 30, "") - c.Assert(err, chk.IsNil) -} - -func (s *StorageBlobSuite) TestAcquireLeaseWithProposedLeaseID(c *chk.C) { - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - blob := randName(5) - c.Assert(cli.putSingleBlockBlob(cnt.Name, blob, []byte{}), chk.IsNil) - - proposedLeaseID := "dfe6dde8-68d5-4910-9248-c97c61768fea" - leaseID, err := cli.AcquireLease(cnt.Name, blob, 30, proposedLeaseID) - c.Assert(err, chk.IsNil) - c.Assert(leaseID, chk.Equals, proposedLeaseID) -} - -func (s *StorageBlobSuite) TestAcquireLeaseWithBadProposedLeaseID(c *chk.C) { - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - blob := randName(5) - c.Assert(cli.putSingleBlockBlob(cnt.Name, blob, []byte{}), chk.IsNil) - - proposedLeaseID := "badbadbad" - _, err := cli.AcquireLease(cnt.Name, blob, 30, proposedLeaseID) - c.Assert(err, chk.NotNil) -} - -func (s *StorageBlobSuite) TestRenewLeaseSuccessful(c *chk.C) { - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - blob := randName(5) - c.Assert(cli.putSingleBlockBlob(cnt.Name, blob, []byte{}), chk.IsNil) - - proposedLeaseID := "dfe6dde8-68d5-4910-9248-c97c61768fea" - leaseID, err := cli.AcquireLease(cnt.Name, blob, 30, proposedLeaseID) - c.Assert(err, chk.IsNil) - - err = cli.RenewLease(cnt.Name, blob, leaseID) - c.Assert(err, chk.IsNil) -} - -func (s *StorageBlobSuite) TestRenewLeaseAgainstNoCurrentLease(c *chk.C) { - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - blob := randName(5) - c.Assert(cli.putSingleBlockBlob(cnt.Name, blob, []byte{}), chk.IsNil) - - badLeaseID := "1f812371-a41d-49e6-b123-f4b542e85144" - err := cli.RenewLease(cnt.Name, blob, badLeaseID) - c.Assert(err, chk.NotNil) -} - -func (s *StorageBlobSuite) TestChangeLeaseSuccessful(c *chk.C) { - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - blob := randName(5) - c.Assert(cli.putSingleBlockBlob(cnt.Name, blob, []byte{}), chk.IsNil) - proposedLeaseID := "dfe6dde8-68d5-4910-9248-c97c61768fea" - leaseID, err := cli.AcquireLease(cnt.Name, blob, 30, proposedLeaseID) - c.Assert(err, chk.IsNil) - - newProposedLeaseID := "dfe6dde8-68d5-4910-9248-c97c61768fbb" - newLeaseID, err := cli.ChangeLease(cnt.Name, blob, leaseID, newProposedLeaseID) - c.Assert(err, chk.IsNil) - c.Assert(newLeaseID, chk.Equals, newProposedLeaseID) -} - -func (s *StorageBlobSuite) TestChangeLeaseNotSuccessfulbadProposedLeaseID(c *chk.C) { - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - blob := randName(5) - c.Assert(cli.putSingleBlockBlob(cnt.Name, blob, []byte{}), chk.IsNil) - proposedLeaseID := "dfe6dde8-68d5-4910-9248-c97c61768fea" - leaseID, err := cli.AcquireLease(cnt.Name, blob, 30, proposedLeaseID) - c.Assert(err, chk.IsNil) - - newProposedLeaseID := "1f812371-a41d-49e6-b123-f4b542e" - _, err = cli.ChangeLease(cnt.Name, blob, leaseID, newProposedLeaseID) - c.Assert(err, chk.NotNil) -} - -func (s *StorageBlobSuite) TestReleaseLeaseSuccessful(c *chk.C) { - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - blob := randName(5) - c.Assert(cli.putSingleBlockBlob(cnt.Name, blob, []byte{}), chk.IsNil) - proposedLeaseID := "dfe6dde8-68d5-4910-9248-c97c61768fea" - leaseID, err := cli.AcquireLease(cnt.Name, blob, 30, proposedLeaseID) - c.Assert(err, chk.IsNil) - - err = cli.ReleaseLease(cnt.Name, blob, leaseID) - c.Assert(err, chk.IsNil) -} - -func (s *StorageBlobSuite) TestReleaseLeaseNotSuccessfulBadLeaseID(c *chk.C) { - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - blob := randName(5) - c.Assert(cli.putSingleBlockBlob(cnt.Name, blob, []byte{}), chk.IsNil) - proposedLeaseID := "dfe6dde8-68d5-4910-9248-c97c61768fea" - _, err := cli.AcquireLease(cnt.Name, blob, 30, proposedLeaseID) - c.Assert(err, chk.IsNil) - - err = cli.ReleaseLease(cnt.Name, blob, "badleaseid") - c.Assert(err, chk.NotNil) -} - -func (s *StorageBlobSuite) TestBreakLeaseSuccessful(c *chk.C) { - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - blob := randName(5) - c.Assert(cli.putSingleBlockBlob(cnt.Name, blob, []byte{}), chk.IsNil) - - proposedLeaseID := "dfe6dde8-68d5-4910-9248-c97c61768fea" - _, err := cli.AcquireLease(cnt.Name, blob, 30, proposedLeaseID) - c.Assert(err, chk.IsNil) - - _, err = cli.BreakLease(cnt.Name, blob) - c.Assert(err, chk.IsNil) -} - -func (s *StorageBlobSuite) TestPutEmptyBlockBlob(c *chk.C) { +func (s *StorageBlobSuite) TestGetBlobRange(c *chk.C) { cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() + rec := cli.client.appendRecorder(c) + defer rec.Stop() - blob := randName(5) - c.Assert(cli.putSingleBlockBlob(cnt.Name, blob, []byte{}), chk.IsNil) + cnt := cli.GetContainerReference(containerName(c)) + b := cnt.GetBlobReference(blobName(c)) + c.Assert(cnt.Create(nil), chk.IsNil) + defer cnt.Delete(nil) - props, err := cli.GetBlobProperties(cnt.Name, blob) - c.Assert(err, chk.IsNil) - c.Assert(props.ContentLength, chk.Not(chk.Equals), 0) -} - -func (s *StorageBlobSuite) TestGetBlobRange(c *chk.C) { - blob := randName(5) body := "0123456789" + c.Assert(b.putSingleBlockBlob([]byte(body)), chk.IsNil) + defer b.Delete(nil) - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - c.Assert(cli.putSingleBlockBlob(cnt.Name, blob, []byte(body)), chk.IsNil) - defer cli.DeleteBlob(cnt.Name, blob, nil) - - // Read 1-3 - for _, r := range []struct { - rangeStr string + cases := []struct { + options GetBlobRangeOptions expected string }{ - {"0-", body}, - {"1-3", body[1 : 3+1]}, - {"3-", body[3:]}, - } { - resp, err := cli.GetBlobRange(cnt.Name, blob, r.rangeStr, nil) + { + options: GetBlobRangeOptions{ + Range: &BlobRange{ + Start: 0, + End: uint64(len(body)), + }, + }, + expected: body, + }, + { + options: GetBlobRangeOptions{ + Range: &BlobRange{ + Start: 1, + End: 3, + }, + }, + expected: body[1 : 3+1], + }, + { + options: GetBlobRangeOptions{ + Range: &BlobRange{ + Start: 3, + End: uint64(len(body)), + }, + }, + expected: body[3:], + }, + } + + // Read 1-3 + for _, r := range cases { + resp, err := b.GetRange(&(r.options)) c.Assert(err, chk.IsNil) blobBody, err := ioutil.ReadAll(resp) c.Assert(err, chk.IsNil) str := string(blobBody) c.Assert(str, chk.Equals, r.expected) - } -} - -func (s *StorageBlobSuite) TestCreateBlockBlobFromReader(c *chk.C) { - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - name := randName(5) - data := randBytes(8888) - c.Assert(cli.CreateBlockBlobFromReader(cnt.Name, name, uint64(len(data)), bytes.NewReader(data), nil), chk.IsNil) - - body, err := cli.GetBlob(cnt.Name, name) - c.Assert(err, chk.IsNil) - gotData, err := ioutil.ReadAll(body) - body.Close() - - c.Assert(err, chk.IsNil) - c.Assert(gotData, chk.DeepEquals, data) -} - -func (s *StorageBlobSuite) TestCreateBlockBlobFromReaderWithShortData(c *chk.C) { - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - name := randName(5) - data := randBytes(8888) - err := cli.CreateBlockBlobFromReader(cnt.Name, name, 9999, bytes.NewReader(data), nil) - c.Assert(err, chk.Not(chk.IsNil)) - - _, err = cli.GetBlob(cnt.Name, name) - // Upload was incomplete: blob should not have been created. - c.Assert(err, chk.Not(chk.IsNil)) -} - -func (s *StorageBlobSuite) TestPutBlock(c *chk.C) { - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - blob := randName(5) - chunk := []byte(randString(1024)) - blockID := base64.StdEncoding.EncodeToString([]byte("foo")) - c.Assert(cli.PutBlock(cnt.Name, blob, blockID, chunk), chk.IsNil) -} - -func (s *StorageBlobSuite) TestGetBlockList_PutBlockList(c *chk.C) { - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - blob := randName(5) - chunk := []byte(randString(1024)) - blockID := base64.StdEncoding.EncodeToString([]byte("foo")) - - // Put one block - c.Assert(cli.PutBlock(cnt.Name, blob, blockID, chunk), chk.IsNil) - defer cli.deleteBlob(cnt.Name, blob, nil) - - // Get committed blocks - committed, err := cli.GetBlockList(cnt.Name, blob, BlockListTypeCommitted) - c.Assert(err, chk.IsNil) - if len(committed.CommittedBlocks) > 0 { - c.Fatal("There are committed blocks") + // Was content lenght properly updated...? + c.Assert(b.Properties.ContentLength, chk.Equals, int64(len(r.expected))) } - - // Get uncommitted blocks - uncommitted, err := cli.GetBlockList(cnt.Name, blob, BlockListTypeUncommitted) - c.Assert(err, chk.IsNil) - - c.Assert(len(uncommitted.UncommittedBlocks), chk.Equals, 1) - // Commit block list - c.Assert(cli.PutBlockList(cnt.Name, blob, []Block{{blockID, BlockStatusUncommitted}}), chk.IsNil) - - // Get all blocks - all, err := cli.GetBlockList(cnt.Name, blob, BlockListTypeAll) - c.Assert(err, chk.IsNil) - c.Assert(len(all.CommittedBlocks), chk.Equals, 1) - c.Assert(len(all.UncommittedBlocks), chk.Equals, 0) - - // Verify the block - thatBlock := all.CommittedBlocks[0] - c.Assert(thatBlock.Name, chk.Equals, blockID) - c.Assert(thatBlock.Size, chk.Equals, int64(len(chunk))) -} - -func (s *StorageBlobSuite) TestCreateBlockBlob(c *chk.C) { - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - blob := randName(5) - c.Assert(cli.CreateBlockBlob(cnt.Name, blob), chk.IsNil) - - // Verify - blocks, err := cli.GetBlockList(cnt.Name, blob, BlockListTypeAll) - c.Assert(err, chk.IsNil) - c.Assert(len(blocks.CommittedBlocks), chk.Equals, 0) - c.Assert(len(blocks.UncommittedBlocks), chk.Equals, 0) -} - -func (s *StorageBlobSuite) TestPutPageBlob(c *chk.C) { - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - blob := randName(5) - size := int64(10 * 1024 * 1024) - c.Assert(cli.PutPageBlob(cnt.Name, blob, size, nil), chk.IsNil) - - // Verify - props, err := cli.GetBlobProperties(cnt.Name, blob) - c.Assert(err, chk.IsNil) - c.Assert(props.ContentLength, chk.Equals, size) - c.Assert(props.BlobType, chk.Equals, BlobTypePage) } -func (s *StorageBlobSuite) TestPutPagesUpdate(c *chk.C) { - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - blob := randName(5) - size := int64(10 * 1024 * 1024) // larger than we'll use - c.Assert(cli.PutPageBlob(cnt.Name, blob, size, nil), chk.IsNil) - - chunk1 := []byte(randString(1024)) - chunk2 := []byte(randString(512)) - - // Append chunks - c.Assert(cli.PutPage(cnt.Name, blob, 0, int64(len(chunk1)-1), PageWriteTypeUpdate, chunk1, nil), chk.IsNil) - c.Assert(cli.PutPage(cnt.Name, blob, int64(len(chunk1)), int64(len(chunk1)+len(chunk2)-1), PageWriteTypeUpdate, chunk2, nil), chk.IsNil) - - // Verify contents - out, err := cli.GetBlobRange(cnt.Name, blob, fmt.Sprintf("%v-%v", 0, len(chunk1)+len(chunk2)-1), nil) - 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...)) - out.Close() - - // Overwrite first half of chunk1 - chunk0 := []byte(randString(512)) - c.Assert(cli.PutPage(cnt.Name, blob, 0, int64(len(chunk0)-1), PageWriteTypeUpdate, chunk0, nil), chk.IsNil) - - // Verify contents - out, err = cli.GetBlobRange(cnt.Name, blob, fmt.Sprintf("%v-%v", 0, len(chunk1)+len(chunk2)-1), nil) - c.Assert(err, chk.IsNil) - defer out.Close() - blobContents, err = ioutil.ReadAll(out) - c.Assert(err, chk.IsNil) - c.Assert(blobContents, chk.DeepEquals, append(append(chunk0, chunk1[512:]...), chunk2...)) -} - -func (s *StorageBlobSuite) TestPutPagesClear(c *chk.C) { - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - blob := randName(5) - size := int64(10 * 1024 * 1024) // larger than we'll use - c.Assert(cli.PutPageBlob(cnt.Name, blob, size, nil), chk.IsNil) - - // Put 0-2047 - chunk := []byte(randString(2048)) - c.Assert(cli.PutPage(cnt.Name, blob, 0, 2047, PageWriteTypeUpdate, chunk, nil), chk.IsNil) - - // Clear 512-1023 - c.Assert(cli.PutPage(cnt.Name, blob, 512, 1023, PageWriteTypeClear, nil, nil), chk.IsNil) - - // Verify contents - out, err := cli.GetBlobRange(cnt.Name, blob, "0-2047", nil) - c.Assert(err, chk.IsNil) - contents, err := ioutil.ReadAll(out) - c.Assert(err, chk.IsNil) - defer out.Close() - c.Assert(contents, chk.DeepEquals, append(append(chunk[:512], make([]byte, 512)...), chunk[1024:]...)) -} - -func (s *StorageBlobSuite) TestGetPageRanges(c *chk.C) { - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - blob := randName(5) - size := int64(10 * 1024 * 1024) // larger than we'll use - c.Assert(cli.PutPageBlob(cnt.Name, blob, size, nil), chk.IsNil) - - // Get page ranges on empty blob - out, err := cli.GetPageRanges(cnt.Name, blob) - c.Assert(err, chk.IsNil) - c.Assert(len(out.PageList), chk.Equals, 0) - - // Add 0-512 page - c.Assert(cli.PutPage(cnt.Name, blob, 0, 511, PageWriteTypeUpdate, []byte(randString(512)), nil), chk.IsNil) - - out, err = cli.GetPageRanges(cnt.Name, blob) - c.Assert(err, chk.IsNil) - c.Assert(len(out.PageList), chk.Equals, 1) - - // Add 1024-2048 - c.Assert(cli.PutPage(cnt.Name, blob, 1024, 2047, PageWriteTypeUpdate, []byte(randString(1024)), nil), chk.IsNil) - - out, err = cli.GetPageRanges(cnt.Name, blob) - c.Assert(err, chk.IsNil) - c.Assert(len(out.PageList), chk.Equals, 2) -} - -func (s *StorageBlobSuite) TestPutAppendBlob(c *chk.C) { - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - blob := randName(5) - c.Assert(cli.PutAppendBlob(cnt.Name, blob, nil), chk.IsNil) - - // Verify - props, err := cli.GetBlobProperties(cnt.Name, blob) - c.Assert(err, chk.IsNil) - c.Assert(props.ContentLength, chk.Equals, int64(0)) - c.Assert(props.BlobType, chk.Equals, BlobTypeAppend) -} - -func (s *StorageBlobSuite) TestPutAppendBlobAppendBlocks(c *chk.C) { - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - blob := randName(5) - c.Assert(cli.PutAppendBlob(cnt.Name, blob, nil), chk.IsNil) - - chunk1 := []byte(randString(1024)) - chunk2 := []byte(randString(512)) - - // Append first block - c.Assert(cli.AppendBlock(cnt.Name, blob, chunk1, nil), chk.IsNil) - - // Verify contents - out, err := cli.GetBlobRange(cnt.Name, blob, fmt.Sprintf("%v-%v", 0, len(chunk1)-1), nil) - c.Assert(err, chk.IsNil) - defer out.Close() - blobContents, err := ioutil.ReadAll(out) - c.Assert(err, chk.IsNil) - c.Assert(blobContents, chk.DeepEquals, chunk1) - out.Close() - - // Append second block - c.Assert(cli.AppendBlock(cnt.Name, blob, chunk2, nil), chk.IsNil) - - // Verify contents - out, err = cli.GetBlobRange(cnt.Name, blob, fmt.Sprintf("%v-%v", 0, len(chunk1)+len(chunk2)-1), nil) - 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...)) - out.Close() -} - -func (b BlobStorageClient) putSingleBlockBlob(container, name string, chunk []byte) error { +func (b *Blob) putSingleBlockBlob(chunk []byte) error { if len(chunk) > MaxBlobBlockSize { return fmt.Errorf("storage: provided chunk (%d bytes) cannot fit into single-block blob (max %d bytes)", len(chunk), MaxBlobBlockSize) } - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) - headers := b.client.getStandardHeaders() + uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), nil) + headers := b.Container.bsc.client.getStandardHeaders() headers["x-ms-blob-type"] = string(BlobTypeBlock) - headers["Content-Length"] = fmt.Sprintf("%v", len(chunk)) + headers["Content-Length"] = strconv.Itoa(len(chunk)) - resp, err := b.client.exec(http.MethodPut, uri, headers, bytes.NewReader(chunk), b.auth) + resp, err := b.Container.bsc.client.exec(http.MethodPut, uri, headers, bytes.NewReader(chunk), b.Container.bsc.auth) if err != nil { return err } return checkRespCode(resp.statusCode, []int{http.StatusCreated}) } -func (s *StorageBlobSuite) TestPutAppendBlobSpecialChars(c *chk.C) { - cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - blob := randNameWithSpecialChars(5) - c.Assert(cli.PutAppendBlob(cnt.Name, blob, nil), chk.IsNil) +func blobName(c *chk.C, extras ...string) string { + return nameGenerator(1024, "blob/", alphanum, c, extras) - // Verify metadata - props, err := cli.GetBlobProperties(cnt.Name, blob) - c.Assert(err, chk.IsNil) - c.Assert(props.ContentLength, chk.Equals, int64(0)) - c.Assert(props.BlobType, chk.Equals, BlobTypeAppend) - - chunk1 := []byte(randString(1024)) - chunk2 := []byte(randString(512)) - - // Append first block - c.Assert(cli.AppendBlock(cnt.Name, blob, chunk1, nil), chk.IsNil) - - // Verify contents - out, err := cli.GetBlobRange(cnt.Name, blob, fmt.Sprintf("%v-%v", 0, len(chunk1)-1), nil) - c.Assert(err, chk.IsNil) - defer out.Close() - blobContents, err := ioutil.ReadAll(out) - c.Assert(err, chk.IsNil) - c.Assert(blobContents, chk.DeepEquals, chunk1) - out.Close() - - // Append second block - c.Assert(cli.AppendBlock(cnt.Name, blob, chunk2, nil), chk.IsNil) +} - // Verify contents - out, err = cli.GetBlobRange(cnt.Name, blob, fmt.Sprintf("%v-%v", 0, len(chunk1)+len(chunk2)-1), nil) - 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...)) - out.Close() +func contentWithSpecialChars(n int) string { + name := string(content(n)) + "/" + string(content(n)) + "-._~:?#[]@!$&'()*,;+= " + string(content(n)) + return name } -func randBytes(n int) []byte { - data := make([]byte, n) - if _, err := io.ReadFull(rand.Reader, data); err != nil { - panic(err) +func nameGenerator(maxLen int, prefix, valid string, c *chk.C, extras []string) string { + extra := strings.Join(extras, "") + name := prefix + extra + removeInvalidCharacters(c.TestName(), valid) + if len(name) > maxLen { + return name[:maxLen] } - return data + return name } -func randName(n int) string { - name := randString(n) + "/" + randString(n) - return name +func removeInvalidCharacters(unformatted string, valid string) string { + unformatted = strings.ToLower(unformatted) + buffer := bytes.NewBufferString(strconv.Itoa((len(unformatted)))) + runes := []rune(unformatted) + for _, r := range runes { + if strings.ContainsRune(valid, r) { + buffer.WriteRune(r) + } + } + return string(buffer.Bytes()) } -func randNameWithSpecialChars(n int) string { - name := randString(n) + "/" + randString(n) + "-._~:?#[]@!$&'()*,;+= " + randString(n) - return name +func content(n int) []byte { + buffer := bytes.NewBufferString("") + rep := (n / len(veryLongString)) + 1 + for i := 0; i < rep; i++ { + buffer.WriteString(veryLongString) + } + return buffer.Bytes()[:n] } + +const ( + alphanum = "0123456789abcdefghijklmnopqrstuvwxyz" + alpha = "abcdefghijklmnopqrstuvwxyz" + veryLongString = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse platea dictumst." +) diff --git a/storage/blobsasuri.go b/storage/blobsasuri.go new file mode 100644 index 000000000000..43173d3a417a --- /dev/null +++ b/storage/blobsasuri.go @@ -0,0 +1,106 @@ +package storage + +import ( + "errors" + "fmt" + "net/url" + "strings" + "time" +) + +// GetSASURIWithSignedIPAndProtocol creates an URL to the specified blob which contains the Shared +// Access Signature with specified permissions and expiration time. Also includes signedIPRange and allowed protocols. +// If old API version is used but no signedIP is passed (ie empty string) then this should still work. +// We only populate the signedIP when it non-empty. +// +// See https://msdn.microsoft.com/en-us/library/azure/ee395415.aspx +func (b *Blob) GetSASURIWithSignedIPAndProtocol(expiry time.Time, permissions string, signedIPRange string, HTTPSOnly bool) (string, error) { + var ( + signedPermissions = permissions + blobURL = b.GetURL() + ) + canonicalizedResource, err := b.Container.bsc.client.buildCanonicalizedResource(blobURL, b.Container.bsc.auth) + if err != nil { + return "", err + } + + // "The canonicalizedresouce portion of the string is a canonical path to the signed resource. + // It must include the service name (blob, table, queue or file) for version 2015-02-21 or + // later, the storage account name, and the resource name, and must be URL-decoded. + // -- https://msdn.microsoft.com/en-us/library/azure/dn140255.aspx + + // We need to replace + with %2b first to avoid being treated as a space (which is correct for query strings, but not the path component). + canonicalizedResource = strings.Replace(canonicalizedResource, "+", "%2b", -1) + canonicalizedResource, err = url.QueryUnescape(canonicalizedResource) + if err != nil { + return "", err + } + + signedExpiry := expiry.UTC().Format(time.RFC3339) + + //If blob name is missing, resource is a container + signedResource := "c" + if len(b.Name) > 0 { + signedResource = "b" + } + + protocols := "https,http" + if HTTPSOnly { + protocols = "https" + } + stringToSign, err := blobSASStringToSign(b.Container.bsc.client.apiVersion, canonicalizedResource, signedExpiry, signedPermissions, signedIPRange, protocols) + if err != nil { + return "", err + } + + sig := b.Container.bsc.client.computeHmac256(stringToSign) + sasParams := url.Values{ + "sv": {b.Container.bsc.client.apiVersion}, + "se": {signedExpiry}, + "sr": {signedResource}, + "sp": {signedPermissions}, + "sig": {sig}, + } + + if b.Container.bsc.client.apiVersion >= "2015-04-05" { + sasParams.Add("spr", protocols) + if signedIPRange != "" { + sasParams.Add("sip", signedIPRange) + } + } + + sasURL, err := url.Parse(blobURL) + if err != nil { + return "", err + } + sasURL.RawQuery = sasParams.Encode() + return sasURL.String(), nil +} + +// GetSASURI creates an URL to the specified blob which contains the Shared +// Access Signature with specified permissions and expiration time. +// +// See https://msdn.microsoft.com/en-us/library/azure/ee395415.aspx +func (b *Blob) GetSASURI(expiry time.Time, permissions string) (string, error) { + return b.GetSASURIWithSignedIPAndProtocol(expiry, permissions, "", false) +} + +func blobSASStringToSign(signedVersion, canonicalizedResource, signedExpiry, signedPermissions string, signedIP string, protocols string) (string, error) { + var signedStart, signedIdentifier, rscc, rscd, rsce, rscl, rsct string + + if signedVersion >= "2015-02-21" { + canonicalizedResource = "/blob" + canonicalizedResource + } + + // https://msdn.microsoft.com/en-us/library/azure/dn140255.aspx#Anchor_12 + if signedVersion >= "2015-04-05" { + return fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s", signedPermissions, signedStart, signedExpiry, canonicalizedResource, signedIdentifier, signedIP, protocols, signedVersion, rscc, rscd, rsce, rscl, rsct), nil + } + + // reference: http://msdn.microsoft.com/en-us/library/azure/dn140255.aspx + if signedVersion >= "2013-08-15" { + return fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s", signedPermissions, signedStart, signedExpiry, canonicalizedResource, signedIdentifier, signedVersion, rscc, rscd, rsce, rscl, rsct), nil + } + + return "", errors.New("storage: not implemented SAS for versions earlier than 2013-08-15") +} diff --git a/storage/blobsasuri_test.go b/storage/blobsasuri_test.go new file mode 100644 index 000000000000..ac2b6b1c586e --- /dev/null +++ b/storage/blobsasuri_test.go @@ -0,0 +1,185 @@ +package storage + +import ( + "io/ioutil" + "net/http" + "net/url" + "time" + + chk "gopkg.in/check.v1" +) + +type BlobSASURISuite struct{} + +var _ = chk.Suite(&BlobSASURISuite{}) + +var oldAPIVer = "2013-08-15" +var newerAPIVer = "2015-04-05" + +func (s *BlobSASURISuite) TestGetBlobSASURI(c *chk.C) { + api, err := NewClient("foo", dummyMiniStorageKey, DefaultBaseURL, oldAPIVer, true) + c.Assert(err, chk.IsNil) + cli := api.GetBlobService() + cnt := cli.GetContainerReference("container") + b := cnt.GetBlobReference("name") + expiry := time.Time{} + + expectedParts := url.URL{ + Scheme: "https", + Host: "foo.blob.core.windows.net", + Path: "container/name", + RawQuery: url.Values{ + "sv": {oldAPIVer}, + "sig": {"/OXG7rWh08jYwtU03GzJM0DHZtidRGpC6g69rSGm3I0="}, + "sr": {"b"}, + "sp": {"r"}, + "se": {"0001-01-01T00:00:00Z"}, + }.Encode()} + + u, err := b.GetSASURI(expiry, "r") + c.Assert(err, chk.IsNil) + sasParts, err := url.Parse(u) + c.Assert(err, chk.IsNil) + c.Assert(expectedParts.String(), chk.Equals, sasParts.String()) + c.Assert(expectedParts.Query(), chk.DeepEquals, sasParts.Query()) +} + +//Gets a SASURI for the entire container +func (s *BlobSASURISuite) TestGetBlobSASURIContainer(c *chk.C) { + api, err := NewClient("foo", dummyMiniStorageKey, DefaultBaseURL, oldAPIVer, true) + c.Assert(err, chk.IsNil) + cli := api.GetBlobService() + cnt := cli.GetContainerReference("container") + b := cnt.GetBlobReference("") + expiry := time.Time{} + + expectedParts := url.URL{ + Scheme: "https", + Host: "foo.blob.core.windows.net", + Path: "container", + RawQuery: url.Values{ + "sv": {oldAPIVer}, + "sig": {"KMjYyQODKp6uK9EKR3yGhO2M84e1LfoztypU32kHj4s="}, + "sr": {"c"}, + "sp": {"r"}, + "se": {"0001-01-01T00:00:00Z"}, + }.Encode()} + + u, err := b.GetSASURI(expiry, "r") + c.Assert(err, chk.IsNil) + sasParts, err := url.Parse(u) + c.Assert(err, chk.IsNil) + c.Assert(expectedParts.String(), chk.Equals, sasParts.String()) + c.Assert(expectedParts.Query(), chk.DeepEquals, sasParts.Query()) +} + +func (s *BlobSASURISuite) TestGetBlobSASURIWithSignedIPAndProtocolValidAPIVersionPassed(c *chk.C) { + api, err := NewClient("foo", dummyMiniStorageKey, DefaultBaseURL, newerAPIVer, true) + c.Assert(err, chk.IsNil) + cli := api.GetBlobService() + cnt := cli.GetContainerReference("container") + b := cnt.GetBlobReference("name") + expiry := time.Time{} + + expectedParts := url.URL{ + Scheme: "https", + Host: "foo.blob.core.windows.net", + Path: "/container/name", + RawQuery: url.Values{ + "sv": {newerAPIVer}, + "sig": {"VBOYJmt89UuBRXrxNzmsCMoC+8PXX2yklV71QcL1BfM="}, + "sr": {"b"}, + "sip": {"127.0.0.1"}, + "sp": {"r"}, + "se": {"0001-01-01T00:00:00Z"}, + "spr": {"https"}, + }.Encode()} + + u, err := b.GetSASURIWithSignedIPAndProtocol(expiry, "r", "127.0.0.1", true) + c.Assert(err, chk.IsNil) + sasParts, err := url.Parse(u) + c.Assert(err, chk.IsNil) + c.Assert(sasParts.Query(), chk.DeepEquals, expectedParts.Query()) +} + +// Trying to use SignedIP and Protocol but using an older version of the API. +// Should ignore the signedIP/protocol and just use what the older version requires. +func (s *BlobSASURISuite) TestGetBlobSASURIWithSignedIPAndProtocolUsingOldAPIVersion(c *chk.C) { + api, err := NewClient("foo", dummyMiniStorageKey, DefaultBaseURL, oldAPIVer, true) + c.Assert(err, chk.IsNil) + cli := api.GetBlobService() + cnt := cli.GetContainerReference("container") + b := cnt.GetBlobReference("name") + expiry := time.Time{} + + expectedParts := url.URL{ + Scheme: "https", + Host: "foo.blob.core.windows.net", + Path: "/container/name", + RawQuery: url.Values{ + "sv": {oldAPIVer}, + "sig": {"/OXG7rWh08jYwtU03GzJM0DHZtidRGpC6g69rSGm3I0="}, + "sr": {"b"}, + "sp": {"r"}, + "se": {"0001-01-01T00:00:00Z"}, + }.Encode()} + + u, err := b.GetSASURIWithSignedIPAndProtocol(expiry, "r", "", true) + c.Assert(err, chk.IsNil) + sasParts, err := url.Parse(u) + c.Assert(err, chk.IsNil) + c.Assert(expectedParts.String(), chk.Equals, sasParts.String()) + c.Assert(expectedParts.Query(), chk.DeepEquals, sasParts.Query()) +} + +func (s *BlobSASURISuite) TestBlobSASURICorrectness(c *chk.C) { + cli := getBlobClient(c) + + if cli.client.usesDummies() { + c.Skip("As GetSASURI result depends on the account key, it is not practical to test it with a dummy key.") + } + + simpleClient := &http.Client{} + rec := cli.client.appendRecorder(c) + simpleClient.Transport = rec + defer rec.Stop() + + cnt := cli.GetContainerReference(containerName(c)) + c.Assert(cnt.Create(nil), chk.IsNil) + b := cnt.GetBlobReference(contentWithSpecialChars(5)) + defer cnt.Delete(nil) + + body := content(100) + expiry := fixedTime.UTC().Add(time.Hour) + permissions := "r" + + c.Assert(b.putSingleBlockBlob(body), chk.IsNil) + + sasURI, err := b.GetSASURI(expiry, permissions) + c.Assert(err, chk.IsNil) + + resp, err := simpleClient.Get(sasURI) + c.Assert(err, chk.IsNil) + + blobResp, err := ioutil.ReadAll(resp.Body) + defer resp.Body.Close() + c.Assert(err, chk.IsNil) + + c.Assert(resp.StatusCode, chk.Equals, http.StatusOK) + c.Assert(string(blobResp), chk.Equals, string(body)) + +} + +func (s *BlobSASURISuite) Test_blobSASStringToSign(c *chk.C) { + _, err := blobSASStringToSign("2012-02-12", "CS", "SE", "SP", "", "") + c.Assert(err, chk.NotNil) // not implemented SAS for versions earlier than 2013-08-15 + + out, err := blobSASStringToSign(oldAPIVer, "CS", "SE", "SP", "", "") + c.Assert(err, chk.IsNil) + c.Assert(out, chk.Equals, "SP\n\nSE\nCS\n\n2013-08-15\n\n\n\n\n") + + // check format for 2015-04-05 version + out, err = blobSASStringToSign(newerAPIVer, "CS", "SE", "SP", "127.0.0.1", "https,http") + c.Assert(err, chk.IsNil) + c.Assert(out, chk.Equals, "SP\n\nSE\n/blobCS\n\n127.0.0.1\nhttps,http\n2015-04-05\n\n\n\n\n") +} diff --git a/storage/blobserviceclient.go b/storage/blobserviceclient.go index e5911ac81bf9..391defd85391 100644 --- a/storage/blobserviceclient.go +++ b/storage/blobserviceclient.go @@ -1,9 +1,9 @@ package storage import ( - "fmt" "net/http" "net/url" + "strconv" ) // BlobStorageClient contains operations for Microsoft Azure Blob Storage @@ -61,6 +61,9 @@ func (b BlobStorageClient) ListContainers(params ListContainersParameters) (*Con } defer resp.body.Close() err = xmlUnmarshal(resp.body, &out) + if err != nil { + return nil, err + } // assign our client to the newly created Container objects for i := range out.Containers { @@ -82,10 +85,10 @@ func (p ListContainersParameters) getParameters() url.Values { out.Set("include", p.Include) } if p.MaxResults != 0 { - out.Set("maxresults", fmt.Sprintf("%v", p.MaxResults)) + out.Set("maxresults", strconv.FormatUint(uint64(p.MaxResults), 10)) } if p.Timeout != 0 { - out.Set("timeout", fmt.Sprintf("%v", p.Timeout)) + out.Set("timeout", strconv.FormatUint(uint64(p.Timeout), 10)) } return out diff --git a/storage/blockblob.go b/storage/blockblob.go new file mode 100644 index 000000000000..09b13cc18561 --- /dev/null +++ b/storage/blockblob.go @@ -0,0 +1,225 @@ +package storage + +import ( + "bytes" + "encoding/xml" + "fmt" + "io" + "net/http" + "net/url" + "strings" + "time" +) + +// BlockListType is used to filter out types of blocks in a Get Blocks List call +// for a block blob. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179400.aspx for all +// block types. +type BlockListType string + +// Filters for listing blocks in block blobs +const ( + BlockListTypeAll BlockListType = "all" + BlockListTypeCommitted BlockListType = "committed" + BlockListTypeUncommitted BlockListType = "uncommitted" +) + +// Maximum sizes (per REST API) for various concepts +const ( + MaxBlobBlockSize = 100 * 1024 * 1024 + MaxBlobPageSize = 4 * 1024 * 1024 +) + +// BlockStatus defines states a block for a block blob can +// be in. +type BlockStatus string + +// List of statuses that can be used to refer to a block in a block list +const ( + BlockStatusUncommitted BlockStatus = "Uncommitted" + BlockStatusCommitted BlockStatus = "Committed" + BlockStatusLatest BlockStatus = "Latest" +) + +// Block is used to create Block entities for Put Block List +// call. +type Block struct { + ID string + Status BlockStatus +} + +// BlockListResponse contains the response fields from Get Block List call. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179400.aspx +type BlockListResponse struct { + XMLName xml.Name `xml:"BlockList"` + CommittedBlocks []BlockResponse `xml:"CommittedBlocks>Block"` + UncommittedBlocks []BlockResponse `xml:"UncommittedBlocks>Block"` +} + +// BlockResponse contains the block information returned +// in the GetBlockListCall. +type BlockResponse struct { + Name string `xml:"Name"` + Size int64 `xml:"Size"` +} + +// CreateBlockBlob initializes an empty block blob with no blocks. +// +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Put-Blob +func (b *Blob) CreateBlockBlob(options *PutBlobOptions) error { + return b.CreateBlockBlobFromReader(nil, options) +} + +// CreateBlockBlobFromReader initializes a block blob using data from +// reader. Size must be the number of bytes read from reader. To +// create an empty blob, use size==0 and reader==nil. +// +// The API rejects requests with size > 256 MiB (but this limit is not +// checked by the SDK). To write a larger blob, use CreateBlockBlob, +// PutBlock, and PutBlockList. +// +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Put-Blob +func (b *Blob) CreateBlockBlobFromReader(blob io.Reader, options *PutBlobOptions) error { + params := url.Values{} + headers := b.Container.bsc.client.getStandardHeaders() + headers["x-ms-blob-type"] = string(BlobTypeBlock) + headers["Content-Length"] = fmt.Sprintf("%d", b.Properties.ContentLength) + 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, blob, b.Container.bsc.auth) + if err != nil { + return err + } + readAndCloseBody(resp.body) + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// PutBlockOptions includes the options for a put block operation +type PutBlockOptions struct { + Timeout uint + LeaseID string `header:"x-ms-lease-id"` + ContentMD5 string `header:"Content-MD5"` + RequestID string `header:"x-ms-client-request-id"` +} + +// PutBlock saves the given data chunk to the specified block blob with +// given ID. +// +// The API rejects chunks larger than 100 MiB (but this limit is not +// checked by the SDK). +// +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Put-Block +func (b *Blob) PutBlock(blockID string, chunk []byte, options *PutBlockOptions) error { + return b.PutBlockWithLength(blockID, uint64(len(chunk)), bytes.NewReader(chunk), options) +} + +// PutBlockWithLength saves the given data stream of exactly specified size to +// the block blob with given ID. It is an alternative to PutBlocks where data +// comes as stream but the length is known in advance. +// +// The API rejects requests with size > 100 MiB (but this limit is not +// checked by the SDK). +// +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Put-Block +func (b *Blob) PutBlockWithLength(blockID string, size uint64, blob io.Reader, options *PutBlockOptions) error { + query := url.Values{ + "comp": {"block"}, + "blockid": {blockID}, + } + headers := b.Container.bsc.client.getStandardHeaders() + headers["Content-Length"] = fmt.Sprintf("%v", size) + + if options != nil { + query = addTimeout(query, options.Timeout) + headers = mergeHeaders(headers, headersFromStruct(*options)) + } + uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), query) + + resp, err := b.Container.bsc.client.exec(http.MethodPut, uri, headers, blob, b.Container.bsc.auth) + if err != nil { + return err + } + readAndCloseBody(resp.body) + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// PutBlockListOptions includes the options for a put block list operation +type PutBlockListOptions struct { + Timeout uint + LeaseID string `header:"x-ms-lease-id"` + 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"` +} + +// PutBlockList saves list of blocks to the specified block blob. +// +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Put-Block-List +func (b *Blob) PutBlockList(blocks []Block, options *PutBlockListOptions) error { + params := url.Values{"comp": {"blocklist"}} + blockListXML := prepareBlockListRequest(blocks) + headers := b.Container.bsc.client.getStandardHeaders() + headers["Content-Length"] = fmt.Sprintf("%v", len(blockListXML)) + 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, strings.NewReader(blockListXML), b.Container.bsc.auth) + if err != nil { + return err + } + readAndCloseBody(resp.body) + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// GetBlockListOptions includes the options for a get block list operation +type GetBlockListOptions struct { + Timeout uint + Snapshot *time.Time + LeaseID string `header:"x-ms-lease-id"` + RequestID string `header:"x-ms-client-request-id"` +} + +// GetBlockList retrieves list of blocks in the specified block blob. +// +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Get-Block-List +func (b *Blob) GetBlockList(blockType BlockListType, options *GetBlockListOptions) (BlockListResponse, error) { + params := url.Values{ + "comp": {"blocklist"}, + "blocklisttype": {string(blockType)}, + } + headers := b.Container.bsc.client.getStandardHeaders() + + if options != nil { + params = addTimeout(params, options.Timeout) + params = addSnapshot(params, options.Snapshot) + headers = mergeHeaders(headers, headersFromStruct(*options)) + } + uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), params) + + var out BlockListResponse + resp, err := b.Container.bsc.client.exec(http.MethodGet, uri, headers, nil, b.Container.bsc.auth) + if err != nil { + return out, err + } + defer resp.body.Close() + + err = xmlUnmarshal(resp.body, &out) + return out, err +} diff --git a/storage/blockblob_test.go b/storage/blockblob_test.go new file mode 100644 index 000000000000..b639fc7a65fd --- /dev/null +++ b/storage/blockblob_test.go @@ -0,0 +1,152 @@ +package storage + +import ( + "bytes" + "encoding/base64" + "io/ioutil" + + chk "gopkg.in/check.v1" +) + +type BlockBlobSuite struct{} + +var _ = chk.Suite(&BlockBlobSuite{}) + +func (s *BlockBlobSuite) TestCreateBlockBlobFromReader(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) + + data := content(8888) + b.Properties.ContentLength = int64(len(data)) + c.Assert(b.CreateBlockBlobFromReader(bytes.NewReader(data), nil), chk.IsNil) + + resp, err := b.Get(nil) + c.Assert(err, chk.IsNil) + gotData, err := ioutil.ReadAll(resp) + defer resp.Close() + + c.Assert(err, chk.IsNil) + c.Assert(gotData, chk.DeepEquals, data) +} + +func (s *BlockBlobSuite) TestCreateBlockBlobFromReaderWithShortData(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) + + data := content(8888) + b.Properties.ContentLength = 9999 + err := b.CreateBlockBlobFromReader(bytes.NewReader(data), nil) + c.Assert(err, chk.NotNil) + + _, err = b.Get(nil) + // Upload was incomplete: blob should not have been created. + c.Assert(err, chk.NotNil) +} + +func (s *BlockBlobSuite) TestPutBlock(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) + + chunk := content(1024) + blockID := base64.StdEncoding.EncodeToString([]byte("lol")) + c.Assert(b.PutBlock(blockID, chunk, nil), chk.IsNil) +} + +func (s *BlockBlobSuite) TestGetBlockList_PutBlockList(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) + + chunk := content(1024) + blockID := base64.StdEncoding.EncodeToString([]byte("lol")) + + // Put one block + c.Assert(b.PutBlock(blockID, chunk, nil), chk.IsNil) + defer b.Delete(nil) + + // Get committed blocks + committed, err := b.GetBlockList(BlockListTypeCommitted, nil) + c.Assert(err, chk.IsNil) + + if len(committed.CommittedBlocks) > 0 { + c.Fatal("There are committed blocks") + } + + // Get uncommitted blocks + uncommitted, err := b.GetBlockList(BlockListTypeUncommitted, nil) + c.Assert(err, chk.IsNil) + + c.Assert(len(uncommitted.UncommittedBlocks), chk.Equals, 1) + // Commit block list + c.Assert(b.PutBlockList([]Block{{blockID, BlockStatusUncommitted}}, nil), chk.IsNil) + + // Get all blocks + all, err := b.GetBlockList(BlockListTypeAll, nil) + c.Assert(err, chk.IsNil) + c.Assert(len(all.CommittedBlocks), chk.Equals, 1) + c.Assert(len(all.UncommittedBlocks), chk.Equals, 0) + + // Verify the block + thatBlock := all.CommittedBlocks[0] + c.Assert(thatBlock.Name, chk.Equals, blockID) + c.Assert(thatBlock.Size, chk.Equals, int64(len(chunk))) +} + +func (s *BlockBlobSuite) TestCreateBlockBlob(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.CreateBlockBlob(nil), chk.IsNil) + + // Verify + blocks, err := b.GetBlockList(BlockListTypeAll, nil) + c.Assert(err, chk.IsNil) + c.Assert(len(blocks.CommittedBlocks), chk.Equals, 0) + c.Assert(len(blocks.UncommittedBlocks), chk.Equals, 0) +} + +func (s *BlockBlobSuite) TestPutEmptyBlockBlob(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.putSingleBlockBlob([]byte("Hello!")), chk.IsNil) + + err := b.GetProperties(nil) + c.Assert(err, chk.IsNil) + c.Assert(b.Properties.ContentLength, chk.Not(chk.Equals), 0) +} diff --git a/storage/client.go b/storage/client.go index e42082d4f6bc..987573f1f61e 100644 --- a/storage/client.go +++ b/storage/client.go @@ -2,6 +2,7 @@ package storage import ( + "bufio" "bytes" "encoding/base64" "encoding/json" @@ -10,12 +11,16 @@ import ( "fmt" "io" "io/ioutil" + "mime" + "mime/multipart" "net/http" "net/url" "runtime" "strconv" "strings" + "time" + "github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest/azure" ) @@ -26,7 +31,7 @@ const ( // DefaultAPIVersion is the Azure Storage API version string used when a // basic client is created. - DefaultAPIVersion = "2015-04-05" + DefaultAPIVersion = "2016-05-31" defaultUseHTTPS = true @@ -46,15 +51,62 @@ const ( storageEmulatorQueue = "127.0.0.1:10001" userAgentHeader = "User-Agent" + + userDefinedMetadataHeaderPrefix = "x-ms-meta-" ) +// Sender sends a request +type Sender interface { + Send(*Client, *http.Request) (*http.Response, error) +} + +// DefaultSender is the default sender for the client. It implements +// an automatic retry strategy. +type DefaultSender struct { + RetryAttempts int + RetryDuration time.Duration + ValidStatusCodes []int + attempts int // used for testing +} + +// Send is the default retry strategy in the client +func (ds *DefaultSender) Send(c *Client, req *http.Request) (resp *http.Response, err error) { + b := []byte{} + if req.Body != nil { + b, err = ioutil.ReadAll(req.Body) + if err != nil { + return resp, err + } + } + + for attempts := 0; attempts < ds.RetryAttempts; attempts++ { + if len(b) > 0 { + req.Body = ioutil.NopCloser(bytes.NewBuffer(b)) + } + resp, err = c.HTTPClient.Do(req) + if err != nil || !autorest.ResponseHasStatusCode(resp, ds.ValidStatusCodes...) { + return resp, err + } + autorest.DelayForBackoff(ds.RetryDuration, attempts, req.Cancel) + ds.attempts = attempts + } + ds.attempts++ + return resp, err +} + // Client is the object that needs to be constructed to perform // operations on the storage account. type Client struct { // HTTPClient is the http.Client used to initiate API - // requests. If it is nil, http.DefaultClient is used. + // requests. http.DefaultClient is used when creating a + // client. HTTPClient *http.Client + // Sender is an interface that sends the request. Clients are + // created with a DefaultSender. The DefaultSender has an + // automatic retry strategy built in. The Sender can be customized. + Sender Sender + accountName string accountKey []byte useHTTPS bool @@ -87,6 +139,8 @@ type AzureStorageServiceError struct { Reason string `xml:"Reason"` StatusCode int RequestID string + Date string + APIVersion string } type odataErrorMessageMessage struct { @@ -169,19 +223,31 @@ func NewClient(accountName, accountKey, blobServiceBaseURL, apiVersion string, u } c = Client{ + HTTPClient: http.DefaultClient, accountName: accountName, accountKey: key, useHTTPS: useHTTPS, baseURL: blobServiceBaseURL, apiVersion: apiVersion, UseSharedKeyLite: false, + Sender: &DefaultSender{ + RetryAttempts: 5, + ValidStatusCodes: []int{ + http.StatusRequestTimeout, // 408 + http.StatusInternalServerError, // 500 + http.StatusBadGateway, // 502 + http.StatusServiceUnavailable, // 503 + http.StatusGatewayTimeout, // 504 + }, + RetryDuration: time.Second * 5, + }, } c.userAgent = c.getDefaultUserAgent() return c, nil } func (c Client) getDefaultUserAgent() string { - return fmt.Sprintf("Go/%s (%s-%s) Azure-SDK-For-Go/%s storage-dataplane/%s", + return fmt.Sprintf("Go/%s (%s-%s) azure-storage-go/%s api-version/%s", runtime.Version(), runtime.GOARCH, runtime.GOOS, @@ -345,11 +411,7 @@ func (c Client) exec(verb, url string, headers map[string]string, body io.Reader req.Header.Add(k, v) } - httpClient := c.HTTPClient - if httpClient == nil { - httpClient = http.DefaultClient - } - resp, err := httpClient.Do(req) + resp, err := c.Sender.Send(&c, req) if err != nil { return nil, err } @@ -362,13 +424,13 @@ func (c Client) exec(verb, url string, headers map[string]string, body io.Reader return nil, err } - requestID := resp.Header.Get("x-ms-request-id") + requestID, date, version := getDebugHeaders(resp.Header) if len(respBody) == 0 { // no error in response body, might happen in HEAD requests - err = serviceErrFromStatusCode(resp.StatusCode, resp.Status, requestID) + err = serviceErrFromStatusCode(resp.StatusCode, resp.Status, requestID, date, version) } else { // response contains storage service error object, unmarshal - storageErr, errIn := serviceErrFromXML(respBody, resp.StatusCode, requestID) + storageErr, errIn := serviceErrFromXML(respBody, resp.StatusCode, requestID, date, version) if err != nil { // error unmarshaling the error response err = errIn } @@ -387,10 +449,10 @@ func (c Client) exec(verb, url string, headers map[string]string, body io.Reader body: resp.Body}, nil } -func (c Client) execInternalJSON(verb, url string, headers map[string]string, body io.Reader, auth authentication) (*odataResponse, error) { +func (c Client) execInternalJSONCommon(verb, url string, headers map[string]string, body io.Reader, auth authentication) (*odataResponse, *http.Request, *http.Response, error) { headers, err := c.addAuthorizationHeader(verb, url, headers, auth) if err != nil { - return nil, err + return nil, nil, nil, err } req, err := http.NewRequest(verb, url, body) @@ -398,14 +460,9 @@ func (c Client) execInternalJSON(verb, url string, headers map[string]string, bo req.Header.Add(k, v) } - httpClient := c.HTTPClient - if httpClient == nil { - httpClient = http.DefaultClient - } - - resp, err := httpClient.Do(req) + resp, err := c.Sender.Send(&c, req) if err != nil { - return nil, err + return nil, nil, nil, err } respToRet := &odataResponse{} @@ -418,22 +475,110 @@ func (c Client) execInternalJSON(verb, url string, headers map[string]string, bo var respBody []byte respBody, err = readAndCloseBody(resp.Body) if err != nil { - return nil, err + return nil, nil, nil, err } + requestID, date, version := getDebugHeaders(resp.Header) if len(respBody) == 0 { // no error in response body, might happen in HEAD requests - err = serviceErrFromStatusCode(resp.StatusCode, resp.Status, resp.Header.Get("x-ms-request-id")) - return respToRet, err + err = serviceErrFromStatusCode(resp.StatusCode, resp.Status, requestID, date, version) + return respToRet, req, resp, err } // try unmarshal as odata.error json err = json.Unmarshal(respBody, &respToRet.odata) - return respToRet, err + } + + return respToRet, req, resp, err +} + +func (c Client) execInternalJSON(verb, url string, headers map[string]string, body io.Reader, auth authentication) (*odataResponse, error) { + respToRet, _, _, err := c.execInternalJSONCommon(verb, url, headers, body, auth) + return respToRet, err +} + +func (c Client) execBatchOperationJSON(verb, url string, headers map[string]string, body io.Reader, auth authentication) (*odataResponse, error) { + // execute common query, get back generated request, response etc... for more processing. + respToRet, req, resp, err := c.execInternalJSONCommon(verb, url, headers, body, auth) + if err != nil { + return nil, err + } + + // return the OData in the case of executing batch commands. + // In this case we need to read the outer batch boundary and contents. + // Then we read the changeset information within the batch + var respBody []byte + respBody, err = readAndCloseBody(resp.Body) + if err != nil { + return nil, err + } + + // outer multipart body + _, batchHeader, err := mime.ParseMediaType(resp.Header["Content-Type"][0]) + if err != nil { + return nil, err + } + + // batch details. + batchBoundary := batchHeader["boundary"] + batchPartBuf, changesetBoundary, err := genBatchReader(batchBoundary, respBody) + if err != nil { + return nil, err + } + + // changeset details. + err = genChangesetReader(req, respToRet, batchPartBuf, changesetBoundary) + if err != nil { + return nil, err } return respToRet, nil } +func genChangesetReader(req *http.Request, respToRet *odataResponse, batchPartBuf io.Reader, changesetBoundary string) error { + changesetMultiReader := multipart.NewReader(batchPartBuf, changesetBoundary) + changesetPart, err := changesetMultiReader.NextPart() + if err != nil { + return err + } + + changesetPartBufioReader := bufio.NewReader(changesetPart) + changesetResp, err := http.ReadResponse(changesetPartBufioReader, req) + if err != nil { + return err + } + + if changesetResp.StatusCode != http.StatusNoContent { + changesetBody, err := readAndCloseBody(changesetResp.Body) + err = json.Unmarshal(changesetBody, &respToRet.odata) + if err != nil { + return err + } + respToRet.statusCode = changesetResp.StatusCode + } + + return nil +} + +func genBatchReader(batchBoundary string, respBody []byte) (io.Reader, string, error) { + respBodyString := string(respBody) + respBodyReader := strings.NewReader(respBodyString) + + // reading batchresponse + batchMultiReader := multipart.NewReader(respBodyReader, batchBoundary) + batchPart, err := batchMultiReader.NextPart() + if err != nil { + return nil, "", err + } + batchPartBufioReader := bufio.NewReader(batchPart) + + _, changesetHeader, err := mime.ParseMediaType(batchPart.Header.Get("Content-Type")) + if err != nil { + return nil, "", err + } + changesetBoundary := changesetHeader["boundary"] + return batchPartBufioReader, changesetBoundary, nil +} + func readAndCloseBody(body io.ReadCloser) ([]byte, error) { defer body.Close() out, err := ioutil.ReadAll(body) @@ -443,28 +588,34 @@ func readAndCloseBody(body io.ReadCloser) ([]byte, error) { return out, err } -func serviceErrFromXML(body []byte, statusCode int, requestID string) (AzureStorageServiceError, error) { - var storageErr AzureStorageServiceError +func serviceErrFromXML(body []byte, statusCode int, requestID, date, version string) (AzureStorageServiceError, error) { + storageErr := AzureStorageServiceError{ + StatusCode: statusCode, + RequestID: requestID, + Date: date, + APIVersion: version, + } if err := xml.Unmarshal(body, &storageErr); err != nil { + storageErr.Message = fmt.Sprintf("Response body could no be unmarshaled: %v. Body: %v.", err, string(body)) return storageErr, err } - storageErr.StatusCode = statusCode - storageErr.RequestID = requestID return storageErr, nil } -func serviceErrFromStatusCode(code int, status string, requestID string) AzureStorageServiceError { +func serviceErrFromStatusCode(code int, status string, requestID, date, version string) AzureStorageServiceError { return AzureStorageServiceError{ StatusCode: code, Code: status, RequestID: requestID, + Date: date, + APIVersion: version, Message: "no response body was available for error status code", } } func (e AzureStorageServiceError) Error() string { - return fmt.Sprintf("storage: service returned error: StatusCode=%d, ErrorCode=%s, ErrorMessage=%s, RequestId=%s, QueryParameterName=%s, QueryParameterValue=%s", - e.StatusCode, e.Code, e.Message, e.RequestID, e.QueryParameterName, e.QueryParameterValue) + return fmt.Sprintf("storage: service returned error: StatusCode=%d, ErrorCode=%s, ErrorMessage=%s, RequestInitiated=%s, RequestId=%s, API Version=%s, QueryParameterName=%s, QueryParameterValue=%s", + e.StatusCode, e.Code, e.Message, e.Date, e.RequestID, e.APIVersion, e.QueryParameterName, e.QueryParameterValue) } // checkRespCode returns UnexpectedStatusError if the given response code is not @@ -477,3 +628,18 @@ func checkRespCode(respCode int, allowed []int) error { } return UnexpectedStatusCodeError{allowed, respCode} } + +func (c Client) addMetadataToHeaders(h map[string]string, metadata map[string]string) map[string]string { + metadata = c.protectUserAgent(metadata) + for k, v := range metadata { + h[userDefinedMetadataHeaderPrefix+k] = v + } + return h +} + +func getDebugHeaders(h http.Header) (requestID, date, version string) { + requestID = h.Get("x-ms-request-id") + version = h.Get("x-ms-version") + date = h.Get("Date") + return +} diff --git a/storage/client_test.go b/storage/client_test.go index a1c25d9acc54..3b4fe3ab8480 100644 --- a/storage/client_test.go +++ b/storage/client_test.go @@ -1,13 +1,24 @@ package storage import ( + "bytes" "encoding/base64" + "io/ioutil" + "math" "net/http" "net/url" "os" + "path/filepath" + "reflect" + "regexp" + "strconv" + "strings" "testing" "time" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/dnaeon/go-vcr/cassette" + "github.com/dnaeon/go-vcr/recorder" chk "gopkg.in/check.v1" ) @@ -18,21 +29,164 @@ type StorageClientSuite struct{} var _ = chk.Suite(&StorageClientSuite{}) -var now = time.Now() - // getBasicClient returns a test client from storage credentials in the env -func getBasicClient(c *chk.C) Client { +func getBasicClient(c *chk.C) *Client { name := os.Getenv("ACCOUNT_NAME") if name == "" { - c.Fatal("ACCOUNT_NAME not set, need an empty storage account to test") + name = dummyStorageAccount } key := os.Getenv("ACCOUNT_KEY") if key == "" { - c.Fatal("ACCOUNT_KEY not set") + key = dummyMiniStorageKey } cli, err := NewBasicClient(name, key) c.Assert(err, chk.IsNil) - return cli + + return &cli +} + +func (client *Client) appendRecorder(c *chk.C) *recorder.Recorder { + tests := strings.Split(c.TestName(), ".") + path := filepath.Join(recordingsFolder, tests[0], tests[1]) + rec, err := recorder.New(path) + c.Assert(err, chk.IsNil) + client.HTTPClient = &http.Client{ + Transport: rec, + } + rec.SetMatcher(func(r *http.Request, i cassette.Request) bool { + return compareMethods(r, i) && + compareURLs(r, i) && + compareHeaders(r, i) && + compareBodies(r, i) + }) + return rec +} + +func (client *Client) usesDummies() bool { + key, err := base64.StdEncoding.DecodeString(dummyMiniStorageKey) + if err != nil { + return false + } + if string(client.accountKey) == string(key) && + client.accountName == dummyStorageAccount { + return true + } + return false +} + +func compareMethods(r *http.Request, i cassette.Request) bool { + return r.Method == i.Method +} + +func compareURLs(r *http.Request, i cassette.Request) bool { + newURL := modifyURL(r.URL) + return newURL.String() == i.URL +} + +func modifyURL(url *url.URL) *url.URL { + // The URL host looks like this... + // accountname.service.storageEndpointSuffix + parts := strings.Split(url.Host, ".") + // parts[0] corresponds to the storage account name, so it can be (almost) any string + // parts[1] corresponds to the service name (table, blob, etc.). + if !(parts[1] == blobServiceName || + parts[1] == tableServiceName || + parts[1] == queueServiceName || + parts[1] == fileServiceName) { + return nil + } + // The rest of the host depends on which Azure cloud is used + storageEndpointSuffix := strings.Join(parts[2:], ".") + if !(storageEndpointSuffix == azure.PublicCloud.StorageEndpointSuffix || + storageEndpointSuffix == azure.USGovernmentCloud.StorageEndpointSuffix || + storageEndpointSuffix == azure.ChinaCloud.StorageEndpointSuffix || + storageEndpointSuffix == azure.GermanCloud.StorageEndpointSuffix) { + return nil + } + + host := dummyStorageAccount + "." + parts[1] + "." + azure.PublicCloud.StorageEndpointSuffix + newURL := url + newURL.Host = host + return newURL +} + +func compareHeaders(r *http.Request, i cassette.Request) bool { + requestHeaders := r.Header + cassetteHeaders := i.Headers + // Some headers shall not be compared... + requestHeaders.Del("User-Agent") + requestHeaders.Del("Authorization") + requestHeaders.Del("X-Ms-Date") + + cassetteHeaders.Del("User-Agent") + cassetteHeaders.Del("Authorization") + cassetteHeaders.Del("X-Ms-Date") + + srcURLstr := requestHeaders.Get("X-Ms-Copy-Source") + if srcURLstr != "" { + srcURL, err := url.Parse(srcURLstr) + if err != nil { + return false + } + modifiedURL := modifyURL(srcURL) + requestHeaders.Set("X-Ms-Copy-Source", modifiedURL.String()) + } + + // Do not compare the complete Content-Type header in table batch requests + if isBatchOp(r.URL.String()) { + // They all start like this, but then they have a UUID... + ctPrefixBatch := "multipart/mixed; boundary=batch_" + contentTypeRequest := requestHeaders.Get("Content-Type") + contentTypeCassette := cassetteHeaders.Get("Content-Type") + if !(strings.HasPrefix(contentTypeRequest, ctPrefixBatch) && + strings.HasPrefix(contentTypeCassette, ctPrefixBatch)) { + return false + } + requestHeaders.Del("Content-Type") + cassetteHeaders.Del("Content-Type") + } + + return reflect.DeepEqual(requestHeaders, cassetteHeaders) +} + +func compareBodies(r *http.Request, i cassette.Request) bool { + body := bytes.Buffer{} + if r.Body != nil { + _, err := body.ReadFrom(r.Body) + if err != nil { + return false + } + r.Body = ioutil.NopCloser(&body) + } + // Comparing bodies in table batch operations is trickier, because the bodies include UUIDs + if isBatchOp(r.URL.String()) { + return compareBatchBodies(body.String(), i.Body) + } + return body.String() == i.Body +} + +func compareBatchBodies(rBody, cBody string) bool { + // UUIDs in the batch body look like this... + // 2d7f2323-1e42-11e7-8c6c-6451064d81e8 + exp, err := regexp.Compile("[0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12}") + if err != nil { + return false + } + rBody = replaceStorageAccount(replaceUUIDs(rBody, exp)) + cBody = replaceUUIDs(cBody, exp) + return rBody == cBody +} + +func replaceUUIDs(body string, exp *regexp.Regexp) string { + indexes := exp.FindAllStringIndex(body, -1) + for _, pair := range indexes { + body = strings.Replace(body, body[pair[0]:pair[1]], "00000000-0000-0000-0000-000000000000", -1) + } + return body +} + +func isBatchOp(url string) bool { + return url == "https://golangrocksonazure.table.core.windows.net/$batch" } //getEmulatorClient returns a test client for Azure Storeage Emulator @@ -52,24 +206,24 @@ func (s *StorageClientSuite) TestNewEmulatorClient(c *chk.C) { } func (s *StorageClientSuite) TestMalformedKeyError(c *chk.C) { - _, err := NewBasicClient("foo", "malformed") + _, err := NewBasicClient(dummyStorageAccount, "malformed") c.Assert(err, chk.ErrorMatches, "azure: malformed storage account key: .*") } func (s *StorageClientSuite) TestGetBaseURL_Basic_Https(c *chk.C) { - cli, err := NewBasicClient("foo", "YmFy") + cli, err := NewBasicClient(dummyStorageAccount, dummyMiniStorageKey) c.Assert(err, chk.IsNil) c.Assert(cli.apiVersion, chk.Equals, DefaultAPIVersion) c.Assert(err, chk.IsNil) - c.Assert(cli.getBaseURL("table"), chk.Equals, "https://foo.table.core.windows.net") + c.Assert(cli.getBaseURL("table"), chk.Equals, "https://golangrocksonazure.table.core.windows.net") } func (s *StorageClientSuite) TestGetBaseURL_Custom_NoHttps(c *chk.C) { apiVersion := "2015-01-01" // a non existing one - cli, err := NewClient("foo", "YmFy", "core.chinacloudapi.cn", apiVersion, false) + cli, err := NewClient(dummyStorageAccount, dummyMiniStorageKey, "core.chinacloudapi.cn", apiVersion, false) c.Assert(err, chk.IsNil) c.Assert(cli.apiVersion, chk.Equals, apiVersion) - c.Assert(cli.getBaseURL("table"), chk.Equals, "http://foo.table.core.chinacloudapi.cn") + c.Assert(cli.getBaseURL("table"), chk.Equals, "http://golangrocksonazure.table.core.chinacloudapi.cn") } func (s *StorageClientSuite) TestGetBaseURL_StorageEmulator(c *chk.C) { @@ -89,37 +243,37 @@ func (s *StorageClientSuite) TestGetBaseURL_StorageEmulator(c *chk.C) { } func (s *StorageClientSuite) TestGetEndpoint_None(c *chk.C) { - cli, err := NewBasicClient("foo", "YmFy") + cli, err := NewBasicClient(dummyStorageAccount, "YmFy") c.Assert(err, chk.IsNil) output := cli.getEndpoint(blobServiceName, "", url.Values{}) - c.Assert(output, chk.Equals, "https://foo.blob.core.windows.net/") + c.Assert(output, chk.Equals, "https://golangrocksonazure.blob.core.windows.net/") } func (s *StorageClientSuite) TestGetEndpoint_PathOnly(c *chk.C) { - cli, err := NewBasicClient("foo", "YmFy") + cli, err := NewBasicClient(dummyStorageAccount, "YmFy") c.Assert(err, chk.IsNil) output := cli.getEndpoint(blobServiceName, "path", url.Values{}) - c.Assert(output, chk.Equals, "https://foo.blob.core.windows.net/path") + c.Assert(output, chk.Equals, "https://golangrocksonazure.blob.core.windows.net/path") } func (s *StorageClientSuite) TestGetEndpoint_ParamsOnly(c *chk.C) { - cli, err := NewBasicClient("foo", "YmFy") + cli, err := NewBasicClient(dummyStorageAccount, "YmFy") c.Assert(err, chk.IsNil) params := url.Values{} params.Set("a", "b") params.Set("c", "d") output := cli.getEndpoint(blobServiceName, "", params) - c.Assert(output, chk.Equals, "https://foo.blob.core.windows.net/?a=b&c=d") + c.Assert(output, chk.Equals, "https://golangrocksonazure.blob.core.windows.net/?a=b&c=d") } func (s *StorageClientSuite) TestGetEndpoint_Mixed(c *chk.C) { - cli, err := NewBasicClient("foo", "YmFy") + cli, err := NewBasicClient(dummyStorageAccount, "YmFy") c.Assert(err, chk.IsNil) params := url.Values{} params.Set("a", "b") params.Set("c", "d") output := cli.getEndpoint(blobServiceName, "path", params) - c.Assert(output, chk.Equals, "https://foo.blob.core.windows.net/path?a=b&c=d") + c.Assert(output, chk.Equals, "https://golangrocksonazure.blob.core.windows.net/path?a=b&c=d") } func (s *StorageClientSuite) TestGetEndpoint_StorageEmulator(c *chk.C) { @@ -139,7 +293,7 @@ func (s *StorageClientSuite) TestGetEndpoint_StorageEmulator(c *chk.C) { } func (s *StorageClientSuite) Test_getStandardHeaders(c *chk.C) { - cli, err := NewBasicClient("foo", "YmFy") + cli, err := NewBasicClient(dummyStorageAccount, "YmFy") c.Assert(err, chk.IsNil) headers := cli.getStandardHeaders() @@ -154,8 +308,11 @@ func (s *StorageClientSuite) Test_getStandardHeaders(c *chk.C) { func (s *StorageClientSuite) TestReturnsStorageServiceError(c *chk.C) { // attempt to delete a nonexisting container cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - _, err := cnt.delete() + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + cnt := cli.GetContainerReference(containerName(c)) + _, err := cnt.delete(nil) c.Assert(err, chk.NotNil) v, ok := err.(AzureStorageServiceError) @@ -168,7 +325,13 @@ func (s *StorageClientSuite) TestReturnsStorageServiceError(c *chk.C) { func (s *StorageClientSuite) TestReturnsStorageServiceError_withoutResponseBody(c *chk.C) { // HEAD on non-existing blob - _, err := getBlobClient(c).GetBlobProperties("non-existing-blob", "non-existing-container") + cli := getBlobClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + cnt := cli.GetContainerReference("non-existing-container") + b := cnt.GetBlobReference("non-existing-blob") + err := b.GetProperties(nil) c.Assert(err, chk.NotNil) c.Assert(err, chk.FitsTypeOf, AzureStorageServiceError{}) @@ -182,7 +345,7 @@ func (s *StorageClientSuite) TestReturnsStorageServiceError_withoutResponseBody( } func (s *StorageClientSuite) Test_createServiceClients(c *chk.C) { - cli, err := NewBasicClient("foo", "YmFy") + cli, err := NewBasicClient(dummyStorageAccount, "YmFy") c.Assert(err, chk.IsNil) ua := cli.getDefaultUserAgent() @@ -209,14 +372,14 @@ func (s *StorageClientSuite) Test_createServiceClients(c *chk.C) { } func (s *StorageClientSuite) TestAddToUserAgent(c *chk.C) { - cli, err := NewBasicClient("foo", "YmFy") + cli, err := NewBasicClient(dummyStorageAccount, "YmFy") c.Assert(err, chk.IsNil) ua := cli.getDefaultUserAgent() - err = cli.AddToUserAgent("bar") + err = cli.AddToUserAgent("rofl") c.Assert(err, chk.IsNil) - c.Assert(cli.userAgent, chk.Equals, ua+" bar") + c.Assert(cli.userAgent, chk.Equals, ua+" rofl") err = cli.AddToUserAgent("") c.Assert(err, chk.NotNil) @@ -230,7 +393,7 @@ func (s *StorageClientSuite) Test_protectUserAgent(c *chk.C) { userAgentHeader: "four", } - cli, err := NewBasicClient("foo", "YmFy") + cli, err := NewBasicClient(dummyStorageAccount, "YmFy") c.Assert(err, chk.IsNil) ua := cli.getDefaultUserAgent() @@ -244,3 +407,47 @@ func (s *StorageClientSuite) Test_protectUserAgent(c *chk.C) { "3": "three", }) } + +func (s *StorageClientSuite) Test_doRetry(c *chk.C) { + cli := getBasicClient(c) + rec := cli.appendRecorder(c) + defer rec.Stop() + + // Prepare request that will fail with 404 (delete non extising table) + uri, err := url.Parse(cli.getEndpoint(tableServiceName, "(retry)", url.Values{"timeout": {strconv.Itoa(30)}})) + c.Assert(err, chk.IsNil) + req := http.Request{ + Method: http.MethodDelete, + URL: uri, + Header: http.Header{ + "Accept": {"application/json;odata=nometadata"}, + "Prefer": {"return-no-content"}, + "X-Ms-Version": {"2016-05-31"}, + }, + } + + ds, ok := cli.Sender.(*DefaultSender) + c.Assert(ok, chk.Equals, true) + // Modify sender so it retries quickly + ds.RetryAttempts = 3 + ds.RetryDuration = time.Second + // include 404 as a valid status code for retries + ds.ValidStatusCodes = []int{http.StatusNotFound} + cli.Sender = ds + + now := time.Now() + resp, err := cli.Sender.Send(cli, &req) + afterRetries := time.Since(now) + c.Assert(err, chk.IsNil) + c.Assert(resp.StatusCode, chk.Equals, http.StatusNotFound) + + // Was it the correct amount of retries... ? + c.Assert(cli.Sender.(*DefaultSender).attempts, chk.Equals, cli.Sender.(*DefaultSender).RetryAttempts) + // What about time... ? + // Note, seconds are rounded + sum := 0 + for i := 0; i < ds.RetryAttempts; i++ { + sum += int(ds.RetryDuration.Seconds() * math.Pow(2, float64(i))) // same formula used in autorest.DelayForBackoff + } + c.Assert(int(afterRetries.Seconds()), chk.Equals, sum) +} diff --git a/storage/container.go b/storage/container.go index f064239674ef..4096a2ab81f5 100644 --- a/storage/container.go +++ b/storage/container.go @@ -8,6 +8,7 @@ import ( "net/http" "net/url" "strconv" + "strings" "time" ) @@ -16,6 +17,7 @@ type Container struct { bsc *BlobStorageClient Name string `xml:"Name"` Properties ContainerProperties `xml:"Properties"` + Metadata map[string]string } func (c *Container) buildPath() string { @@ -69,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. // @@ -77,9 +87,10 @@ type ListBlobsParameters struct { Prefix string Delimiter string Marker string - Include string + Include *IncludeBlobDataset MaxResults uint Timeout uint + RequestID string } func (p ListBlobsParameters) getParameters() url.Values { @@ -94,19 +105,32 @@ 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", fmt.Sprintf("%v", p.MaxResults)) + out.Set("maxresults", strconv.FormatUint(uint64(p.MaxResults), 10)) } if p.Timeout != 0 { - out.Set("timeout", fmt.Sprintf("%v", p.Timeout)) + out.Set("timeout", strconv.FormatUint(uint64(p.Timeout), 10)) } 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. // @@ -142,23 +166,38 @@ const ( ContainerAccessHeader string = "x-ms-blob-public-access" ) +// GetBlobReference returns a Blob object for the specified blob name. +func (c *Container) GetBlobReference(name string) Blob { + return Blob{ + Container: c, + Name: name, + } +} + +// CreateContainerOptions includes the options for a create container operation +type CreateContainerOptions struct { + Timeout uint + Access ContainerAccessType `header:"x-ms-blob-public-access"` + RequestID string `header:"x-ms-client-request-id"` +} + // Create creates a blob container within the storage account // with given name and access level. Returns error if container already exists. // -// See https://msdn.microsoft.com/en-us/library/azure/dd179468.aspx -func (c *Container) Create() error { - resp, err := c.create() +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Create-Container +func (c *Container) Create(options *CreateContainerOptions) error { + resp, err := c.create(options) if err != nil { return err } - defer readAndCloseBody(resp.body) + readAndCloseBody(resp.body) return checkRespCode(resp.statusCode, []int{http.StatusCreated}) } // CreateIfNotExists creates a blob container if it does not exist. Returns // true if container is newly created or false if container already exists. -func (c *Container) CreateIfNotExists() (bool, error) { - resp, err := c.create() +func (c *Container) CreateIfNotExists(options *CreateContainerOptions) (bool, error) { + resp, err := c.create(options) if resp != nil { defer readAndCloseBody(resp.body) if resp.statusCode == http.StatusCreated || resp.statusCode == http.StatusConflict { @@ -168,9 +207,17 @@ func (c *Container) CreateIfNotExists() (bool, error) { return false, err } -func (c *Container) create() (*storageResponse, error) { - uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), url.Values{"restype": {"container"}}) +func (c *Container) create(options *CreateContainerOptions) (*storageResponse, error) { + query := url.Values{"restype": {"container"}} headers := c.bsc.client.getStandardHeaders() + headers = c.bsc.client.addMetadataToHeaders(headers, c.Metadata) + + if options != nil { + query = addTimeout(query, options.Timeout) + headers = mergeHeaders(headers, headersFromStruct(*options)) + } + uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), query) + return c.bsc.client.exec(http.MethodPut, uri, headers, nil, c.bsc.auth) } @@ -190,29 +237,35 @@ func (c *Container) Exists() (bool, error) { return false, err } -// SetPermissions sets up container permissions as per https://msdn.microsoft.com/en-us/library/azure/dd179391.aspx -func (c *Container) SetPermissions(permissions ContainerPermissions, timeout int, leaseID string) error { +// SetContainerPermissionOptions includes options for a set container permissions operation +type SetContainerPermissionOptions struct { + Timeout uint + LeaseID string `header:"x-ms-lease-id"` + IfModifiedSince *time.Time `header:"If-Modified-Since"` + IfUnmodifiedSince *time.Time `header:"If-Unmodified-Since"` + RequestID string `header:"x-ms-client-request-id"` +} + +// SetPermissions sets up container permissions +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Set-Container-ACL +func (c *Container) SetPermissions(permissions ContainerPermissions, options *SetContainerPermissionOptions) error { + body, length, err := generateContainerACLpayload(permissions.AccessPolicies) + if err != nil { + return err + } params := url.Values{ "restype": {"container"}, "comp": {"acl"}, } - - if timeout > 0 { - params.Add("timeout", strconv.Itoa(timeout)) - } - - uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), params) headers := c.bsc.client.getStandardHeaders() - if permissions.AccessType != "" { - headers[ContainerAccessHeader] = string(permissions.AccessType) - } + headers = addToHeaders(headers, ContainerAccessHeader, string(permissions.AccessType)) + headers["Content-Length"] = strconv.Itoa(length) - if leaseID != "" { - headers[headerLeaseID] = leaseID + if options != nil { + params = addTimeout(params, options.Timeout) + headers = mergeHeaders(headers, headersFromStruct(*options)) } - - body, length, err := generateContainerACLpayload(permissions.AccessPolicies) - headers["Content-Length"] = strconv.Itoa(length) + uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), params) resp, err := c.bsc.client.exec(http.MethodPut, uri, headers, body, c.bsc.auth) if err != nil { @@ -227,25 +280,28 @@ func (c *Container) SetPermissions(permissions ContainerPermissions, timeout int return nil } +// GetContainerPermissionOptions includes options for a get container permissions operation +type GetContainerPermissionOptions struct { + Timeout uint + LeaseID string `header:"x-ms-lease-id"` + RequestID string `header:"x-ms-client-request-id"` +} + // GetPermissions gets the container permissions as per https://msdn.microsoft.com/en-us/library/azure/dd179469.aspx // If timeout is 0 then it will not be passed to Azure // leaseID will only be passed to Azure if populated -func (c *Container) GetPermissions(timeout int, leaseID string) (*ContainerPermissions, error) { +func (c *Container) GetPermissions(options *GetContainerPermissionOptions) (*ContainerPermissions, error) { params := url.Values{ "restype": {"container"}, "comp": {"acl"}, } - - if timeout > 0 { - params.Add("timeout", strconv.Itoa(timeout)) - } - - uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), params) headers := c.bsc.client.getStandardHeaders() - if leaseID != "" { - headers[headerLeaseID] = leaseID + if options != nil { + params = addTimeout(params, options.Timeout) + headers = mergeHeaders(headers, headersFromStruct(*options)) } + uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), params) resp, err := c.bsc.client.exec(http.MethodGet, uri, headers, nil, c.bsc.auth) if err != nil { @@ -284,16 +340,25 @@ func buildAccessPolicy(ap AccessPolicy, headers *http.Header) *ContainerPermissi return &permissions } +// DeleteContainerOptions includes options for a delete container operation +type DeleteContainerOptions struct { + Timeout uint + LeaseID string `header:"x-ms-lease-id"` + IfModifiedSince *time.Time `header:"If-Modified-Since"` + IfUnmodifiedSince *time.Time `header:"If-Unmodified-Since"` + RequestID string `header:"x-ms-client-request-id"` +} + // Delete deletes the container with given name on the storage // account. If the container does not exist returns error. // -// See https://msdn.microsoft.com/en-us/library/azure/dd179408.aspx -func (c *Container) Delete() error { - resp, err := c.delete() +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/delete-container +func (c *Container) Delete(options *DeleteContainerOptions) error { + resp, err := c.delete(options) if err != nil { return err } - defer readAndCloseBody(resp.body) + readAndCloseBody(resp.body) return checkRespCode(resp.statusCode, []int{http.StatusAccepted}) } @@ -302,9 +367,9 @@ func (c *Container) Delete() error { // false if the container did not exist at the time of the Delete Container // operation. // -// See https://msdn.microsoft.com/en-us/library/azure/dd179408.aspx -func (c *Container) DeleteIfExists() (bool, error) { - resp, err := c.delete() +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/delete-container +func (c *Container) DeleteIfExists(options *DeleteContainerOptions) (bool, error) { + resp, err := c.delete(options) if resp != nil { defer readAndCloseBody(resp.body) if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound { @@ -314,23 +379,32 @@ func (c *Container) DeleteIfExists() (bool, error) { return false, err } -func (c *Container) delete() (*storageResponse, error) { - uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), url.Values{"restype": {"container"}}) +func (c *Container) delete(options *DeleteContainerOptions) (*storageResponse, error) { + query := url.Values{"restype": {"container"}} headers := c.bsc.client.getStandardHeaders() + + if options != nil { + query = addTimeout(query, options.Timeout) + headers = mergeHeaders(headers, headersFromStruct(*options)) + } + uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), query) + return c.bsc.client.exec(http.MethodDelete, uri, headers, nil, c.bsc.auth) } // ListBlobs returns an object that contains list of blobs in the container, // pagination token and other information in the response of List Blobs call. // -// See https://msdn.microsoft.com/en-us/library/azure/dd135734.aspx +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/List-Blobs func (c *Container) ListBlobs(params ListBlobsParameters) (BlobListResponse, error) { q := mergeParams(params.getParameters(), url.Values{ "restype": {"container"}, "comp": {"list"}}, ) uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), q) + headers := c.bsc.client.getStandardHeaders() + headers = addToHeaders(headers, "x-ms-client-request-id", params.RequestID) var out BlobListResponse resp, err := c.bsc.client.exec(http.MethodGet, uri, headers, nil, c.bsc.auth) diff --git a/storage/container_test.go b/storage/container_test.go index 5bfd0ab5ea6c..a31ff9ad115d 100644 --- a/storage/container_test.go +++ b/storage/container_test.go @@ -1,8 +1,8 @@ package storage import ( - "crypto/rand" "sort" + "strconv" "time" chk "gopkg.in/check.v1" @@ -14,20 +14,22 @@ var _ = chk.Suite(&ContainerSuite{}) func (s *ContainerSuite) Test_containerBuildPath(c *chk.C) { cli := getBlobClient(c) - cnt := cli.GetContainerReference("foo") - c.Assert(cnt.buildPath(), chk.Equals, "/foo") + cnt := cli.GetContainerReference("lol") + c.Assert(cnt.buildPath(), chk.Equals, "/lol") } func (s *ContainerSuite) TestListContainersPagination(c *chk.C) { cli := getBlobClient(c) - c.Assert(deleteTestContainers(cli), chk.IsNil) + cli.deleteTestContainers(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() const n = 5 const pageSize = 2 cntNames := []string{} for i := 0; i < n; i++ { - cntNames = append(cntNames, randContainer()) + cntNames = append(cntNames, containerName(c, strconv.Itoa(i))) } sort.Strings(cntNames) @@ -35,9 +37,9 @@ func (s *ContainerSuite) TestListContainersPagination(c *chk.C) { created := []Container{} for i := 0; i < n; i++ { cnt := cli.GetContainerReference(cntNames[i]) - c.Assert(cnt.Create(), chk.IsNil) + c.Assert(cnt.Create(nil), chk.IsNil) created = append(created, cnt) - defer cnt.Delete() + defer cnt.Delete(nil) } // Paginate results @@ -45,7 +47,6 @@ func (s *ContainerSuite) TestListContainersPagination(c *chk.C) { marker := "" for { resp, err := cli.ListContainers(ListContainersParameters{ - Prefix: testContainerPrefix, MaxResults: pageSize, Marker: marker}) @@ -72,73 +73,100 @@ func (s *ContainerSuite) TestListContainersPagination(c *chk.C) { func (s *ContainerSuite) TestContainerExists(c *chk.C) { cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - ok, err := cnt.Exists() + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + // Container does not exist + cnt1 := cli.GetContainerReference(containerName(c, "1")) + ok, err := cnt1.Exists() c.Assert(err, chk.IsNil) c.Assert(ok, chk.Equals, false) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() - - ok, err = cnt.Exists() + // COntainer exists + cnt2 := cli.GetContainerReference(containerName(c, "2")) + c.Assert(cnt2.Create(nil), chk.IsNil) + defer cnt2.Delete(nil) + ok, err = cnt2.Exists() c.Assert(err, chk.IsNil) c.Assert(ok, chk.Equals, true) } func (s *ContainerSuite) TestCreateContainerDeleteContainer(c *chk.C) { cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - c.Assert(cnt.Delete(), chk.IsNil) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + cnt := cli.GetContainerReference(containerName(c)) + c.Assert(cnt.Create(nil), chk.IsNil) + c.Assert(cnt.Delete(nil), chk.IsNil) } func (s *ContainerSuite) TestCreateContainerIfNotExists(c *chk.C) { cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - defer cnt.Delete() + rec := cli.client.appendRecorder(c) + defer rec.Stop() - // First create - ok, err := cnt.CreateIfNotExists() + // Create non exisiting container + cnt := cli.GetContainerReference(containerName(c)) + ok, err := cnt.CreateIfNotExists(nil) + defer cnt.Delete(nil) c.Assert(err, chk.IsNil) c.Assert(ok, chk.Equals, true) - // Second create, should not give errors - ok, err = cnt.CreateIfNotExists() +} + +func (s *ContainerSuite) TestCreateContainerIfExists(c *chk.C) { + cli := getBlobClient(c) + cnt := cli.GetContainerReference(containerName(c)) + cnt.Create(nil) + defer cnt.Delete(nil) + rec := cli.client.appendRecorder(c) + cnt.bsc = &cli + defer rec.Stop() + + // Try to create already exisiting container + ok, err := cnt.CreateIfNotExists(nil) c.Assert(err, chk.IsNil) c.Assert(ok, chk.Equals, false) } func (s *ContainerSuite) TestDeleteContainerIfExists(c *chk.C) { cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) + rec := cli.client.appendRecorder(c) + defer rec.Stop() // Nonexisting container - c.Assert(cnt.Delete(), chk.NotNil) - - ok, err := cnt.DeleteIfExists() + cnt1 := cli.GetContainerReference(containerName(c, "1")) + ok, err := cnt1.Exists() + c.Assert(err, chk.IsNil) + c.Assert(ok, chk.Equals, false) + ok, err = cnt1.DeleteIfExists(nil) c.Assert(err, chk.IsNil) c.Assert(ok, chk.Equals, false) // Existing container - c.Assert(cnt.Create(), chk.IsNil) - ok, err = cnt.DeleteIfExists() + cnt2 := cli.GetContainerReference(containerName(c, "2")) + c.Assert(cnt2.Create(nil), chk.IsNil) + ok, err = cnt2.DeleteIfExists(nil) c.Assert(err, chk.IsNil) c.Assert(ok, chk.Equals, true) } func (s *ContainerSuite) TestListBlobsPagination(c *chk.C) { cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + cnt := cli.GetContainerReference(containerName(c)) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() + c.Assert(cnt.Create(nil), chk.IsNil) + defer cnt.Delete(nil) blobs := []string{} const n = 5 const pageSize = 2 for i := 0; i < n; i++ { - name := randName(5) - c.Assert(cli.putSingleBlockBlob(cnt.Name, name, []byte("Hello, world!")), chk.IsNil) + name := blobName(c, strconv.Itoa(i)) + b := cnt.GetBlobReference(name) + c.Assert(b.putSingleBlockBlob([]byte("Hello, world!")), chk.IsNil) blobs = append(blobs, name) } sort.Strings(blobs) @@ -240,9 +268,12 @@ func listBlobsAsFiles(cli BlobStorageClient, cnt Container, parentDir string) (f // scenarios. func (s *ContainerSuite) TestListBlobsTraversal(c *chk.C) { cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + cnt := cli.GetContainerReference(containerName(c)) + c.Assert(cnt.Create(nil), chk.IsNil) + defer cnt.Delete(nil) // Note use of leading forward slash as per naming rules. blobsToCreate := []string{ @@ -255,7 +286,8 @@ func (s *ContainerSuite) TestListBlobsTraversal(c *chk.C) { // Create the above blobs for _, blobName := range blobsToCreate { - err := cli.CreateBlockBlob(cnt.Name, blobName) + b := cnt.GetBlobReference(blobName) + err := b.CreateBlockBlob(nil) c.Assert(err, chk.IsNil) } @@ -296,45 +328,64 @@ func (s *ContainerSuite) TestListBlobsTraversal(c *chk.C) { func (s *ContainerSuite) TestListBlobsWithMetadata(c *chk.C) { cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + cnt := cli.GetContainerReference(containerName(c)) + c.Assert(cnt.Create(nil), chk.IsNil) + defer cnt.Delete(nil) expectMeta := make(map[string]BlobMetadata) // Put 4 blobs with metadata for i := 0; i < 4; i++ { - name := randName(5) - c.Assert(cli.putSingleBlockBlob(cnt.Name, name, []byte("Hello, world!")), chk.IsNil) - c.Assert(cli.SetBlobMetadata(cnt.Name, name, map[string]string{ - "Foo": name, - "Bar_BAZ": "Waz Qux", - }, nil), chk.IsNil) + name := blobName(c, strconv.Itoa(i)) + b := cnt.GetBlobReference(name) + c.Assert(b.putSingleBlockBlob([]byte("Hello, world!")), chk.IsNil) + b.Metadata = BlobMetadata{ + "Lol": name, + "Rofl_BAZ": "Waz Qux", + } + c.Assert(b.SetMetadata(nil), chk.IsNil) expectMeta[name] = BlobMetadata{ - "foo": name, - "bar_baz": "Waz Qux", + "lol": name, + "rofl_baz": "Waz Qux", } + _, err := b.CreateSnapshot(nil) + c.Assert(err, chk.IsNil) } // Put one more blob with no metadata - blobWithoutMetadata := randName(5) - c.Assert(cli.putSingleBlockBlob(cnt.Name, blobWithoutMetadata, []byte("Hello, world!")), chk.IsNil) - expectMeta[blobWithoutMetadata] = nil + b := cnt.GetBlobReference(blobName(c, "nometa")) + 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]) } } @@ -360,51 +411,63 @@ func appendContainerPermission(perms ContainerPermissions, accessType ContainerA func (s *ContainerSuite) TestSetContainerPermissionsWithTimeoutSuccessfully(c *chk.C) { cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + cnt := cli.GetContainerReference(containerName(c)) + c.Assert(cnt.Create(nil), chk.IsNil) + defer cnt.Delete(nil) perms := ContainerPermissions{} - perms = appendContainerPermission(perms, ContainerAccessTypeBlob, "GolangRocksOnAzure", now, now.Add(10*time.Hour), true, true, true) + perms = appendContainerPermission(perms, ContainerAccessTypeBlob, "GolangRocksOnAzure", fixedTime, fixedTime.Add(10*time.Hour), true, true, true) - err := cnt.SetPermissions(perms, 30, "") + options := SetContainerPermissionOptions{ + Timeout: 30, + } + err := cnt.SetPermissions(perms, &options) c.Assert(err, chk.IsNil) } func (s *ContainerSuite) TestSetContainerPermissionsSuccessfully(c *chk.C) { cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + cnt := cli.GetContainerReference(containerName(c)) + c.Assert(cnt.Create(nil), chk.IsNil) + defer cnt.Delete(nil) perms := ContainerPermissions{} - perms = appendContainerPermission(perms, ContainerAccessTypeBlob, "GolangRocksOnAzure", now, now.Add(10*time.Hour), true, true, true) + perms = appendContainerPermission(perms, ContainerAccessTypeBlob, "GolangRocksOnAzure", fixedTime, fixedTime.Add(10*time.Hour), true, true, true) - err := cnt.SetPermissions(perms, 0, "") + err := cnt.SetPermissions(perms, nil) c.Assert(err, chk.IsNil) } func (s *ContainerSuite) TestSetThenGetContainerPermissionsSuccessfully(c *chk.C) { cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.delete() + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + cnt := cli.GetContainerReference(containerName(c)) + c.Assert(cnt.Create(nil), chk.IsNil) + defer cnt.delete(nil) perms := ContainerPermissions{} - perms = appendContainerPermission(perms, ContainerAccessTypeBlob, "AutoRestIsSuperCool", now, now.Add(10*time.Hour), true, true, true) - perms = appendContainerPermission(perms, ContainerAccessTypeBlob, "GolangRocksOnAzure", now.Add(20*time.Hour), now.Add(30*time.Hour), true, false, false) + perms = appendContainerPermission(perms, ContainerAccessTypeBlob, "AutoRestIsSuperCool", fixedTime, fixedTime.Add(10*time.Hour), true, true, true) + perms = appendContainerPermission(perms, ContainerAccessTypeBlob, "GolangRocksOnAzure", fixedTime.Add(20*time.Hour), fixedTime.Add(30*time.Hour), true, false, false) c.Assert(perms.AccessPolicies, chk.HasLen, 2) - err := cnt.SetPermissions(perms, 0, "") + err := cnt.SetPermissions(perms, nil) c.Assert(err, chk.IsNil) - newPerms, err := cnt.GetPermissions(0, "") + newPerms, err := cnt.GetPermissions(nil) c.Assert(err, chk.IsNil) // check container permissions itself. c.Assert(newPerms.AccessType, chk.Equals, perms.AccessType) - // now check policy set. + // fixedTime check policy set. c.Assert(newPerms.AccessPolicies, chk.HasLen, 2) for i := range perms.AccessPolicies { @@ -427,42 +490,48 @@ func (s *ContainerSuite) TestSetThenGetContainerPermissionsSuccessfully(c *chk.C func (s *ContainerSuite) TestSetContainerPermissionsOnlySuccessfully(c *chk.C) { cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + cnt := cli.GetContainerReference(containerName(c)) + c.Assert(cnt.Create(nil), chk.IsNil) + defer cnt.Delete(nil) perms := ContainerPermissions{} - perms = appendContainerPermission(perms, ContainerAccessTypeBlob, "GolangRocksOnAzure", now, now.Add(10*time.Hour), true, true, true) + perms = appendContainerPermission(perms, ContainerAccessTypeBlob, "GolangRocksOnAzure", fixedTime, fixedTime.Add(10*time.Hour), true, true, true) - err := cnt.SetPermissions(perms, 0, "") + err := cnt.SetPermissions(perms, nil) c.Assert(err, chk.IsNil) } func (s *ContainerSuite) TestSetThenGetContainerPermissionsOnlySuccessfully(c *chk.C) { cli := getBlobClient(c) - cnt := cli.GetContainerReference(randContainer()) - c.Assert(cnt.Create(), chk.IsNil) - defer cnt.Delete() + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + cnt := cli.GetContainerReference(containerName(c)) + c.Assert(cnt.Create(nil), chk.IsNil) + defer cnt.Delete(nil) perms := ContainerPermissions{} - perms = appendContainerPermission(perms, ContainerAccessTypeBlob, "", now, now.Add(10*time.Hour), true, true, true) + perms = appendContainerPermission(perms, ContainerAccessTypeBlob, "", fixedTime, fixedTime.Add(10*time.Hour), true, true, true) - err := cnt.SetPermissions(perms, 0, "") + err := cnt.SetPermissions(perms, nil) c.Assert(err, chk.IsNil) - newPerms, err := cnt.GetPermissions(0, "") + newPerms, err := cnt.GetPermissions(nil) c.Assert(err, chk.IsNil) // check container permissions itself. c.Assert(newPerms.AccessType, chk.Equals, perms.AccessType) - // now check there are NO policies set + // fixedTime check there are NO policies set c.Assert(newPerms.AccessPolicies, chk.HasLen, 0) } -func deleteTestContainers(cli BlobStorageClient) error { +func (cli *BlobStorageClient) deleteTestContainers(c *chk.C) error { for { - resp, err := cli.ListContainers(ListContainersParameters{Prefix: testContainerPrefix}) + resp, err := cli.ListContainers(ListContainersParameters{}) if err != nil { return err } @@ -470,7 +539,7 @@ func deleteTestContainers(cli BlobStorageClient) error { break } for _, c := range resp.Containers { - err = c.Delete() + err = c.Delete(nil) if err != nil { return err } @@ -479,19 +548,6 @@ func deleteTestContainers(cli BlobStorageClient) error { return nil } -func randContainer() string { - return testContainerPrefix + randString(32-len(testContainerPrefix)) -} - -func randString(n int) string { - if n <= 0 { - panic("negative number") - } - const alphanum = "0123456789abcdefghijklmnopqrstuvwxyz" - var bytes = make([]byte, n) - rand.Read(bytes) - for i, b := range bytes { - bytes[i] = alphanum[b%byte(len(alphanum))] - } - return string(bytes) +func containerName(c *chk.C, extras ...string) string { + return nameGenerator(32, "cnt-", alphanum, c, extras) } diff --git a/storage/copyblob.go b/storage/copyblob.go new file mode 100644 index 000000000000..377a3c622e9a --- /dev/null +++ b/storage/copyblob.go @@ -0,0 +1,223 @@ +package storage + +import ( + "errors" + "fmt" + "net/http" + "net/url" + "strings" + "time" +) + +const ( + blobCopyStatusPending = "pending" + blobCopyStatusSuccess = "success" + blobCopyStatusAborted = "aborted" + blobCopyStatusFailed = "failed" +) + +// CopyOptions includes the options for a copy blob operation +type CopyOptions struct { + Timeout uint + Source CopyOptionsConditions + Destiny CopyOptionsConditions + RequestID string +} + +// IncrementalCopyOptions includes the options for an incremental copy blob operation +type IncrementalCopyOptions struct { + Timeout uint + Destination IncrementalCopyOptionsConditions + RequestID string +} + +// CopyOptionsConditions includes some conditional options in a copy blob operation +type CopyOptionsConditions struct { + LeaseID string + IfModifiedSince *time.Time + IfUnmodifiedSince *time.Time + IfMatch string + IfNoneMatch string +} + +// IncrementalCopyOptionsConditions includes some conditional options in a copy blob operation +type IncrementalCopyOptionsConditions struct { + IfModifiedSince *time.Time + IfUnmodifiedSince *time.Time + IfMatch string + IfNoneMatch string +} + +// Copy starts a blob copy operation and waits for the operation to +// complete. sourceBlob parameter must be a canonical URL to the blob (can be +// obtained using GetBlobURL method.) There is no SLA on blob copy and therefore +// this helper method works faster on smaller files. +// +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Copy-Blob +func (b *Blob) Copy(sourceBlob string, options *CopyOptions) error { + copyID, err := b.StartCopy(sourceBlob, options) + if err != nil { + return err + } + + return b.WaitForCopy(copyID) +} + +// StartCopy starts a blob copy operation. +// sourceBlob parameter must be a canonical URL to the blob (can be +// obtained using GetBlobURL method.) +// +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Copy-Blob +func (b *Blob) StartCopy(sourceBlob string, options *CopyOptions) (string, error) { + params := url.Values{} + headers := b.Container.bsc.client.getStandardHeaders() + headers["x-ms-copy-source"] = sourceBlob + headers = b.Container.bsc.client.addMetadataToHeaders(headers, b.Metadata) + + if options != nil { + params = addTimeout(params, options.Timeout) + headers = addToHeaders(headers, "x-ms-client-request-id", options.RequestID) + // source + headers = addToHeaders(headers, "x-ms-source-lease-id", options.Source.LeaseID) + headers = addTimeToHeaders(headers, "x-ms-source-if-modified-since", options.Source.IfModifiedSince) + headers = addTimeToHeaders(headers, "x-ms-source-if-unmodified-since", options.Source.IfUnmodifiedSince) + headers = addToHeaders(headers, "x-ms-source-if-match", options.Source.IfMatch) + headers = addToHeaders(headers, "x-ms-source-if-none-match", options.Source.IfNoneMatch) + //destiny + headers = addToHeaders(headers, "x-ms-lease-id", options.Destiny.LeaseID) + headers = addTimeToHeaders(headers, "x-ms-if-modified-since", options.Destiny.IfModifiedSince) + headers = addTimeToHeaders(headers, "x-ms-if-unmodified-since", options.Destiny.IfUnmodifiedSince) + headers = addToHeaders(headers, "x-ms-if-match", options.Destiny.IfMatch) + headers = addToHeaders(headers, "x-ms-if-none-match", options.Destiny.IfNoneMatch) + } + 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 + } + defer readAndCloseBody(resp.body) + + if err := checkRespCode(resp.statusCode, []int{http.StatusAccepted, http.StatusCreated}); err != nil { + return "", err + } + + copyID := resp.headers.Get("x-ms-copy-id") + if copyID == "" { + return "", errors.New("Got empty copy id header") + } + return copyID, nil +} + +// AbortCopyOptions includes the options for an abort blob operation +type AbortCopyOptions struct { + Timeout uint + LeaseID string `header:"x-ms-lease-id"` + RequestID string `header:"x-ms-client-request-id"` +} + +// AbortCopy aborts a BlobCopy which has already been triggered by the StartBlobCopy function. +// copyID is generated from StartBlobCopy function. +// currentLeaseID is required IF the destination blob has an active lease on it. +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Abort-Copy-Blob +func (b *Blob) AbortCopy(copyID string, options *AbortCopyOptions) error { + params := url.Values{ + "comp": {"copy"}, + "copyid": {copyID}, + } + headers := b.Container.bsc.client.getStandardHeaders() + headers["x-ms-copy-action"] = "abort" + + 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.StatusNoContent}) +} + +// WaitForCopy loops until a BlobCopy operation is completed (or fails with error) +func (b *Blob) WaitForCopy(copyID string) error { + for { + err := b.GetProperties(nil) + if err != nil { + return err + } + + if b.Properties.CopyID != copyID { + return errBlobCopyIDMismatch + } + + switch b.Properties.CopyStatus { + case blobCopyStatusSuccess: + return nil + case blobCopyStatusPending: + continue + case blobCopyStatusAborted: + return errBlobCopyAborted + case blobCopyStatusFailed: + return fmt.Errorf("storage: blob copy failed. Id=%s Description=%s", b.Properties.CopyID, b.Properties.CopyStatusDescription) + default: + return fmt.Errorf("storage: unhandled blob copy status: '%s'", b.Properties.CopyStatus) + } + } +} + +// IncrementalCopyBlob copies a snapshot of a source blob and copies to referring blob +// sourceBlob parameter must be a valid snapshot URL of the original blob. +// THe original blob mut be public, or use a Shared Access Signature. +// +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/incremental-copy-blob . +func (b *Blob) IncrementalCopyBlob(sourceBlobURL string, snapshotTime time.Time, options *IncrementalCopyOptions) (string, error) { + params := url.Values{"comp": {"incrementalcopy"}} + + // need formatting to 7 decimal places so it's friendly to Windows and *nix + snapshotTimeFormatted := snapshotTime.Format("2006-01-02T15:04:05.0000000Z") + u, err := url.Parse(sourceBlobURL) + if err != nil { + return "", err + } + query := u.Query() + query.Add("snapshot", snapshotTimeFormatted) + encodedQuery := query.Encode() + encodedQuery = strings.Replace(encodedQuery, "%3A", ":", -1) + u.RawQuery = encodedQuery + snapshotURL := u.String() + + headers := b.Container.bsc.client.getStandardHeaders() + headers["x-ms-copy-source"] = snapshotURL + + if options != nil { + addTimeout(params, options.Timeout) + headers = addToHeaders(headers, "x-ms-client-request-id", options.RequestID) + headers = addTimeToHeaders(headers, "x-ms-if-modified-since", options.Destination.IfModifiedSince) + headers = addTimeToHeaders(headers, "x-ms-if-unmodified-since", options.Destination.IfUnmodifiedSince) + headers = addToHeaders(headers, "x-ms-if-match", options.Destination.IfMatch) + headers = addToHeaders(headers, "x-ms-if-none-match", options.Destination.IfNoneMatch) + } + + // get URI of destination blob + 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 + } + defer readAndCloseBody(resp.body) + + if err := checkRespCode(resp.statusCode, []int{http.StatusAccepted}); err != nil { + return "", err + } + + copyID := resp.headers.Get("x-ms-copy-id") + if copyID == "" { + return "", errors.New("Got empty copy id header") + } + return copyID, nil +} diff --git a/storage/copyblob_test.go b/storage/copyblob_test.go new file mode 100644 index 000000000000..60a50c8b7b4d --- /dev/null +++ b/storage/copyblob_test.go @@ -0,0 +1,171 @@ +package storage + +import ( + "io/ioutil" + "net/http" + "testing" + + chk "gopkg.in/check.v1" +) + +type CopyBlobSuite struct{} + +var _ = chk.Suite(&CopyBlobSuite{}) + +func (s *CopyBlobSuite) TestBlobCopy(c *chk.C) { + if testing.Short() { + c.Skip("skipping blob copy in short mode, no SLA on async operation") + } + + cli := getBlobClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + cnt := cli.GetContainerReference(containerName(c)) + c.Assert(cnt.Create(nil), chk.IsNil) + defer cnt.Delete(nil) + + srcBlob := cnt.GetBlobReference(blobName(c, "src")) + dstBlob := cnt.GetBlobReference(blobName(c, "dst")) + body := content(1024) + + c.Assert(srcBlob.putSingleBlockBlob(body), chk.IsNil) + defer srcBlob.Delete(nil) + + c.Assert(dstBlob.Copy(srcBlob.GetURL(), nil), chk.IsNil) + defer dstBlob.Delete(nil) + + resp, err := dstBlob.Get(nil) + c.Assert(err, chk.IsNil) + + b, err := ioutil.ReadAll(resp) + defer resp.Close() + c.Assert(err, chk.IsNil) + c.Assert(b, chk.DeepEquals, body) +} + +func (s *CopyBlobSuite) TestStartBlobCopy(c *chk.C) { + if testing.Short() { + c.Skip("skipping blob copy in short mode, no SLA on async operation") + } + + cli := getBlobClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + cnt := cli.GetContainerReference(containerName(c)) + c.Assert(cnt.Create(nil), chk.IsNil) + defer cnt.Delete(nil) + + srcBlob := cnt.GetBlobReference(blobName(c, "src")) + dstBlob := cnt.GetBlobReference(blobName(c, "dst")) + body := content(1024) + + c.Assert(srcBlob.putSingleBlockBlob(body), chk.IsNil) + defer srcBlob.Delete(nil) + + // given we dont know when it will start, can we even test destination creation? + // will just test that an error wasn't thrown for now. + copyID, err := dstBlob.StartCopy(srcBlob.GetURL(), nil) + c.Assert(copyID, chk.NotNil) + c.Assert(err, chk.IsNil) +} + +// Tests abort of blobcopy. Given the blobcopy is usually over before we can actually trigger an abort +// it is agreed that we perform a copy then try and perform an abort. It should result in a HTTP status of 409. +// So basically we're testing negative scenario (as good as we can do for now) +func (s *CopyBlobSuite) TestAbortBlobCopy(c *chk.C) { + if testing.Short() { + c.Skip("skipping blob copy in short mode, no SLA on async operation") + } + + cli := getBlobClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + cnt := cli.GetContainerReference(containerName(c)) + c.Assert(cnt.Create(nil), chk.IsNil) + defer cnt.Delete(nil) + + srcBlob := cnt.GetBlobReference(blobName(c, "src")) + dstBlob := cnt.GetBlobReference(blobName(c, "dst")) + body := content(1024) + + c.Assert(srcBlob.putSingleBlockBlob(body), chk.IsNil) + defer srcBlob.Delete(nil) + + // given we dont know when it will start, can we even test destination creation? + // will just test that an error wasn't thrown for now. + copyID, err := dstBlob.StartCopy(srcBlob.GetURL(), nil) + c.Assert(copyID, chk.NotNil) + c.Assert(err, chk.IsNil) + + err = dstBlob.WaitForCopy(copyID) + c.Assert(err, chk.IsNil) + + // abort abort abort, but we *know* its already completed. + err = dstBlob.AbortCopy(copyID, nil) + + // abort should fail (over already) + c.Assert(err.(AzureStorageServiceError).StatusCode, chk.Equals, http.StatusConflict) +} + +func (s *CopyBlobSuite) TestIncrementalCopyBlobNoTimeout(c *chk.C) { + if testing.Short() { + c.Skip("skipping blob copy in short mode, no SLA on async operation") + } + + cli := getBlobClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + cnt := cli.GetContainerReference(containerName(c)) + options := CreateContainerOptions{ + Access: ContainerAccessTypeBlob, + } + c.Assert(cnt.Create(&options), chk.IsNil) + defer cnt.Delete(nil) + + b := cnt.GetBlobReference(blobName(c, "src")) + size := int64(10 * 1024 * 1024) + b.Properties.ContentLength = size + c.Assert(b.PutPageBlob(nil), chk.IsNil) + + snapshotTime, err := b.CreateSnapshot(nil) + c.Assert(err, chk.IsNil) + c.Assert(snapshotTime, chk.NotNil) + + u := b.GetURL() + destBlob := cnt.GetBlobReference(blobName(c, "dst")) + copyID, err := destBlob.IncrementalCopyBlob(u, *snapshotTime, nil) + c.Assert(copyID, chk.NotNil) + c.Assert(err, chk.IsNil) +} + +func (s *CopyBlobSuite) TestIncrementalCopyBlobWithTimeout(c *chk.C) { + cli := getBlobClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + cnt := cli.GetContainerReference(containerName(c)) + options := CreateContainerOptions{ + Access: ContainerAccessTypeBlob, + } + c.Assert(cnt.Create(&options), chk.IsNil) + defer cnt.Delete(nil) + + b := cnt.GetBlobReference(blobName(c, "src")) + size := int64(10 * 1024 * 1024) + b.Properties.ContentLength = size + c.Assert(b.PutPageBlob(nil), chk.IsNil) + + snapshotTime, err := b.CreateSnapshot(nil) + c.Assert(err, chk.IsNil) + c.Assert(snapshotTime, chk.NotNil) + + u := b.GetURL() + destBlob := cnt.GetBlobReference(blobName(c, "dst")) + copyID, err := destBlob.IncrementalCopyBlob(u, *snapshotTime, &IncrementalCopyOptions{Timeout: 30}) + c.Assert(copyID, chk.NotNil) + c.Assert(err, chk.IsNil) +} diff --git a/storage/directory.go b/storage/directory.go index d27e62079a18..29610329ec31 100644 --- a/storage/directory.go +++ b/storage/directory.go @@ -25,8 +25,9 @@ type DirectoryProperties struct { // ListDirsAndFilesParameters defines the set of customizable parameters to // make a List Files and Directories call. // -// See https://msdn.microsoft.com/en-us/library/azure/dn166980.aspx +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/List-Directories-and-Files type ListDirsAndFilesParameters struct { + Prefix string Marker string MaxResults uint Timeout uint @@ -35,7 +36,7 @@ type ListDirsAndFilesParameters struct { // DirsAndFilesListResponse contains the response fields from // a List Files and Directories call. // -// See https://msdn.microsoft.com/en-us/library/azure/dn166980.aspx +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/List-Directories-and-Files type DirsAndFilesListResponse struct { XMLName xml.Name `xml:"EnumerationResults"` Xmlns string `xml:"xmlns,attr"` @@ -60,14 +61,15 @@ func (d *Directory) buildPath() string { // Create this directory in the associated share. // If a directory with the same name already exists, the operation fails. // -// See https://msdn.microsoft.com/en-us/library/azure/dn166993.aspx -func (d *Directory) Create() error { +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Create-Directory +func (d *Directory) Create(options *FileRequestOptions) error { // if this is the root directory exit early if d.parent == nil { return nil } - headers, err := d.fsc.createResource(d.buildPath(), resourceDirectory, nil, mergeMDIntoExtraHeaders(d.Metadata, nil), []int{http.StatusCreated}) + params := prepareOptions(options) + headers, err := d.fsc.createResource(d.buildPath(), resourceDirectory, params, mergeMDIntoExtraHeaders(d.Metadata, nil), []int{http.StatusCreated}) if err != nil { return err } @@ -80,14 +82,15 @@ func (d *Directory) Create() error { // directory does not exists. Returns true if the directory is newly created or // false if the directory already exists. // -// See https://msdn.microsoft.com/en-us/library/azure/dn166993.aspx -func (d *Directory) CreateIfNotExists() (bool, error) { +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Create-Directory +func (d *Directory) CreateIfNotExists(options *FileRequestOptions) (bool, error) { // if this is the root directory exit early if d.parent == nil { return false, nil } - resp, err := d.fsc.createResourceNoClose(d.buildPath(), resourceDirectory, nil, nil) + params := prepareOptions(options) + resp, err := d.fsc.createResourceNoClose(d.buildPath(), resourceDirectory, params, nil) if resp != nil { defer readAndCloseBody(resp.body) if resp.statusCode == http.StatusCreated || resp.statusCode == http.StatusConflict { @@ -96,7 +99,7 @@ func (d *Directory) CreateIfNotExists() (bool, error) { return true, nil } - return false, d.FetchAttributes() + return false, d.FetchAttributes(nil) } } @@ -106,16 +109,16 @@ func (d *Directory) CreateIfNotExists() (bool, error) { // Delete removes this directory. It must be empty in order to be deleted. // If the directory does not exist the operation fails. // -// See https://msdn.microsoft.com/en-us/library/azure/dn166969.aspx -func (d *Directory) Delete() error { - return d.fsc.deleteResource(d.buildPath(), resourceDirectory) +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Delete-Directory +func (d *Directory) Delete(options *FileRequestOptions) error { + return d.fsc.deleteResource(d.buildPath(), resourceDirectory, options) } // DeleteIfExists removes this directory if it exists. // -// See https://msdn.microsoft.com/en-us/library/azure/dn166969.aspx -func (d *Directory) DeleteIfExists() (bool, error) { - resp, err := d.fsc.deleteResourceNoClose(d.buildPath(), resourceDirectory) +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Delete-Directory +func (d *Directory) DeleteIfExists(options *FileRequestOptions) (bool, error) { + resp, err := d.fsc.deleteResourceNoClose(d.buildPath(), resourceDirectory, options) if resp != nil { defer readAndCloseBody(resp.body) if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound { @@ -135,8 +138,10 @@ func (d *Directory) Exists() (bool, error) { } // FetchAttributes retrieves metadata for this directory. -func (d *Directory) FetchAttributes() error { - headers, err := d.fsc.getResourceHeaders(d.buildPath(), compNone, resourceDirectory, http.MethodHead) +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-directory-properties +func (d *Directory) FetchAttributes(options *FileRequestOptions) error { + params := prepareOptions(options) + headers, err := d.fsc.getResourceHeaders(d.buildPath(), compNone, resourceDirectory, params, http.MethodHead) if err != nil { return err } @@ -170,7 +175,7 @@ func (d *Directory) GetFileReference(name string) *File { // ListDirsAndFiles returns a list of files and directories under this directory. // It also contains a pagination token and other response details. // -// See https://msdn.microsoft.com/en-us/library/azure/dn166980.aspx +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/List-Directories-and-Files func (d *Directory) ListDirsAndFiles(params ListDirsAndFilesParameters) (*DirsAndFilesListResponse, error) { q := mergeParams(params.getParameters(), getURLInitValues(compList, resourceDirectory)) @@ -192,9 +197,9 @@ func (d *Directory) ListDirsAndFiles(params ListDirsAndFilesParameters) (*DirsAn // are case-insensitive so case munging should not matter to other // applications either. // -// See https://msdn.microsoft.com/en-us/library/azure/mt427370.aspx -func (d *Directory) SetMetadata() error { - headers, err := d.fsc.setResourceHeaders(d.buildPath(), compMetadata, resourceDirectory, mergeMDIntoExtraHeaders(d.Metadata, nil)) +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Set-Directory-Metadata +func (d *Directory) SetMetadata(options *FileRequestOptions) error { + headers, err := d.fsc.setResourceHeaders(d.buildPath(), compMetadata, resourceDirectory, mergeMDIntoExtraHeaders(d.Metadata, nil), options) if err != nil { return err } diff --git a/storage/directory_test.go b/storage/directory_test.go index 221348dba04b..ffe5f25c6e79 100644 --- a/storage/directory_test.go +++ b/storage/directory_test.go @@ -6,29 +6,43 @@ type StorageDirSuite struct{} var _ = chk.Suite(&StorageDirSuite{}) -func (s *StorageDirSuite) TestListDirsAndFiles(c *chk.C) { +func (s *StorageDirSuite) TestListZeroDirsAndFiles(c *chk.C) { // create share cli := getFileClient(c) - share := cli.GetShareReference(randShare()) + rec := cli.client.appendRecorder(c) + defer rec.Stop() - c.Assert(share.Create(), chk.IsNil) - defer share.Delete() - root := share.GetRootDirectoryReference() + share := cli.GetShareReference(shareName(c)) + c.Assert(share.Create(nil), chk.IsNil) + defer share.Delete(nil) // list contents, should be empty + root := share.GetRootDirectoryReference() resp, err := root.ListDirsAndFiles(ListDirsAndFilesParameters{}) c.Assert(err, chk.IsNil) c.Assert(resp.Directories, chk.IsNil) c.Assert(resp.Files, chk.IsNil) +} + +func (s *StorageDirSuite) TestListDirsAndFiles(c *chk.C) { + // create share + cli := getFileClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + share := cli.GetShareReference(shareName(c)) + c.Assert(share.Create(nil), chk.IsNil) + defer share.Delete(nil) // create a directory and a file + root := share.GetRootDirectoryReference() dir := root.GetDirectoryReference("SomeDirectory") - file := root.GetFileReference("foo.file") - c.Assert(dir.Create(), chk.IsNil) - c.Assert(file.Create(512), chk.IsNil) + file := root.GetFileReference("lol.file") + c.Assert(dir.Create(nil), chk.IsNil) + c.Assert(file.Create(512, nil), chk.IsNil) // list contents - resp, err = root.ListDirsAndFiles(ListDirsAndFilesParameters{}) + resp, err := root.ListDirsAndFiles(ListDirsAndFilesParameters{}) c.Assert(err, chk.IsNil) c.Assert(len(resp.Directories), chk.Equals, 1) c.Assert(len(resp.Files), chk.Equals, 1) @@ -36,39 +50,84 @@ func (s *StorageDirSuite) TestListDirsAndFiles(c *chk.C) { c.Assert(resp.Files[0].Name, chk.Equals, file.Name) // delete file - del, err := file.DeleteIfExists() + del, err := file.DeleteIfExists(nil) c.Assert(err, chk.IsNil) c.Assert(del, chk.Equals, true) - // attempt to delete again - del, err = file.DeleteIfExists() + ok, err := file.Exists() c.Assert(err, chk.IsNil) - c.Assert(del, chk.Equals, false) + c.Assert(ok, chk.Equals, false) } func (s *StorageDirSuite) TestCreateDirectory(c *chk.C) { - // create share cli := getFileClient(c) - share := cli.GetShareReference(randShare()) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + share := cli.GetShareReference(shareName(c)) + c.Assert(share.Create(nil), chk.IsNil) + defer share.Delete(nil) - c.Assert(share.Create(), chk.IsNil) - defer share.Delete() root := share.GetRootDirectoryReference() + dir := root.GetDirectoryReference("dir") + err := dir.Create(nil) + c.Assert(err, chk.IsNil) - // directory shouldn't exist - dir := root.GetDirectoryReference("SomeDirectory") + // check properties + c.Assert(dir.Properties.Etag, chk.Not(chk.Equals), "") + c.Assert(dir.Properties.LastModified, chk.Not(chk.Equals), "") + + // delete directory and verify + c.Assert(dir.Delete(nil), chk.IsNil) exists, err := dir.Exists() c.Assert(err, chk.IsNil) c.Assert(exists, chk.Equals, false) +} - // create directory - exists, err = dir.CreateIfNotExists() +func (s *StorageDirSuite) TestCreateDirectoryIfNotExists(c *chk.C) { + cli := getFileClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + // create share + share := cli.GetShareReference(shareName(c)) + share.Create(nil) + defer share.Delete(nil) + + // create non exisiting directory + root := share.GetRootDirectoryReference() + dir := root.GetDirectoryReference("dir") + exists, err := dir.CreateIfNotExists(nil) c.Assert(err, chk.IsNil) c.Assert(exists, chk.Equals, true) - // try to create again, should fail - c.Assert(dir.Create(), chk.NotNil) - exists, err = dir.CreateIfNotExists() + c.Assert(dir.Properties.Etag, chk.Not(chk.Equals), "") + c.Assert(dir.Properties.LastModified, chk.Not(chk.Equals), "") + + c.Assert(dir.Delete(nil), chk.IsNil) + exists, err = dir.Exists() + c.Assert(err, chk.IsNil) + c.Assert(exists, chk.Equals, false) +} + +func (s *StorageDirSuite) TestCreateDirectoryIfExists(c *chk.C) { + // create share + cli := getFileClient(c) + share := cli.GetShareReference(shareName(c)) + share.Create(nil) + defer share.Delete(nil) + + // create directory + root := share.GetRootDirectoryReference() + dir := root.GetDirectoryReference("dir") + dir.Create(nil) + + rec := cli.client.appendRecorder(c) + dir.fsc = &cli + defer rec.Stop() + + // try to create directory + exists, err := dir.CreateIfNotExists(nil) c.Assert(err, chk.IsNil) c.Assert(exists, chk.Equals, false) @@ -76,24 +135,23 @@ func (s *StorageDirSuite) TestCreateDirectory(c *chk.C) { c.Assert(dir.Properties.Etag, chk.Not(chk.Equals), "") c.Assert(dir.Properties.LastModified, chk.Not(chk.Equals), "") - // delete directory and verify - c.Assert(dir.Delete(), chk.IsNil) - exists, err = dir.Exists() - c.Assert(err, chk.IsNil) - c.Assert(exists, chk.Equals, false) + // delete directory + c.Assert(dir.Delete(nil), chk.IsNil) } func (s *StorageDirSuite) TestDirectoryMetadata(c *chk.C) { // create share cli := getFileClient(c) - share := cli.GetShareReference(randShare()) + rec := cli.client.appendRecorder(c) + defer rec.Stop() - c.Assert(share.Create(), chk.IsNil) - defer share.Delete() + share := cli.GetShareReference(shareName(c)) + c.Assert(share.Create(nil), chk.IsNil) + defer share.Delete(nil) root := share.GetRootDirectoryReference() dir := root.GetDirectoryReference("testdir") - c.Assert(dir.Create(), chk.IsNil) + c.Assert(dir.Create(nil), chk.IsNil) // get metadata, shouldn't be any c.Assert(dir.Metadata, chk.IsNil) @@ -104,9 +162,9 @@ func (s *StorageDirSuite) TestDirectoryMetadata(c *chk.C) { "another": "anothervalue", } dir.Metadata = md - c.Assert(dir.SetMetadata(), chk.IsNil) + c.Assert(dir.SetMetadata(nil), chk.IsNil) // retrieve and verify - c.Assert(dir.FetchAttributes(), chk.IsNil) + c.Assert(dir.FetchAttributes(nil), chk.IsNil) c.Assert(dir.Metadata, chk.DeepEquals, md) } diff --git a/storage/entity.go b/storage/entity.go new file mode 100644 index 000000000000..29e73ed4ce38 --- /dev/null +++ b/storage/entity.go @@ -0,0 +1,439 @@ +package storage + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "strconv" + "strings" + "time" + + "github.com/satori/uuid" +) + +// Annotating as secure for gas scanning +/* #nosec */ +const ( + partitionKeyNode = "PartitionKey" + rowKeyNode = "RowKey" + etagErrorTemplate = "Etag didn't match: %v" +) + +var ( + errEmptyPayload = errors.New("Empty payload is not a valid metadata level for this operation") + errNilPreviousResult = errors.New("The previous results page is nil") + errNilNextLink = errors.New("There are no more pages in this query results") +) + +// Entity represents an entity inside an Azure table. +type Entity struct { + Table *Table + PartitionKey string + RowKey string + TimeStamp time.Time + OdataMetadata string + OdataType string + OdataID string + OdataEtag string + OdataEditLink string + Properties map[string]interface{} +} + +// GetEntityReference returns an Entity object with the specified +// partition key and row key. +func (t *Table) GetEntityReference(partitionKey, rowKey string) Entity { + return Entity{ + PartitionKey: partitionKey, + RowKey: rowKey, + Table: t, + } +} + +// EntityOptions includes options for entity operations. +type EntityOptions struct { + Timeout uint + RequestID string `header:"x-ms-client-request-id"` +} + +// GetEntityOptions includes options for a get entity operation +type GetEntityOptions struct { + Select []string + RequestID string `header:"x-ms-client-request-id"` +} + +// Get gets the referenced entity. Which properties to get can be +// specified using the select option. +// See: +// https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/query-entities +// https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/querying-tables-and-entities +func (e *Entity) Get(timeout uint, ml MetadataLevel, options *GetEntityOptions) error { + if ml == EmptyPayload { + return errEmptyPayload + } + // RowKey and PartitionKey could be lost if not included in the query + // As those are the entity identifiers, it is best if they are not lost + rk := e.RowKey + pk := e.PartitionKey + + query := url.Values{ + "timeout": {strconv.FormatUint(uint64(timeout), 10)}, + } + headers := e.Table.tsc.client.getStandardHeaders() + headers[headerAccept] = string(ml) + + if options != nil { + if len(options.Select) > 0 { + query.Add("$select", strings.Join(options.Select, ",")) + } + headers = mergeHeaders(headers, headersFromStruct(*options)) + } + + uri := e.Table.tsc.client.getEndpoint(tableServiceName, e.buildPath(), query) + resp, err := e.Table.tsc.client.exec(http.MethodGet, uri, headers, nil, e.Table.tsc.auth) + if err != nil { + return err + } + defer readAndCloseBody(resp.body) + + if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + return err + } + + respBody, err := ioutil.ReadAll(resp.body) + if err != nil { + return err + } + err = json.Unmarshal(respBody, e) + if err != nil { + return err + } + e.PartitionKey = pk + e.RowKey = rk + + return nil +} + +// Insert inserts the referenced entity in its table. +// The function fails if there is an entity with the same +// PartitionKey and RowKey in the table. +// ml determines the level of detail of metadata in the operation response, +// or no data at all. +// See: https://docs.microsoft.com/rest/api/storageservices/fileservices/insert-entity +func (e *Entity) Insert(ml MetadataLevel, options *EntityOptions) error { + query, headers := options.getParameters() + headers = mergeHeaders(headers, e.Table.tsc.client.getStandardHeaders()) + + body, err := json.Marshal(e) + if err != nil { + return err + } + headers = addBodyRelatedHeaders(headers, len(body)) + headers = addReturnContentHeaders(headers, ml) + + uri := e.Table.tsc.client.getEndpoint(tableServiceName, e.Table.buildPath(), query) + resp, err := e.Table.tsc.client.exec(http.MethodPost, uri, headers, bytes.NewReader(body), e.Table.tsc.auth) + if err != nil { + return err + } + defer resp.body.Close() + + data, err := ioutil.ReadAll(resp.body) + if err != nil { + return err + } + + if ml != EmptyPayload { + if err = checkRespCode(resp.statusCode, []int{http.StatusCreated}); err != nil { + return err + } + if err = e.UnmarshalJSON(data); err != nil { + return err + } + } else { + if err = checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil { + return err + } + } + + return nil +} + +// Update updates the contents of an entity. The function fails if there is no entity +// with the same PartitionKey and RowKey in the table or if the ETag is different +// than the one in Azure. +// See: https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/update-entity2 +func (e *Entity) Update(force bool, options *EntityOptions) error { + return e.updateMerge(force, http.MethodPut, options) +} + +// Merge merges the contents of entity specified with PartitionKey and RowKey +// with the content specified in Properties. +// The function fails if there is no entity with the same PartitionKey and +// RowKey in the table or if the ETag is different than the one in Azure. +// Read more: https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/merge-entity +func (e *Entity) Merge(force bool, options *EntityOptions) error { + return e.updateMerge(force, "MERGE", options) +} + +// Delete deletes the entity. +// The function fails if there is no entity with the same PartitionKey and +// RowKey in the table or if the ETag is different than the one in Azure. +// See: https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/delete-entity1 +func (e *Entity) Delete(force bool, options *EntityOptions) error { + query, headers := options.getParameters() + headers = mergeHeaders(headers, e.Table.tsc.client.getStandardHeaders()) + + headers = addIfMatchHeader(headers, force, e.OdataEtag) + headers = addReturnContentHeaders(headers, EmptyPayload) + + uri := e.Table.tsc.client.getEndpoint(tableServiceName, e.buildPath(), query) + resp, err := e.Table.tsc.client.exec(http.MethodDelete, uri, headers, nil, e.Table.tsc.auth) + if err != nil { + if resp.statusCode == http.StatusPreconditionFailed { + return fmt.Errorf(etagErrorTemplate, err) + } + return err + } + defer readAndCloseBody(resp.body) + + if err = checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil { + return err + } + + return e.updateTimestamp(resp.headers) +} + +// InsertOrReplace inserts an entity or replaces the existing one. +// Read more: https://docs.microsoft.com/rest/api/storageservices/fileservices/insert-or-replace-entity +func (e *Entity) InsertOrReplace(options *EntityOptions) error { + return e.insertOr(http.MethodPut, options) +} + +// InsertOrMerge inserts an entity or merges the existing one. +// Read more: https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/insert-or-merge-entity +func (e *Entity) InsertOrMerge(options *EntityOptions) error { + return e.insertOr("MERGE", options) +} + +func (e *Entity) buildPath() string { + return fmt.Sprintf("%s(PartitionKey='%s', RowKey='%s')", e.Table.buildPath(), e.PartitionKey, e.RowKey) +} + +// MarshalJSON is a custom marshaller for entity +func (e *Entity) MarshalJSON() ([]byte, error) { + completeMap := map[string]interface{}{} + completeMap[partitionKeyNode] = e.PartitionKey + completeMap[rowKeyNode] = e.RowKey + for k, v := range e.Properties { + typeKey := strings.Join([]string{k, OdataTypeSuffix}, "") + switch t := v.(type) { + case []byte: + completeMap[typeKey] = OdataBinary + completeMap[k] = string(t) + case time.Time: + completeMap[typeKey] = OdataDateTime + completeMap[k] = t.Format(time.RFC3339Nano) + case uuid.UUID: + completeMap[typeKey] = OdataGUID + completeMap[k] = t.String() + case int64: + completeMap[typeKey] = OdataInt64 + completeMap[k] = fmt.Sprintf("%v", v) + default: + completeMap[k] = v + } + if strings.HasSuffix(k, OdataTypeSuffix) { + if !(completeMap[k] == OdataBinary || + completeMap[k] == OdataDateTime || + completeMap[k] == OdataGUID || + completeMap[k] == OdataInt64) { + return nil, fmt.Errorf("Odata.type annotation %v value is not valid", k) + } + valueKey := strings.TrimSuffix(k, OdataTypeSuffix) + if _, ok := completeMap[valueKey]; !ok { + return nil, fmt.Errorf("Odata.type annotation %v defined without value defined", k) + } + } + } + return json.Marshal(completeMap) +} + +// UnmarshalJSON is a custom unmarshaller for entities +func (e *Entity) UnmarshalJSON(data []byte) error { + errorTemplate := "Deserializing error: %v" + + props := map[string]interface{}{} + err := json.Unmarshal(data, &props) + if err != nil { + return err + } + + // deselialize metadata + e.OdataMetadata = stringFromMap(props, "odata.metadata") + e.OdataType = stringFromMap(props, "odata.type") + e.OdataID = stringFromMap(props, "odata.id") + e.OdataEtag = stringFromMap(props, "odata.etag") + e.OdataEditLink = stringFromMap(props, "odata.editLink") + e.PartitionKey = stringFromMap(props, partitionKeyNode) + e.RowKey = stringFromMap(props, rowKeyNode) + + // deserialize timestamp + timeStamp, ok := props["Timestamp"] + if ok { + str, ok := timeStamp.(string) + if !ok { + return fmt.Errorf(errorTemplate, "Timestamp casting error") + } + t, err := time.Parse(time.RFC3339Nano, str) + if err != nil { + return fmt.Errorf(errorTemplate, err) + } + e.TimeStamp = t + } + delete(props, "Timestamp") + delete(props, "Timestamp@odata.type") + + // deserialize entity (user defined fields) + for k, v := range props { + if strings.HasSuffix(k, OdataTypeSuffix) { + valueKey := strings.TrimSuffix(k, OdataTypeSuffix) + str, ok := props[valueKey].(string) + if !ok { + return fmt.Errorf(errorTemplate, fmt.Sprintf("%v casting error", v)) + } + switch v { + case OdataBinary: + props[valueKey] = []byte(str) + case OdataDateTime: + t, err := time.Parse("2006-01-02T15:04:05Z", str) + if err != nil { + return fmt.Errorf(errorTemplate, err) + } + props[valueKey] = t + case OdataGUID: + props[valueKey] = uuid.FromStringOrNil(str) + case OdataInt64: + i, err := strconv.ParseInt(str, 10, 64) + if err != nil { + return fmt.Errorf(errorTemplate, err) + } + props[valueKey] = i + default: + return fmt.Errorf(errorTemplate, fmt.Sprintf("%v is not supported", v)) + } + delete(props, k) + } + } + + e.Properties = props + return nil +} + +func getAndDelete(props map[string]interface{}, key string) interface{} { + if value, ok := props[key]; ok { + delete(props, key) + return value + } + return nil +} + +func addIfMatchHeader(h map[string]string, force bool, etag string) map[string]string { + if force { + h[headerIfMatch] = "*" + } else { + h[headerIfMatch] = etag + } + return h +} + +// updates Etag and timestamp +func (e *Entity) updateEtagAndTimestamp(headers http.Header) error { + e.OdataEtag = headers.Get(headerEtag) + return e.updateTimestamp(headers) +} + +func (e *Entity) updateTimestamp(headers http.Header) error { + str := headers.Get(headerDate) + t, err := time.Parse(time.RFC1123, str) + if err != nil { + return fmt.Errorf("Update timestamp error: %v", err) + } + e.TimeStamp = t + return nil +} + +func (e *Entity) insertOr(verb string, options *EntityOptions) error { + query, headers := options.getParameters() + headers = mergeHeaders(headers, e.Table.tsc.client.getStandardHeaders()) + + body, err := json.Marshal(e) + if err != nil { + return err + } + headers = addBodyRelatedHeaders(headers, len(body)) + headers = addReturnContentHeaders(headers, EmptyPayload) + + uri := e.Table.tsc.client.getEndpoint(tableServiceName, e.buildPath(), query) + resp, err := e.Table.tsc.client.exec(verb, uri, headers, bytes.NewReader(body), e.Table.tsc.auth) + if err != nil { + return err + } + defer readAndCloseBody(resp.body) + + if err = checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil { + return err + } + + return e.updateEtagAndTimestamp(resp.headers) +} + +func (e *Entity) updateMerge(force bool, verb string, options *EntityOptions) error { + query, headers := options.getParameters() + headers = mergeHeaders(headers, e.Table.tsc.client.getStandardHeaders()) + + body, err := json.Marshal(e) + if err != nil { + return err + } + headers = addBodyRelatedHeaders(headers, len(body)) + headers = addIfMatchHeader(headers, force, e.OdataEtag) + headers = addReturnContentHeaders(headers, EmptyPayload) + + uri := e.Table.tsc.client.getEndpoint(tableServiceName, e.buildPath(), query) + resp, err := e.Table.tsc.client.exec(verb, uri, headers, bytes.NewReader(body), e.Table.tsc.auth) + if err != nil { + if resp.statusCode == http.StatusPreconditionFailed { + return fmt.Errorf(etagErrorTemplate, err) + } + return err + } + defer readAndCloseBody(resp.body) + + if err = checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil { + return err + } + + return e.updateEtagAndTimestamp(resp.headers) +} + +func stringFromMap(props map[string]interface{}, key string) string { + value := getAndDelete(props, key) + if value != nil { + return value.(string) + } + return "" +} + +func (options *EntityOptions) getParameters() (url.Values, map[string]string) { + query := url.Values{} + headers := map[string]string{} + if options != nil { + query = addTimeout(query, options.Timeout) + headers = headersFromStruct(*options) + } + return query, headers +} diff --git a/storage/entity_test.go b/storage/entity_test.go new file mode 100644 index 000000000000..4d194111b18d --- /dev/null +++ b/storage/entity_test.go @@ -0,0 +1,549 @@ +package storage + +import ( + "encoding/json" + "fmt" + "time" + + "github.com/satori/uuid" + chk "gopkg.in/check.v1" +) + +type StorageEntitySuite struct{} + +var _ = chk.Suite(&StorageEntitySuite{}) + +func (s *StorageEntitySuite) TestGet(c *chk.C) { + cli := getTableClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + table := cli.GetTableReference(tableName(c)) + + err := table.Create(30, EmptyPayload, nil) + c.Assert(err, chk.IsNil) + defer table.Delete(30, nil) + + entity := table.GetEntityReference("mypartitionkey", "myrowkey") + + props := map[string]interface{}{ + "AmountDue": 200.23, + "CustomerCode": uuid.FromStringOrNil("c9da6455-213d-42c9-9a79-3e9149a57833"), + "CustomerSince": time.Date(1992, time.December, 20, 21, 55, 0, 0, time.UTC), + "IsActive": true, + "NumberOfOrders": int64(255), + } + entity.Properties = props + err = entity.Insert(EmptyPayload, nil) + c.Assert(err, chk.IsNil) + + err = entity.Get(30, FullMetadata, &GetEntityOptions{ + Select: []string{"IsActive"}, + }) + c.Assert(err, chk.IsNil) + c.Assert(entity.Properties, chk.HasLen, 1) + + err = entity.Get(30, FullMetadata, &GetEntityOptions{ + Select: []string{ + "AmountDue", + "CustomerCode", + "CustomerSince", + "IsActive", + "NumberOfOrders", + }}) + c.Assert(err, chk.IsNil) + c.Assert(entity.Properties, chk.HasLen, 5) + + err = entity.Get(30, FullMetadata, nil) + c.Assert(err, chk.IsNil) + c.Assert(entity.Properties, chk.HasLen, 5) +} + +const ( + validEtag = "W/\"datetime''2017-04-01T01%3A07%3A23.8881885Z''\"" +) + +func (s *StorageEntitySuite) TestInsert(c *chk.C) { + cli := getTableClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + table := cli.GetTableReference(tableName(c)) + err := table.Create(30, EmptyPayload, nil) + c.Assert(err, chk.IsNil) + defer table.Delete(30, nil) + + entity := table.GetEntityReference("mypartitionkey", "myrowkey") + + props := map[string]interface{}{ + "AmountDue": 200.23, + "CustomerCode": uuid.FromStringOrNil("c9da6455-213d-42c9-9a79-3e9149a57833"), + "CustomerSince": time.Date(1992, time.December, 20, 21, 55, 0, 0, time.UTC), + "IsActive": true, + "NumberOfOrders": int64(255), + } + entity.Properties = props + err = entity.Insert(EmptyPayload, nil) + c.Assert(err, chk.IsNil) + // Did not update + c.Assert(entity.TimeStamp, chk.Equals, time.Time{}) + c.Assert(entity.OdataMetadata, chk.Equals, "") + c.Assert(entity.OdataType, chk.Equals, "") + c.Assert(entity.OdataID, chk.Equals, "") + c.Assert(entity.OdataEtag, chk.Equals, "") + c.Assert(entity.OdataEditLink, chk.Equals, "") + + // Update + entity.PartitionKey = "mypartitionkey2" + entity.RowKey = "myrowkey2" + err = entity.Insert(FullMetadata, nil) + c.Assert(err, chk.IsNil) + // Check everything was updated... + c.Assert(entity.TimeStamp, chk.NotNil) + c.Assert(entity.OdataMetadata, chk.Not(chk.Equals), "") + c.Assert(entity.OdataType, chk.Not(chk.Equals), "") + c.Assert(entity.OdataID, chk.Not(chk.Equals), "") + c.Assert(entity.OdataEtag, chk.Not(chk.Equals), "") + c.Assert(entity.OdataEditLink, chk.Not(chk.Equals), "") +} + +func (s *StorageEntitySuite) TestUpdate(c *chk.C) { + cli := getTableClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + table := cli.GetTableReference(tableName(c)) + err := table.Create(30, EmptyPayload, nil) + c.Assert(err, chk.IsNil) + defer table.Delete(30, nil) + + entity := table.GetEntityReference("mypartitionkey", "myrowkey") + entity.Properties = map[string]interface{}{ + "AmountDue": 200.23, + "CustomerCode": uuid.FromStringOrNil("c9da6455-213d-42c9-9a79-3e9149a57833"), + "CustomerSince": time.Date(1992, time.December, 20, 21, 55, 0, 0, time.UTC), + "IsActive": true, + "NumberOfOrders": int64(255), + } + // Force update + err = entity.Insert(FullMetadata, nil) + c.Assert(err, chk.IsNil) + + etag := entity.OdataEtag + timestamp := entity.TimeStamp + + props := map[string]interface{}{ + "Name": "Anakin", + "FamilyName": "Skywalker", + "HasEpicTheme": true, + } + entity.Properties = props + // Update providing etag + err = entity.Update(false, nil) + c.Assert(err, chk.IsNil) + + c.Assert(entity.Properties, chk.DeepEquals, props) + c.Assert(entity.OdataEtag, chk.Not(chk.Equals), etag) + c.Assert(entity.TimeStamp, chk.Not(chk.Equals), timestamp) + + // Try to update with old etag + entity.OdataEtag = validEtag + err = entity.Update(false, nil) + c.Assert(err, chk.NotNil) + c.Assert(err, chk.ErrorMatches, "Etag didn't match: .*") + + // Force update + props = map[string]interface{}{ + "Name": "Leia", + "FamilyName": "Organa", + "HasAwesomeDress": true, + } + entity.Properties = props + err = entity.Update(true, nil) + c.Assert(err, chk.IsNil) + c.Assert(entity.Properties, chk.DeepEquals, props) +} + +func (s *StorageEntitySuite) TestMerge(c *chk.C) { + cli := getTableClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + table := cli.GetTableReference(tableName(c)) + err := table.Create(30, EmptyPayload, nil) + c.Assert(err, chk.IsNil) + defer table.Delete(30, nil) + + entity := table.GetEntityReference("mypartitionkey", "myrowkey") + entity.Properties = map[string]interface{}{ + "Country": "Mexico", + "MalePoet": "Nezahualcoyotl", + } + c.Assert(entity.Insert(FullMetadata, nil), chk.IsNil) + + etag := entity.OdataEtag + timestamp := entity.TimeStamp + + entity.Properties = map[string]interface{}{ + "FemalePoet": "Sor Juana Ines de la Cruz", + } + // Merge providing etag + err = entity.Merge(false, nil) + c.Assert(err, chk.IsNil) + c.Assert(entity.OdataEtag, chk.Not(chk.Equals), etag) + c.Assert(entity.TimeStamp, chk.Not(chk.Equals), timestamp) + + // Try to merge with incorrect etag + entity.OdataEtag = validEtag + err = entity.Merge(false, nil) + c.Assert(err, chk.NotNil) + c.Assert(err, chk.ErrorMatches, "Etag didn't match: .*") + + // Force merge + entity.Properties = map[string]interface{}{ + "MalePainter": "Diego Rivera", + "FemalePainter": "Frida Kahlo", + } + err = entity.Merge(true, nil) + c.Assert(err, chk.IsNil) +} + +func (s *StorageEntitySuite) TestDelete(c *chk.C) { + cli := getTableClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + table := cli.GetTableReference(tableName(c)) + err := table.Create(30, EmptyPayload, nil) + c.Assert(err, chk.IsNil) + defer table.Delete(30, nil) + + // Delete providing etag + entity1 := table.GetEntityReference("pkey1", "rowkey1") + c.Assert(entity1.Insert(FullMetadata, nil), chk.IsNil) + + err = entity1.Delete(false, nil) + c.Assert(err, chk.IsNil) + + // Try to delete with incorrect etag + entity2 := table.GetEntityReference("pkey2", "rowkey2") + c.Assert(entity2.Insert(EmptyPayload, nil), chk.IsNil) + entity2.OdataEtag = "GolangRocksOnAzure" + + err = entity2.Delete(false, nil) + c.Assert(err, chk.NotNil) + + // Force delete + err = entity2.Delete(true, nil) + c.Assert(err, chk.IsNil) +} + +func (s *StorageEntitySuite) TestInsertOrReplace(c *chk.C) { + cli := getTableClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + table := cli.GetTableReference(tableName(c)) + err := table.Create(30, EmptyPayload, nil) + c.Assert(err, chk.IsNil) + defer table.Delete(30, nil) + + entity := table.GetEntityReference("mypartitionkey", "myrowkey") + entity.Properties = map[string]interface{}{ + "Name": "Anakin", + "FamilyName": "Skywalker", + "HasEpicTheme": true, + } + + err = entity.InsertOrReplace(nil) + c.Assert(err, chk.IsNil) + + entity.Properties = map[string]interface{}{ + "Name": "Leia", + "FamilyName": "Organa", + "HasAwesomeDress": true, + } + err = entity.InsertOrReplace(nil) + c.Assert(err, chk.IsNil) +} + +func (s *StorageEntitySuite) TestInsertOrMerge(c *chk.C) { + cli := getTableClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + table := cli.GetTableReference(tableName(c)) + err := table.Create(30, EmptyPayload, nil) + c.Assert(err, chk.IsNil) + defer table.Delete(30, nil) + + entity := table.GetEntityReference("mypartitionkey", "myrowkey") + entity.Properties = map[string]interface{}{ + "Name": "Luke", + "FamilyName": "Skywalker", + } + + err = entity.InsertOrMerge(nil) + c.Assert(err, chk.IsNil) + + entity.Properties = map[string]interface{}{ + "Father": "Anakin", + "Mentor": "Yoda", + } + err = entity.InsertOrMerge(nil) + c.Assert(err, chk.IsNil) +} + +func (s *StorageEntitySuite) Test_InsertAndGetEntities(c *chk.C) { + cli := getTableClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + table := cli.GetTableReference(tableName(c)) + err := table.Create(30, EmptyPayload, nil) + c.Assert(err, chk.IsNil) + defer table.Delete(30, nil) + + entity := table.GetEntityReference("mypartitionkey", "100") + entity.Properties = map[string]interface{}{ + "Name": "Luke", + "FamilyName": "Skywalker", + "HasCoolWeapon": true, + } + c.Assert(entity.Insert(EmptyPayload, nil), chk.IsNil) + + entity.RowKey = "200" + c.Assert(entity.Insert(FullMetadata, nil), chk.IsNil) + + entities, err := table.QueryEntities(30, FullMetadata, nil) + c.Assert(err, chk.IsNil) + + c.Assert(entities.Entities, chk.HasLen, 2) + c.Assert(entities.OdataMetadata+"/@Element", chk.Equals, entity.OdataMetadata) + + compareEntities(entities.Entities[1], entity, c) +} + +func (s *StorageEntitySuite) Test_InsertAndExecuteQuery(c *chk.C) { + cli := getTableClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + table := cli.GetTableReference(tableName(c)) + err := table.Create(30, EmptyPayload, nil) + c.Assert(err, chk.IsNil) + defer table.Delete(30, nil) + + entity := table.GetEntityReference("mypartitionkey", "100") + entity.Properties = map[string]interface{}{ + "Name": "Luke", + "FamilyName": "Skywalker", + "HasCoolWeapon": true, + } + c.Assert(entity.Insert(EmptyPayload, nil), chk.IsNil) + + entity.RowKey = "200" + c.Assert(entity.Insert(EmptyPayload, nil), chk.IsNil) + + queryOptions := QueryOptions{ + Filter: "RowKey eq '200'", + } + + entities, err := table.QueryEntities(30, FullMetadata, &queryOptions) + c.Assert(err, chk.IsNil) + + c.Assert(entities.Entities, chk.HasLen, 1) + c.Assert(entities.Entities[0].RowKey, chk.Equals, entity.RowKey) +} + +func (s *StorageEntitySuite) Test_InsertAndDeleteEntities(c *chk.C) { + cli := getTableClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + table := cli.GetTableReference(tableName(c)) + err := table.Create(30, EmptyPayload, nil) + c.Assert(err, chk.IsNil) + defer table.Delete(30, nil) + + entity := table.GetEntityReference("mypartitionkey", "100") + entity.Properties = map[string]interface{}{ + "FamilyName": "Skywalker", + "Name": "Luke", + "Number": 3, + } + c.Assert(entity.Insert(EmptyPayload, nil), chk.IsNil) + + entity.Properties["Number"] = 1 + entity.RowKey = "200" + c.Assert(entity.Insert(FullMetadata, nil), chk.IsNil) + + options := QueryOptions{ + Filter: "Number eq 1", + } + + result, err := table.QueryEntities(30, FullMetadata, &options) + c.Assert(err, chk.IsNil) + c.Assert(result.Entities, chk.HasLen, 1) + compareEntities(result.Entities[0], entity, c) + + err = result.Entities[0].Delete(true, nil) + c.Assert(err, chk.IsNil) + + result, err = table.QueryEntities(30, FullMetadata, nil) + c.Assert(err, chk.IsNil) + + // only 1 entry must be present + c.Assert(result.Entities, chk.HasLen, 1) +} + +func (s *StorageEntitySuite) TestExecuteQueryNextResults(c *chk.C) { + cli := getTableClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + table := cli.GetTableReference(tableName(c)) + err := table.Create(30, EmptyPayload, nil) + c.Assert(err, chk.IsNil) + defer table.Delete(30, nil) + + var entityList []Entity + + for i := 0; i < 5; i++ { + entity := table.GetEntityReference("pkey", fmt.Sprintf("r%d", i)) + err := entity.Insert(FullMetadata, nil) + c.Assert(err, chk.IsNil) + entityList = append(entityList, entity) + } + + // retrieve using top = 2. Should return 2 entries, 2 entries and finally + // 1 entry + options := QueryOptions{ + Top: 2, + } + results, err := table.QueryEntities(30, FullMetadata, &options) + c.Assert(err, chk.IsNil) + c.Assert(results.Entities, chk.HasLen, 2) + c.Assert(results.NextLink, chk.NotNil) + compareEntities(results.Entities[0], entityList[0], c) + compareEntities(results.Entities[1], entityList[1], c) + + results, err = results.NextResults(nil) + c.Assert(err, chk.IsNil) + c.Assert(results.Entities, chk.HasLen, 2) + c.Assert(results.NextLink, chk.NotNil) + compareEntities(results.Entities[0], entityList[2], c) + compareEntities(results.Entities[1], entityList[3], c) + + results, err = results.NextResults(nil) + c.Assert(err, chk.IsNil) + c.Assert(results.Entities, chk.HasLen, 1) + c.Assert(results.NextLink, chk.IsNil) + compareEntities(results.Entities[0], entityList[4], c) +} + +func (s *StorageEntitySuite) Test_entityMarshalJSON(c *chk.C) { + expected := `{"Address":"Mountain View","Age":23,"AmountDue":200.23,"Binary":"abcd","Binary@odata.type":"Edm.Binary","CustomerCode":"c9da6455-213d-42c9-9a79-3e9149a57833","CustomerCode@odata.type":"Edm.Guid","CustomerSince":"1992-12-20T21:55:00Z","CustomerSince@odata.type":"Edm.DateTime","IsActive":true,"NumberOfOrders":"255","NumberOfOrders@odata.type":"Edm.Int64","PartitionKey":"mypartitionkey","RowKey":"myrowkey"}` + + entity := Entity{ + PartitionKey: "mypartitionkey", + RowKey: "myrowkey", + Properties: map[string]interface{}{ + "Address": "Mountain View", + "Age": 23, + "AmountDue": 200.23, + "Binary": []byte("abcd"), + "CustomerCode": uuid.FromStringOrNil("c9da6455-213d-42c9-9a79-3e9149a57833"), + "CustomerSince": time.Date(1992, time.December, 20, 21, 55, 0, 0, time.UTC), + "IsActive": true, + "NumberOfOrders": int64(255), + }, + } + got, err := json.Marshal(&entity) + c.Assert(err, chk.IsNil) + c.Assert(string(got), chk.Equals, expected) + + entity.Properties["Contoso@odata.type"] = "Edm.Trololololol" + got, err = json.Marshal(&entity) + c.Assert(got, chk.IsNil) + c.Assert(err, chk.ErrorMatches, ".*Odata.type annotation Contoso@odata.type value is not valid") + + entity.Properties["Contoso@odata.type"] = OdataGUID + got, err = json.Marshal(&entity) + c.Assert(got, chk.IsNil) + c.Assert(err, chk.ErrorMatches, ".*Odata.type annotation Contoso@odata.type defined without value defined") +} + +func (s *StorageEntitySuite) Test_entityUnmarshalJSON(c *chk.C) { + input := `{ + "odata.metadata":"https://azuregosdkstoragetests.table.core.windows.net/$metadata#SampleTable/@Element", + "odata.type":"azuregosdkstoragetests.SampleTable", + "odata.id":"https://azuregosdkstoragetests.table.core.windows.net/SampleTable(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')", + "odata.etag":"W/\"datetime''2017-01-27T01%3A01%3A44.151805Z''\"", + "odata.editLink":"SampleTable(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')", + "PartitionKey":"mypartitionkey", + "RowKey":"myrowkey", + "Timestamp":"2017-01-27T01:01:44.151805Z", + "Timestamp@odata.type":"Edm.DateTime", + "Address": "Mountain View", + "Age": 23, + "AmountDue":200.23, + "Binary@odata.type": "Edm.Binary", + "Binary": "abcd", + "CustomerCode@odata.type":"Edm.Guid", + "CustomerCode":"c9da6455-213d-42c9-9a79-3e9149a57833", + "CustomerSince@odata.type":"Edm.DateTime", + "CustomerSince":"1992-12-20T21:55:00Z", + "IsActive":true, + "NumberOfOrders@odata.type":"Edm.Int64", + "NumberOfOrders":"255"}` + + var entity Entity + data := []byte(input) + err := json.Unmarshal(data, &entity) + c.Assert(err, chk.IsNil) + + expectedProperties := map[string]interface{}{ + "Address": "Mountain View", + "Age": 23, + "AmountDue": 200.23, + "Binary": []byte("abcd"), + "CustomerCode": uuid.FromStringOrNil("c9da6455-213d-42c9-9a79-3e9149a57833"), + "CustomerSince": time.Date(1992, 12, 20, 21, 55, 0, 0, time.UTC), + "IsActive": true, + "NumberOfOrders": int64(255), + } + + c.Assert(entity.OdataMetadata, chk.Equals, "https://azuregosdkstoragetests.table.core.windows.net/$metadata#SampleTable/@Element") + c.Assert(entity.OdataType, chk.Equals, "azuregosdkstoragetests.SampleTable") + c.Assert(entity.OdataID, chk.Equals, "https://azuregosdkstoragetests.table.core.windows.net/SampleTable(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')") + c.Assert(entity.OdataEtag, chk.Equals, "W/\"datetime''2017-01-27T01%3A01%3A44.151805Z''\"") + c.Assert(entity.OdataEditLink, chk.Equals, "SampleTable(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')") + c.Assert(entity.PartitionKey, chk.Equals, "mypartitionkey") + c.Assert(entity.RowKey, chk.Equals, "myrowkey") + c.Assert(entity.TimeStamp, chk.Equals, time.Date(2017, 1, 27, 1, 1, 44, 151805000, time.UTC)) + + c.Assert(entity.Properties, chk.HasLen, len(expectedProperties)) + c.Assert(entity.Properties["Address"], chk.Equals, expectedProperties["Address"]) + // Note on Age assertion... Looks like the json unmarshaller thinks all numbers are float64. + c.Assert(entity.Properties["Age"], chk.Equals, float64(expectedProperties["Age"].(int))) + c.Assert(entity.Properties["AmountDue"], chk.Equals, expectedProperties["AmountDue"]) + c.Assert(entity.Properties["Binary"], chk.DeepEquals, expectedProperties["Binary"]) + c.Assert(entity.Properties["CustomerSince"], chk.Equals, expectedProperties["CustomerSince"]) + c.Assert(entity.Properties["IsActive"], chk.Equals, expectedProperties["IsActive"]) + c.Assert(entity.Properties["NumberOfOrders"], chk.Equals, expectedProperties["NumberOfOrders"]) + +} + +func compareEntities(got, expected Entity, c *chk.C) { + c.Assert(got.PartitionKey, chk.Equals, expected.PartitionKey) + c.Assert(got.RowKey, chk.Equals, expected.RowKey) + c.Assert(got.TimeStamp, chk.Equals, expected.TimeStamp) + + c.Assert(got.OdataEtag, chk.Equals, expected.OdataEtag) + c.Assert(got.OdataType, chk.Equals, expected.OdataType) + c.Assert(got.OdataID, chk.Equals, expected.OdataID) + c.Assert(got.OdataEditLink, chk.Equals, expected.OdataEditLink) + + c.Assert(got.Properties, chk.DeepEquals, expected.Properties) +} diff --git a/storage/file.go b/storage/file.go index e4901a1144f0..238ac6d6d95a 100644 --- a/storage/file.go +++ b/storage/file.go @@ -32,7 +32,7 @@ type FileProperties struct { Etag string Language string `header:"x-ms-content-language"` LastModified string - Length uint64 `xml:"Content-Length"` + Length uint64 `xml:"Content-Length" header:"x-ms-content-length"` MD5 string `header:"x-ms-content-md5"` Type string `header:"x-ms-content-type"` } @@ -54,26 +54,22 @@ type FileStream struct { } // FileRequestOptions will be passed to misc file operations. -// Currently just Timeout (in seconds) but will expand. +// Currently just Timeout (in seconds) but could expand. type FileRequestOptions struct { Timeout uint // timeout duration in seconds. } -// getParameters, construct parameters for FileRequestOptions. -// currently only timeout, but expecting to grow as functionality fills out. -func (p FileRequestOptions) getParameters() url.Values { - out := url.Values{} - - if p.Timeout != 0 { - out.Set("timeout", fmt.Sprintf("%v", p.Timeout)) +func prepareOptions(options *FileRequestOptions) url.Values { + params := url.Values{} + if options != nil { + params = addTimeout(params, options.Timeout) } - - return out + return params } // FileRanges contains a list of file range information for a file. // -// See https://msdn.microsoft.com/en-us/library/azure/dn166984.aspx +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/List-Ranges type FileRanges struct { ContentLength uint64 LastModified string @@ -83,7 +79,7 @@ type FileRanges struct { // FileRange contains range information for a file. // -// See https://msdn.microsoft.com/en-us/library/azure/dn166984.aspx +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/List-Ranges type FileRange struct { Start uint64 `xml:"Start"` End uint64 `xml:"End"` @@ -100,9 +96,13 @@ func (f *File) buildPath() string { // ClearRange releases the specified range of space in a file. // -// See https://msdn.microsoft.com/en-us/library/azure/dn194276.aspx -func (f *File) ClearRange(fileRange FileRange) error { - headers, err := f.modifyRange(nil, fileRange, nil) +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Put-Range +func (f *File) ClearRange(fileRange FileRange, options *FileRequestOptions) error { + var timeout *uint + if options != nil { + timeout = &options.Timeout + } + headers, err := f.modifyRange(nil, fileRange, timeout, nil) if err != nil { return err } @@ -113,24 +113,23 @@ func (f *File) ClearRange(fileRange FileRange) error { // Create creates a new file or replaces an existing one. // -// See https://msdn.microsoft.com/en-us/library/azure/dn194271.aspx -func (f *File) Create(maxSize uint64) error { +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Create-File +func (f *File) Create(maxSize uint64, options *FileRequestOptions) error { if maxSize > oneTB { return fmt.Errorf("max file size is 1TB") } + params := prepareOptions(options) + headers := headersFromStruct(f.Properties) + headers["x-ms-content-length"] = strconv.FormatUint(maxSize, 10) + headers["x-ms-type"] = "file" - extraHeaders := map[string]string{ - "x-ms-content-length": strconv.FormatUint(maxSize, 10), - "x-ms-type": "file", - } - - headers, err := f.fsc.createResource(f.buildPath(), resourceFile, nil, mergeMDIntoExtraHeaders(f.Metadata, extraHeaders), []int{http.StatusCreated}) + outputHeaders, err := f.fsc.createResource(f.buildPath(), resourceFile, params, mergeMDIntoExtraHeaders(f.Metadata, headers), []int{http.StatusCreated}) if err != nil { return err } f.Properties.Length = maxSize - f.updateEtagAndLastModified(headers) + f.updateEtagAndLastModified(outputHeaders) return nil } @@ -142,13 +141,9 @@ func (f *File) CopyFile(sourceURL string, options *FileRequestOptions) error { "x-ms-type": "file", "x-ms-copy-source": sourceURL, } + params := prepareOptions(options) - var parameters url.Values - if options != nil { - parameters = options.getParameters() - } - - headers, err := f.fsc.createResource(f.buildPath(), resourceFile, parameters, mergeMDIntoExtraHeaders(f.Metadata, extraHeaders), []int{http.StatusAccepted}) + headers, err := f.fsc.createResource(f.buildPath(), resourceFile, params, mergeMDIntoExtraHeaders(f.Metadata, extraHeaders), []int{http.StatusAccepted}) if err != nil { return err } @@ -159,16 +154,16 @@ func (f *File) CopyFile(sourceURL string, options *FileRequestOptions) error { // Delete immediately removes this file from the storage account. // -// See https://msdn.microsoft.com/en-us/library/azure/dn689085.aspx -func (f *File) Delete() error { - return f.fsc.deleteResource(f.buildPath(), resourceFile) +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Delete-File2 +func (f *File) Delete(options *FileRequestOptions) error { + return f.fsc.deleteResource(f.buildPath(), resourceFile, options) } // DeleteIfExists removes this file if it exists. // -// See https://msdn.microsoft.com/en-us/library/azure/dn689085.aspx -func (f *File) DeleteIfExists() (bool, error) { - resp, err := f.fsc.deleteResourceNoClose(f.buildPath(), resourceFile) +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Delete-File2 +func (f *File) DeleteIfExists(options *FileRequestOptions) (bool, error) { + resp, err := f.fsc.deleteResourceNoClose(f.buildPath(), resourceFile, options) if resp != nil { defer readAndCloseBody(resp.body) if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound { @@ -178,33 +173,59 @@ func (f *File) DeleteIfExists() (bool, error) { return false, err } -// DownloadRangeToStream operation downloads the specified range of this file with optional MD5 hash. +// GetFileOptions includes options for a get file operation +type GetFileOptions struct { + Timeout uint + GetContentMD5 bool +} + +// DownloadToStream operation downloads the file. // -// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-file -func (f *File) DownloadRangeToStream(fileRange FileRange, getContentMD5 bool) (fs FileStream, err error) { - if getContentMD5 && isRangeTooBig(fileRange) { - return fs, fmt.Errorf("must specify a range less than or equal to 4MB when getContentMD5 is true") +// See: https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-file +func (f *File) DownloadToStream(options *FileRequestOptions) (io.ReadCloser, error) { + params := prepareOptions(options) + resp, err := f.fsc.getResourceNoClose(f.buildPath(), compNone, resourceFile, params, http.MethodGet, nil) + if err != nil { + return nil, err + } + + if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + readAndCloseBody(resp.body) + return nil, err } + return resp.body, nil +} +// DownloadRangeToStream operation downloads the specified range of this file with optional MD5 hash. +// +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-file +func (f *File) DownloadRangeToStream(fileRange FileRange, options *GetFileOptions) (fs FileStream, err error) { extraHeaders := map[string]string{ "Range": fileRange.String(), } - if getContentMD5 == true { - extraHeaders["x-ms-range-get-content-md5"] = "true" + params := url.Values{} + if options != nil { + if options.GetContentMD5 { + if isRangeTooBig(fileRange) { + return fs, fmt.Errorf("must specify a range less than or equal to 4MB when getContentMD5 is true") + } + extraHeaders["x-ms-range-get-content-md5"] = "true" + } + params = addTimeout(params, options.Timeout) } - resp, err := f.fsc.getResourceNoClose(f.buildPath(), compNone, resourceFile, http.MethodGet, extraHeaders) + resp, err := f.fsc.getResourceNoClose(f.buildPath(), compNone, resourceFile, params, http.MethodGet, extraHeaders) if err != nil { return fs, err } if err = checkRespCode(resp.statusCode, []int{http.StatusOK, http.StatusPartialContent}); err != nil { - resp.body.Close() + readAndCloseBody(resp.body) return fs, err } fs.Body = resp.body - if getContentMD5 { + if options != nil && options.GetContentMD5 { fs.ContentMD5 = resp.headers.Get("Content-MD5") } return fs, nil @@ -221,8 +242,10 @@ func (f *File) Exists() (bool, error) { } // FetchAttributes updates metadata and properties for this file. -func (f *File) FetchAttributes() error { - headers, err := f.fsc.getResourceHeaders(f.buildPath(), compNone, resourceFile, http.MethodHead) +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-file-properties +func (f *File) FetchAttributes(options *FileRequestOptions) error { + params := prepareOptions(options) + headers, err := f.fsc.getResourceHeaders(f.buildPath(), compNone, resourceFile, params, http.MethodHead) if err != nil { return err } @@ -242,17 +265,26 @@ func isRangeTooBig(fileRange FileRange) bool { return false } +// ListRangesOptions includes options for a list file ranges operation +type ListRangesOptions struct { + Timeout uint + ListRange *FileRange +} + // ListRanges returns the list of valid ranges for this file. // -// See https://msdn.microsoft.com/en-us/library/azure/dn166984.aspx -func (f *File) ListRanges(listRange *FileRange) (*FileRanges, error) { +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/List-Ranges +func (f *File) ListRanges(options *ListRangesOptions) (*FileRanges, error) { params := url.Values{"comp": {"rangelist"}} // add optional range to list var headers map[string]string - if listRange != nil { - headers = make(map[string]string) - headers["Range"] = listRange.String() + if options != nil { + params = addTimeout(params, options.Timeout) + if options.ListRange != nil { + headers = make(map[string]string) + headers["Range"] = options.ListRange.String() + } } resp, err := f.fsc.listContent(f.buildPath(), params, headers) @@ -278,7 +310,7 @@ func (f *File) ListRanges(listRange *FileRange) (*FileRanges, error) { } // modifies a range of bytes in this file -func (f *File) modifyRange(bytes io.Reader, fileRange FileRange, contentMD5 *string) (http.Header, error) { +func (f *File) modifyRange(bytes io.Reader, fileRange FileRange, timeout *uint, contentMD5 *string) (http.Header, error) { if err := f.fsc.checkForStorageEmulator(); err != nil { return nil, err } @@ -289,7 +321,12 @@ func (f *File) modifyRange(bytes io.Reader, fileRange FileRange, contentMD5 *str return nil, errors.New("range cannot exceed 4MB in size") } - uri := f.fsc.client.getEndpoint(fileServiceName, f.buildPath(), url.Values{"comp": {"range"}}) + params := url.Values{"comp": {"range"}} + if timeout != nil { + params = addTimeout(params, *timeout) + } + + uri := f.fsc.client.getEndpoint(fileServiceName, f.buildPath(), params) // default to clear write := "clear" @@ -327,9 +364,9 @@ func (f *File) modifyRange(bytes io.Reader, fileRange FileRange, contentMD5 *str // are case-insensitive so case munging should not matter to other // applications either. // -// See https://msdn.microsoft.com/en-us/library/azure/dn689097.aspx -func (f *File) SetMetadata() error { - headers, err := f.fsc.setResourceHeaders(f.buildPath(), compMetadata, resourceFile, mergeMDIntoExtraHeaders(f.Metadata, nil)) +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Set-File-Metadata +func (f *File) SetMetadata(options *FileRequestOptions) error { + headers, err := f.fsc.setResourceHeaders(f.buildPath(), compMetadata, resourceFile, mergeMDIntoExtraHeaders(f.Metadata, nil), options) if err != nil { return err } @@ -345,9 +382,9 @@ func (f *File) SetMetadata() error { // are case-insensitive so case munging should not matter to other // applications either. // -// See https://msdn.microsoft.com/en-us/library/azure/dn166975.aspx -func (f *File) SetProperties() error { - headers, err := f.fsc.setResourceHeaders(f.buildPath(), compProperties, resourceFile, headersFromStruct(f.Properties)) +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Set-File-Properties +func (f *File) SetProperties(options *FileRequestOptions) error { + headers, err := f.fsc.setResourceHeaders(f.buildPath(), compProperties, resourceFile, headersFromStruct(f.Properties), options) if err != nil { return err } @@ -390,19 +427,32 @@ func (f *File) updateProperties(header http.Header) { // This method does not create a publicly accessible URL if the file // is private and this method does not check if the file exists. func (f *File) URL() string { - return f.fsc.client.getEndpoint(fileServiceName, f.buildPath(), url.Values{}) + return f.fsc.client.getEndpoint(fileServiceName, f.buildPath(), nil) } -// WriteRange writes a range of bytes to this file with an optional MD5 hash of the content. -// Note that the length of bytes must match (rangeEnd - rangeStart) + 1 with a maximum size of 4MB. +// WriteRangeOptions includes opptions for a write file range operation +type WriteRangeOptions struct { + Timeout uint + ContentMD5 string +} + +// WriteRange writes a range of bytes to this file with an optional MD5 hash of the content (inside +// options parameter). Note that the length of bytes must match (rangeEnd - rangeStart) + 1 with +// a maximum size of 4MB. // -// See https://msdn.microsoft.com/en-us/library/azure/dn194276.aspx -func (f *File) WriteRange(bytes io.Reader, fileRange FileRange, contentMD5 *string) error { +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Put-Range +func (f *File) WriteRange(bytes io.Reader, fileRange FileRange, options *WriteRangeOptions) error { if bytes == nil { return errors.New("bytes cannot be nil") } + var timeout *uint + var md5 *string + if options != nil { + timeout = &options.Timeout + md5 = &options.ContentMD5 + } - headers, err := f.modifyRange(bytes, fileRange, contentMD5) + headers, err := f.modifyRange(bytes, fileRange, timeout, md5) if err != nil { return err } diff --git a/storage/file_test.go b/storage/file_test.go index 86e0283e1565..4993f302ff27 100644 --- a/storage/file_test.go +++ b/storage/file_test.go @@ -14,19 +14,22 @@ type StorageFileSuite struct{} var _ = chk.Suite(&StorageFileSuite{}) func (s *StorageFileSuite) TestCreateFile(c *chk.C) { - // create share cli := getFileClient(c) - share := cli.GetShareReference(randShare()) + cli.deleteAllShares() + rec := cli.client.appendRecorder(c) + defer rec.Stop() - c.Assert(share.Create(), chk.IsNil) - defer share.Delete() + // create share + share := cli.GetShareReference(shareName(c)) + c.Assert(share.Create(nil), chk.IsNil) + defer share.Delete(nil) root := share.GetRootDirectoryReference() // create directory structure dir1 := root.GetDirectoryReference("one") - c.Assert(dir1.Create(), chk.IsNil) + c.Assert(dir1.Create(nil), chk.IsNil) dir2 := dir1.GetDirectoryReference("two") - c.Assert(dir2.Create(), chk.IsNil) + c.Assert(dir2.Create(nil), chk.IsNil) // verify file doesn't exist file := dir2.GetFileReference("some.file") @@ -35,32 +38,31 @@ func (s *StorageFileSuite) TestCreateFile(c *chk.C) { c.Assert(exists, chk.Equals, false) // create file - c.Assert(file.Create(1024), chk.IsNil) - exists, err = file.Exists() - c.Assert(err, chk.IsNil) - c.Assert(exists, chk.Equals, true) + c.Assert(file.Create(1024, nil), chk.IsNil) // delete file and verify - c.Assert(file.Delete(), chk.IsNil) + c.Assert(file.Delete(nil), chk.IsNil) exists, err = file.Exists() c.Assert(err, chk.IsNil) c.Assert(exists, chk.Equals, false) } func (s *StorageFileSuite) TestGetFile(c *chk.C) { - // create share cli := getFileClient(c) - share := cli.GetShareReference(randShare()) + rec := cli.client.appendRecorder(c) + defer rec.Stop() - c.Assert(share.Create(), chk.IsNil) - defer share.Delete() + // create share + share := cli.GetShareReference(shareName(c)) + c.Assert(share.Create(nil), chk.IsNil) + defer share.Delete(nil) root := share.GetRootDirectoryReference() // create file const size = uint64(1024) byteStream, _ := newByteStream(size) file := root.GetFileReference("some.file") - c.Assert(file.Create(size), chk.IsNil) + c.Assert(file.Create(size, nil), chk.IsNil) // fill file with some data c.Assert(file.WriteRange(byteStream, FileRange{End: size - 1}, nil), chk.IsNil) @@ -71,10 +73,13 @@ func (s *StorageFileSuite) TestGetFile(c *chk.C) { "another": "anothervalue", } file.Metadata = md - c.Assert(file.SetMetadata(), chk.IsNil) + c.Assert(file.SetMetadata(nil), chk.IsNil) + options := GetFileOptions{ + GetContentMD5: false, + } // retrieve full file content and verify - stream, err := file.DownloadRangeToStream(FileRange{Start: 0, End: size - 1}, false) + stream, err := file.DownloadRangeToStream(FileRange{Start: 0, End: size - 1}, &options) c.Assert(err, chk.IsNil) defer stream.Body.Close() var b1 [size]byte @@ -86,7 +91,7 @@ func (s *StorageFileSuite) TestGetFile(c *chk.C) { c.Assert(b1, chk.DeepEquals, c1) // retrieve partial file content and verify - stream, err = file.DownloadRangeToStream(FileRange{Start: size / 2, End: size - 1}, false) + stream, err = file.DownloadRangeToStream(FileRange{Start: size / 2, End: size - 1}, &options) c.Assert(err, chk.IsNil) defer stream.Body.Close() var b2 [size / 2]byte @@ -99,40 +104,50 @@ func (s *StorageFileSuite) TestGetFile(c *chk.C) { } func (s *StorageFileSuite) TestFileRanges(c *chk.C) { - // create share cli := getFileClient(c) - share := cli.GetShareReference(randShare()) + rec := cli.client.appendRecorder(c) + defer rec.Stop() - c.Assert(share.Create(), chk.IsNil) - defer share.Delete() + share := cli.GetShareReference(shareName(c)) + c.Assert(share.Create(nil), chk.IsNil) + defer share.Delete(nil) root := share.GetRootDirectoryReference() - // create file fileSize := uint64(4096) - byteStream, _ := newByteStream(fileSize) - file := root.GetFileReference("test.dat") - c.Assert(file.Create(fileSize), chk.IsNil) + contentBytes := content(int(fileSize)) + + // --- File with no valid ranges + file1 := root.GetFileReference("file1.txt") + c.Assert(file1.Create(fileSize, nil), chk.IsNil) - // verify there are no valid ranges - ranges, err := file.ListRanges(nil) + ranges, err := file1.ListRanges(nil) c.Assert(err, chk.IsNil) c.Assert(ranges.ContentLength, chk.Equals, fileSize) c.Assert(ranges.FileRanges, chk.IsNil) - // fill entire range and validate - c.Assert(file.WriteRange(byteStream, FileRange{End: fileSize - 1}, nil), chk.IsNil) - ranges, err = file.ListRanges(nil) + // --- File after writing a range + file2 := root.GetFileReference("file2.txt") + c.Assert(file2.Create(fileSize, nil), chk.IsNil) + c.Assert(file2.WriteRange(bytes.NewReader(contentBytes), FileRange{End: fileSize - 1}, nil), chk.IsNil) + + ranges, err = file2.ListRanges(nil) c.Assert(err, chk.IsNil) c.Assert(len(ranges.FileRanges), chk.Equals, 1) c.Assert((ranges.FileRanges[0].End-ranges.FileRanges[0].Start)+1, chk.Equals, fileSize) - // clear entire range and validate - c.Assert(file.ClearRange(FileRange{End: fileSize - 1}), chk.IsNil) - ranges, err = file.ListRanges(nil) + // --- File after writing and clearing + file3 := root.GetFileReference("file3.txt") + c.Assert(file3.Create(fileSize, nil), chk.IsNil) + c.Assert(file3.WriteRange(bytes.NewReader(contentBytes), FileRange{End: fileSize - 1}, nil), chk.IsNil) + c.Assert(file3.ClearRange(FileRange{End: fileSize - 1}, nil), chk.IsNil) + + ranges, err = file3.ListRanges(nil) c.Assert(err, chk.IsNil) c.Assert(ranges.FileRanges, chk.IsNil) - // put partial ranges on 512 byte aligned boundaries + // --- File with ranges and subranges + file4 := root.GetFileReference("file4.txt") + c.Assert(file4.Create(fileSize, nil), chk.IsNil) putRanges := []FileRange{ {End: 511}, {Start: 1024, End: 1535}, @@ -141,43 +156,58 @@ func (s *StorageFileSuite) TestFileRanges(c *chk.C) { } for _, r := range putRanges { - byteStream, _ = newByteStream(512) - err = file.WriteRange(byteStream, r, nil) + err = file4.WriteRange(bytes.NewReader(contentBytes[:512]), r, nil) c.Assert(err, chk.IsNil) } // validate all ranges - ranges, err = file.ListRanges(nil) + ranges, err = file4.ListRanges(nil) c.Assert(err, chk.IsNil) c.Assert(ranges.FileRanges, chk.DeepEquals, putRanges) + options := ListRangesOptions{ + ListRange: &FileRange{ + Start: 1000, + End: 3000, + }, + } // validate sub-ranges - ranges, err = file.ListRanges(&FileRange{Start: 1000, End: 3000}) + ranges, err = file4.ListRanges(&options) c.Assert(err, chk.IsNil) c.Assert(ranges.FileRanges, chk.DeepEquals, putRanges[1:3]) - // clear partial range and validate - c.Assert(file.ClearRange(putRanges[0]), chk.IsNil) - c.Assert(file.ClearRange(putRanges[2]), chk.IsNil) - ranges, err = file.ListRanges(nil) + // --- clear partial range and validate + file5 := root.GetFileReference("file5.txt") + c.Assert(file5.Create(fileSize, nil), chk.IsNil) + c.Assert(file5.WriteRange(bytes.NewReader(contentBytes), FileRange{End: fileSize - 1}, nil), chk.IsNil) + c.Assert(file5.ClearRange(putRanges[0], nil), chk.IsNil) + c.Assert(file5.ClearRange(putRanges[2], nil), chk.IsNil) + + ranges, err = file5.ListRanges(nil) c.Assert(err, chk.IsNil) + expectedtRanges := []FileRange{ + {Start: 512, End: 2047}, + {Start: 2560, End: 4095}, + } c.Assert(ranges.FileRanges, chk.HasLen, 2) - c.Assert(ranges.FileRanges[0], chk.DeepEquals, putRanges[1]) - c.Assert(ranges.FileRanges[1], chk.DeepEquals, putRanges[3]) + c.Assert(ranges.FileRanges[0], chk.DeepEquals, expectedtRanges[0]) + c.Assert(ranges.FileRanges[1], chk.DeepEquals, expectedtRanges[1]) } func (s *StorageFileSuite) TestFileProperties(c *chk.C) { - // create share cli := getFileClient(c) - share := cli.GetShareReference(randShare()) + rec := cli.client.appendRecorder(c) + defer rec.Stop() - c.Assert(share.Create(), chk.IsNil) - defer share.Delete() + // create share + share := cli.GetShareReference(shareName(c)) + c.Assert(share.Create(nil), chk.IsNil) + defer share.Delete(nil) root := share.GetRootDirectoryReference() fileSize := uint64(512) file := root.GetFileReference("test.dat") - c.Assert(file.Create(fileSize), chk.IsNil) + c.Assert(file.Create(fileSize, nil), chk.IsNil) // get initial set of properties c.Assert(file.Properties.Length, chk.Equals, fileSize) @@ -194,10 +224,10 @@ func (s *StorageFileSuite) TestFileProperties(c *chk.C) { file.Properties.Disposition = disp file.Properties.Encoding = enc file.Properties.Language = lang - c.Assert(file.SetProperties(), chk.IsNil) + c.Assert(file.SetProperties(nil), chk.IsNil) // retrieve and verify - c.Assert(file.FetchAttributes(), chk.IsNil) + c.Assert(file.FetchAttributes(nil), chk.IsNil) c.Assert(file.Properties.CacheControl, chk.Equals, cc) c.Assert(file.Properties.Type, chk.Equals, ct) c.Assert(file.Properties.Disposition, chk.Equals, disp) @@ -206,17 +236,19 @@ func (s *StorageFileSuite) TestFileProperties(c *chk.C) { } func (s *StorageFileSuite) TestFileMetadata(c *chk.C) { - // create share cli := getFileClient(c) - share := cli.GetShareReference(randShare()) + rec := cli.client.appendRecorder(c) + defer rec.Stop() - c.Assert(share.Create(), chk.IsNil) - defer share.Delete() + // create share + share := cli.GetShareReference(shareName(c)) + c.Assert(share.Create(nil), chk.IsNil) + defer share.Delete(nil) root := share.GetRootDirectoryReference() fileSize := uint64(512) file := root.GetFileReference("test.dat") - c.Assert(file.Create(fileSize), chk.IsNil) + c.Assert(file.Create(fileSize, nil), chk.IsNil) // get metadata, shouldn't be any c.Assert(file.Metadata, chk.HasLen, 0) @@ -227,34 +259,42 @@ func (s *StorageFileSuite) TestFileMetadata(c *chk.C) { "another": "anothervalue", } file.Metadata = md - c.Assert(file.SetMetadata(), chk.IsNil) + c.Assert(file.SetMetadata(nil), chk.IsNil) // retrieve and verify - c.Assert(file.FetchAttributes(), chk.IsNil) + c.Assert(file.FetchAttributes(nil), chk.IsNil) c.Assert(file.Metadata, chk.DeepEquals, md) } func (s *StorageFileSuite) TestFileMD5(c *chk.C) { - // create share cli := getFileClient(c) - share := cli.GetShareReference(randShare()) + rec := cli.client.appendRecorder(c) + defer rec.Stop() - c.Assert(share.Create(), chk.IsNil) - defer share.Delete() + // create share + share := cli.GetShareReference(shareName(c)) + c.Assert(share.Create(nil), chk.IsNil) + defer share.Delete(nil) root := share.GetRootDirectoryReference() // create file const size = uint64(1024) fileSize := uint64(size) file := root.GetFileReference("test.dat") - c.Assert(file.Create(fileSize), chk.IsNil) + c.Assert(file.Create(fileSize, nil), chk.IsNil) // fill file with some data and MD5 hash byteStream, contentMD5 := newByteStream(size) - c.Assert(file.WriteRange(byteStream, FileRange{End: size - 1}, &contentMD5), chk.IsNil) + options := WriteRangeOptions{ + ContentMD5: contentMD5, + } + c.Assert(file.WriteRange(byteStream, FileRange{End: size - 1}, &options), chk.IsNil) // download file and verify - stream, err := file.DownloadRangeToStream(FileRange{Start: 0, End: size - 1}, true) + downloadOptions := GetFileOptions{ + GetContentMD5: true, + } + stream, err := file.DownloadRangeToStream(FileRange{Start: 0, End: size - 1}, &downloadOptions) c.Assert(err, chk.IsNil) defer stream.Body.Close() c.Assert(stream.ContentMD5, chk.Equals, contentMD5) @@ -274,31 +314,27 @@ func newByteStream(count uint64) (io.Reader, string) { } func (s *StorageFileSuite) TestCopyFileSameAccountNoMetaData(c *chk.C) { - - // create share cli := getFileClient(c) - share := cli.GetShareReference(randShare()) + rec := cli.client.appendRecorder(c) + defer rec.Stop() - c.Assert(share.Create(), chk.IsNil) - defer share.Delete() + // create share + share := cli.GetShareReference(shareName(c)) + c.Assert(share.Create(nil), chk.IsNil) + defer share.Delete(nil) root := share.GetRootDirectoryReference() // create directory structure dir1 := root.GetDirectoryReference("one") - c.Assert(dir1.Create(), chk.IsNil) + c.Assert(dir1.Create(nil), chk.IsNil) dir2 := dir1.GetDirectoryReference("two") - c.Assert(dir2.Create(), chk.IsNil) + c.Assert(dir2.Create(nil), chk.IsNil) - // verify file doesn't exist + // create file file := dir2.GetFileReference("some.file") + c.Assert(file.Create(1024, nil), chk.IsNil) exists, err := file.Exists() c.Assert(err, chk.IsNil) - c.Assert(exists, chk.Equals, false) - - // create file - c.Assert(file.Create(1024), chk.IsNil) - exists, err = file.Exists() - c.Assert(err, chk.IsNil) c.Assert(exists, chk.Equals, true) otherFile := dir2.GetFileReference("someother.file") @@ -307,81 +343,57 @@ func (s *StorageFileSuite) TestCopyFileSameAccountNoMetaData(c *chk.C) { err = otherFile.CopyFile(file.URL(), nil) c.Assert(err, chk.IsNil) - // delete file and verify - c.Assert(file.Delete(), chk.IsNil) - c.Assert(otherFile.Delete(), chk.IsNil) - exists, err = file.Exists() - c.Assert(err, chk.IsNil) - c.Assert(exists, chk.Equals, false) - - exists, err = otherFile.Exists() - c.Assert(err, chk.IsNil) - c.Assert(exists, chk.Equals, false) - + // delete files + c.Assert(file.Delete(nil), chk.IsNil) + c.Assert(otherFile.Delete(nil), chk.IsNil) } func (s *StorageFileSuite) TestCopyFileSameAccountTimeout(c *chk.C) { - // create share cli := getFileClient(c) - share := cli.GetShareReference(randShare()) + rec := cli.client.appendRecorder(c) + defer rec.Stop() - c.Assert(share.Create(), chk.IsNil) - defer share.Delete() + // create share + share := cli.GetShareReference(shareName(c)) + c.Assert(share.Create(nil), chk.IsNil) + defer share.Delete(nil) root := share.GetRootDirectoryReference() // create directory structure dir1 := root.GetDirectoryReference("one") - c.Assert(dir1.Create(), chk.IsNil) + c.Assert(dir1.Create(nil), chk.IsNil) dir2 := dir1.GetDirectoryReference("two") - c.Assert(dir2.Create(), chk.IsNil) - - // verify file doesn't exist - file := dir2.GetFileReference("some.file") - exists, err := file.Exists() - c.Assert(err, chk.IsNil) - c.Assert(exists, chk.Equals, false) + c.Assert(dir2.Create(nil), chk.IsNil) // create file - c.Assert(file.Create(1024), chk.IsNil) - exists, err = file.Exists() - c.Assert(err, chk.IsNil) - c.Assert(exists, chk.Equals, true) + file := dir2.GetFileReference("some.file") + c.Assert(file.Create(1024, nil), chk.IsNil) + // copy the file, 60 second timeout. otherFile := dir2.GetFileReference("someother.file") - options := FileRequestOptions{} options.Timeout = 60 + c.Assert(otherFile.CopyFile(file.URL(), &options), chk.IsNil) - // copy the file, 60 second timeout. - err = otherFile.CopyFile(file.URL(), &options) - c.Assert(err, chk.IsNil) - - // delete file and verify - c.Assert(file.Delete(), chk.IsNil) - c.Assert(otherFile.Delete(), chk.IsNil) - exists, err = file.Exists() - c.Assert(err, chk.IsNil) - c.Assert(exists, chk.Equals, false) - - exists, err = otherFile.Exists() - c.Assert(err, chk.IsNil) - c.Assert(exists, chk.Equals, false) - + // delete files + c.Assert(file.Delete(nil), chk.IsNil) + c.Assert(otherFile.Delete(nil), chk.IsNil) } func (s *StorageFileSuite) TestCopyFileMissingFile(c *chk.C) { - - // create share cli := getFileClient(c) - share := cli.GetShareReference(randShare()) + rec := cli.client.appendRecorder(c) + defer rec.Stop() - c.Assert(share.Create(), chk.IsNil) - defer share.Delete() + // create share + share := cli.GetShareReference(shareName(c)) + c.Assert(share.Create(nil), chk.IsNil) + defer share.Delete(nil) root := share.GetRootDirectoryReference() // create directory structure dir1 := root.GetDirectoryReference("one") - c.Assert(dir1.Create(), chk.IsNil) + c.Assert(dir1.Create(nil), chk.IsNil) otherFile := dir1.GetFileReference("someother.file") diff --git a/storage/fileserviceclient.go b/storage/fileserviceclient.go index d68bd7f64e98..30554238f4d7 100644 --- a/storage/fileserviceclient.go +++ b/storage/fileserviceclient.go @@ -5,7 +5,7 @@ import ( "fmt" "net/http" "net/url" - "strings" + "strconv" ) // FileServiceClient contains operations for Microsoft Azure File Service. @@ -17,7 +17,7 @@ type FileServiceClient struct { // ListSharesParameters defines the set of customizable parameters to make a // List Shares call. // -// See https://msdn.microsoft.com/en-us/library/azure/dn167009.aspx +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/List-Shares type ListSharesParameters struct { Prefix string Marker string @@ -29,7 +29,7 @@ type ListSharesParameters struct { // ShareListResponse contains the response fields from // ListShares call. // -// See https://msdn.microsoft.com/en-us/library/azure/dn167009.aspx +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/List-Shares type ShareListResponse struct { XMLName xml.Name `xml:"EnumerationResults"` Xmlns string `xml:"xmlns,attr"` @@ -79,10 +79,10 @@ func (p ListSharesParameters) getParameters() url.Values { out.Set("include", p.Include) } if p.MaxResults != 0 { - out.Set("maxresults", fmt.Sprintf("%v", p.MaxResults)) + out.Set("maxresults", strconv.FormatUint(uint64(p.MaxResults), 10)) } if p.Timeout != 0 { - out.Set("timeout", fmt.Sprintf("%v", p.Timeout)) + out.Set("timeout", strconv.FormatUint(uint64(p.Timeout), 10)) } return out @@ -91,15 +91,16 @@ func (p ListSharesParameters) getParameters() url.Values { func (p ListDirsAndFilesParameters) getParameters() url.Values { out := url.Values{} + if p.Prefix != "" { + out.Set("prefix", p.Prefix) + } if p.Marker != "" { out.Set("marker", p.Marker) } if p.MaxResults != 0 { - out.Set("maxresults", fmt.Sprintf("%v", p.MaxResults)) - } - if p.Timeout != 0 { - out.Set("timeout", fmt.Sprintf("%v", p.Timeout)) + out.Set("maxresults", strconv.FormatUint(uint64(p.MaxResults), 10)) } + out = addTimeout(out, p.Timeout) return out } @@ -130,7 +131,7 @@ func (f FileServiceClient) GetShareReference(name string) Share { // ListShares returns the list of shares in a storage account along with // pagination token and other response details. // -// See https://msdn.microsoft.com/en-us/library/azure/dd179352.aspx +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/list-shares func (f FileServiceClient) ListShares(params ListSharesParameters) (*ShareListResponse, error) { q := mergeParams(params.getParameters(), url.Values{"comp": {"list"}}) @@ -231,8 +232,8 @@ func (f FileServiceClient) createResourceNoClose(path string, res resourceType, } // returns HTTP header data for the specified directory or share -func (f FileServiceClient) getResourceHeaders(path string, comp compType, res resourceType, verb string) (http.Header, error) { - resp, err := f.getResourceNoClose(path, comp, res, verb, nil) +func (f FileServiceClient) getResourceHeaders(path string, comp compType, res resourceType, params url.Values, verb string) (http.Header, error) { + resp, err := f.getResourceNoClose(path, comp, res, params, verb, nil) if err != nil { return nil, err } @@ -246,22 +247,21 @@ func (f FileServiceClient) getResourceHeaders(path string, comp compType, res re } // gets the specified resource, doesn't close the response body -func (f FileServiceClient) getResourceNoClose(path string, comp compType, res resourceType, verb string, extraHeaders map[string]string) (*storageResponse, error) { +func (f FileServiceClient) getResourceNoClose(path string, comp compType, res resourceType, params url.Values, verb string, extraHeaders map[string]string) (*storageResponse, error) { if err := f.checkForStorageEmulator(); err != nil { return nil, err } - params := getURLInitValues(comp, res) + params = mergeParams(params, getURLInitValues(comp, res)) uri := f.client.getEndpoint(fileServiceName, path, params) - extraHeaders = f.client.protectUserAgent(extraHeaders) headers := mergeHeaders(f.client.getStandardHeaders(), extraHeaders) return f.client.exec(verb, uri, headers, nil, f.auth) } // deletes the resource and returns the response -func (f FileServiceClient) deleteResource(path string, res resourceType) error { - resp, err := f.deleteResourceNoClose(path, res) +func (f FileServiceClient) deleteResource(path string, res resourceType, options *FileRequestOptions) error { + resp, err := f.deleteResourceNoClose(path, res, options) if err != nil { return err } @@ -270,12 +270,12 @@ func (f FileServiceClient) deleteResource(path string, res resourceType) error { } // deletes the resource and returns the response, doesn't close the response body -func (f FileServiceClient) deleteResourceNoClose(path string, res resourceType) (*storageResponse, error) { +func (f FileServiceClient) deleteResourceNoClose(path string, res resourceType, options *FileRequestOptions) (*storageResponse, error) { if err := f.checkForStorageEmulator(); err != nil { return nil, err } - values := getURLInitValues(compNone, res) + values := mergeParams(getURLInitValues(compNone, res), prepareOptions(options)) uri := f.client.getEndpoint(fileServiceName, path, values) return f.client.exec(http.MethodDelete, uri, f.client.getStandardHeaders(), nil, f.auth) } @@ -294,21 +294,13 @@ func mergeMDIntoExtraHeaders(metadata, extraHeaders map[string]string) map[strin return extraHeaders } -// merges extraHeaders into headers and returns headers -func mergeHeaders(headers, extraHeaders map[string]string) map[string]string { - for k, v := range extraHeaders { - headers[k] = v - } - return headers -} - // sets extra header data for the specified resource -func (f FileServiceClient) setResourceHeaders(path string, comp compType, res resourceType, extraHeaders map[string]string) (http.Header, error) { +func (f FileServiceClient) setResourceHeaders(path string, comp compType, res resourceType, extraHeaders map[string]string, options *FileRequestOptions) (http.Header, error) { if err := f.checkForStorageEmulator(); err != nil { return nil, err } - params := getURLInitValues(comp, res) + params := mergeParams(getURLInitValues(comp, res), prepareOptions(options)) uri := f.client.getEndpoint(fileServiceName, path, params) extraHeaders = f.client.protectUserAgent(extraHeaders) headers := mergeHeaders(f.client.getStandardHeaders(), extraHeaders) @@ -322,49 +314,6 @@ func (f FileServiceClient) setResourceHeaders(path string, comp compType, res re return resp.headers, checkRespCode(resp.statusCode, []int{http.StatusOK}) } -// gets metadata for the specified resource -func (f FileServiceClient) getMetadata(path string, res resourceType) (map[string]string, error) { - if err := f.checkForStorageEmulator(); err != nil { - return nil, err - } - - headers, err := f.getResourceHeaders(path, compMetadata, res, http.MethodGet) - if err != nil { - return nil, err - } - - return getMetadataFromHeaders(headers), nil -} - -// returns a map of custom metadata values from the specified HTTP header -func getMetadataFromHeaders(header http.Header) map[string]string { - metadata := make(map[string]string) - for k, v := range header { - // Can't trust CanonicalHeaderKey() to munge case - // reliably. "_" is allowed in identifiers: - // https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx - // https://msdn.microsoft.com/library/aa664670(VS.71).aspx - // http://tools.ietf.org/html/rfc7230#section-3.2 - // ...but "_" is considered invalid by - // CanonicalMIMEHeaderKey in - // https://golang.org/src/net/textproto/reader.go?s=14615:14659#L542 - // so k can be "X-Ms-Meta-Foo" or "x-ms-meta-foo_bar". - k = strings.ToLower(k) - if len(v) == 0 || !strings.HasPrefix(k, strings.ToLower(userDefinedMetadataHeaderPrefix)) { - continue - } - // metadata["foo"] = content of the last X-Ms-Meta-Foo header - k = k[len(userDefinedMetadataHeaderPrefix):] - metadata[k] = v[len(v)-1] - } - - if len(metadata) == 0 { - return nil - } - - return metadata -} - //checkForStorageEmulator determines if the client is setup for use with //Azure Storage Emulator, and returns a relevant error func (f FileServiceClient) checkForStorageEmulator() error { diff --git a/storage/leaseblob.go b/storage/leaseblob.go new file mode 100644 index 000000000000..415b740183b3 --- /dev/null +++ b/storage/leaseblob.go @@ -0,0 +1,187 @@ +package storage + +import ( + "errors" + "net/http" + "net/url" + "strconv" + "time" +) + +// lease constants. +const ( + leaseHeaderPrefix = "x-ms-lease-" + headerLeaseID = "x-ms-lease-id" + leaseAction = "x-ms-lease-action" + leaseBreakPeriod = "x-ms-lease-break-period" + leaseDuration = "x-ms-lease-duration" + leaseProposedID = "x-ms-proposed-lease-id" + leaseTime = "x-ms-lease-time" + + acquireLease = "acquire" + renewLease = "renew" + changeLease = "change" + releaseLease = "release" + breakLease = "break" +) + +// leasePut is common PUT code for the various acquire/release/break etc functions. +func (b *Blob) leaseCommonPut(headers map[string]string, expectedStatus int, options *LeaseOptions) (http.Header, error) { + params := url.Values{"comp": {"lease"}} + + 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 nil, err + } + defer readAndCloseBody(resp.body) + + if err := checkRespCode(resp.statusCode, []int{expectedStatus}); err != nil { + return nil, err + } + + return resp.headers, nil +} + +// LeaseOptions includes options for all operations regarding leasing blobs +type LeaseOptions struct { + Timeout uint + Origin string `header:"Origin"` + IfMatch string `header:"If-Match"` + IfNoneMatch string `header:"If-None-Match"` + IfModifiedSince *time.Time `header:"If-Modified-Since"` + IfUnmodifiedSince *time.Time `header:"If-Unmodified-Since"` + RequestID string `header:"x-ms-client-request-id"` +} + +// AcquireLease creates a lease for a blob +// returns leaseID acquired +// In API Versions starting on 2012-02-12, the minimum leaseTimeInSeconds is 15, the maximum +// non-infinite leaseTimeInSeconds is 60. To specify an infinite lease, provide the value -1. +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Lease-Blob +func (b *Blob) AcquireLease(leaseTimeInSeconds int, proposedLeaseID string, options *LeaseOptions) (returnedLeaseID string, err error) { + headers := b.Container.bsc.client.getStandardHeaders() + headers[leaseAction] = acquireLease + + if leaseTimeInSeconds == -1 { + // Do nothing, but don't trigger the following clauses. + } else if leaseTimeInSeconds > 60 || b.Container.bsc.client.apiVersion < "2012-02-12" { + leaseTimeInSeconds = 60 + } else if leaseTimeInSeconds < 15 { + leaseTimeInSeconds = 15 + } + + headers[leaseDuration] = strconv.Itoa(leaseTimeInSeconds) + + if proposedLeaseID != "" { + headers[leaseProposedID] = proposedLeaseID + } + + respHeaders, err := b.leaseCommonPut(headers, http.StatusCreated, options) + if err != nil { + return "", err + } + + returnedLeaseID = respHeaders.Get(http.CanonicalHeaderKey(headerLeaseID)) + + if returnedLeaseID != "" { + return returnedLeaseID, nil + } + + return "", errors.New("LeaseID not returned") +} + +// BreakLease breaks the lease for a blob +// Returns the timeout remaining in the lease in seconds +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Lease-Blob +func (b *Blob) BreakLease(options *LeaseOptions) (breakTimeout int, err error) { + headers := b.Container.bsc.client.getStandardHeaders() + headers[leaseAction] = breakLease + return b.breakLeaseCommon(headers, options) +} + +// BreakLeaseWithBreakPeriod breaks the lease for a blob +// breakPeriodInSeconds is used to determine how long until new lease can be created. +// Returns the timeout remaining in the lease in seconds +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Lease-Blob +func (b *Blob) BreakLeaseWithBreakPeriod(breakPeriodInSeconds int, options *LeaseOptions) (breakTimeout int, err error) { + headers := b.Container.bsc.client.getStandardHeaders() + headers[leaseAction] = breakLease + headers[leaseBreakPeriod] = strconv.Itoa(breakPeriodInSeconds) + return b.breakLeaseCommon(headers, options) +} + +// breakLeaseCommon is common code for both version of BreakLease (with and without break period) +func (b *Blob) breakLeaseCommon(headers map[string]string, options *LeaseOptions) (breakTimeout int, err error) { + + respHeaders, err := b.leaseCommonPut(headers, http.StatusAccepted, options) + if err != nil { + return 0, err + } + + breakTimeoutStr := respHeaders.Get(http.CanonicalHeaderKey(leaseTime)) + if breakTimeoutStr != "" { + breakTimeout, err = strconv.Atoi(breakTimeoutStr) + if err != nil { + return 0, err + } + } + + return breakTimeout, nil +} + +// ChangeLease changes a lease ID for a blob +// Returns the new LeaseID acquired +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Lease-Blob +func (b *Blob) ChangeLease(currentLeaseID string, proposedLeaseID string, options *LeaseOptions) (newLeaseID string, err error) { + headers := b.Container.bsc.client.getStandardHeaders() + headers[leaseAction] = changeLease + headers[headerLeaseID] = currentLeaseID + headers[leaseProposedID] = proposedLeaseID + + respHeaders, err := b.leaseCommonPut(headers, http.StatusOK, options) + if err != nil { + return "", err + } + + newLeaseID = respHeaders.Get(http.CanonicalHeaderKey(headerLeaseID)) + if newLeaseID != "" { + return newLeaseID, nil + } + + return "", errors.New("LeaseID not returned") +} + +// ReleaseLease releases the lease for a blob +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Lease-Blob +func (b *Blob) ReleaseLease(currentLeaseID string, options *LeaseOptions) error { + headers := b.Container.bsc.client.getStandardHeaders() + headers[leaseAction] = releaseLease + headers[headerLeaseID] = currentLeaseID + + _, err := b.leaseCommonPut(headers, http.StatusOK, options) + if err != nil { + return err + } + + return nil +} + +// RenewLease renews the lease for a blob as per https://msdn.microsoft.com/en-us/library/azure/ee691972.aspx +func (b *Blob) RenewLease(currentLeaseID string, options *LeaseOptions) error { + headers := b.Container.bsc.client.getStandardHeaders() + headers[leaseAction] = renewLease + headers[headerLeaseID] = currentLeaseID + + _, err := b.leaseCommonPut(headers, http.StatusOK, options) + if err != nil { + return err + } + + return nil +} diff --git a/storage/leaseblob_test.go b/storage/leaseblob_test.go new file mode 100644 index 000000000000..cd4528be750b --- /dev/null +++ b/storage/leaseblob_test.go @@ -0,0 +1,211 @@ +package storage + +import chk "gopkg.in/check.v1" + +type LeaseBlobSuite struct{} + +var _ = chk.Suite(&LeaseBlobSuite{}) + +func (s *LeaseBlobSuite) TestAcquireLeaseWithNoProposedLeaseID(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.putSingleBlockBlob([]byte("Hello!")), chk.IsNil) + + _, err := b.AcquireLease(30, "", nil) + c.Assert(err, chk.IsNil) +} + +func (s *LeaseBlobSuite) TestAcquireLeaseWithProposedLeaseID(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.putSingleBlockBlob([]byte("Hello!")), chk.IsNil) + + proposedLeaseID := "dfe6dde8-68d5-4910-9248-c97c61768fea" + leaseID, err := b.AcquireLease(30, proposedLeaseID, nil) + c.Assert(err, chk.IsNil) + c.Assert(leaseID, chk.Equals, proposedLeaseID) +} + +func (s *LeaseBlobSuite) TestAcquireLeaseWithBadProposedLeaseID(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.putSingleBlockBlob([]byte("Hello!")), chk.IsNil) + + proposedLeaseID := "badbadbad" + _, err := b.AcquireLease(30, proposedLeaseID, nil) + c.Assert(err, chk.NotNil) +} + +func (s *LeaseBlobSuite) TestAcquireInfiniteLease(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.putSingleBlockBlob([]byte("Hello!")), chk.IsNil) + + proposedLeaseID := "dfe6dde8-68d5-4910-9248-c97c61768fea" + _, err := b.AcquireLease(-1, proposedLeaseID, nil) + c.Assert(err, chk.IsNil) +} + +func (s *LeaseBlobSuite) TestRenewLeaseSuccessful(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.putSingleBlockBlob([]byte("Hello!")), chk.IsNil) + + proposedLeaseID := "dfe6dde8-68d5-4910-9248-c97c61768fea" + leaseID, err := b.AcquireLease(30, proposedLeaseID, nil) + c.Assert(err, chk.IsNil) + + err = b.RenewLease(leaseID, nil) + c.Assert(err, chk.IsNil) +} + +func (s *LeaseBlobSuite) TestRenewLeaseAgainstNoCurrentLease(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.putSingleBlockBlob([]byte("Hello!")), chk.IsNil) + + badLeaseID := "Golang rocks on Azure" + err := b.RenewLease(badLeaseID, nil) + c.Assert(err, chk.NotNil) +} + +func (s *LeaseBlobSuite) TestChangeLeaseSuccessful(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.putSingleBlockBlob([]byte("Hello!")), chk.IsNil) + proposedLeaseID := "dfe6dde8-68d5-4910-9248-c97c61768fea" + leaseID, err := b.AcquireLease(30, proposedLeaseID, nil) + c.Assert(err, chk.IsNil) + + newProposedLeaseID := "dfe6dde8-68d5-4910-9248-c97c61768fbb" + newLeaseID, err := b.ChangeLease(leaseID, newProposedLeaseID, nil) + c.Assert(err, chk.IsNil) + c.Assert(newLeaseID, chk.Equals, newProposedLeaseID) +} + +func (s *LeaseBlobSuite) TestChangeLeaseNotSuccessfulbadProposedLeaseID(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.putSingleBlockBlob([]byte("Hello!")), chk.IsNil) + proposedLeaseID := "dfe6dde8-68d5-4910-9248-c97c61768fea" + leaseID, err := b.AcquireLease(30, proposedLeaseID, nil) + c.Assert(err, chk.IsNil) + + newProposedLeaseID := "1f812371-a41d-49e6-b123-f4b542e" + _, err = b.ChangeLease(leaseID, newProposedLeaseID, nil) + c.Assert(err, chk.NotNil) +} + +func (s *LeaseBlobSuite) TestReleaseLeaseSuccessful(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.putSingleBlockBlob([]byte("Hello!")), chk.IsNil) + proposedLeaseID := "dfe6dde8-68d5-4910-9248-c97c61768fea" + leaseID, err := b.AcquireLease(30, proposedLeaseID, nil) + c.Assert(err, chk.IsNil) + + err = b.ReleaseLease(leaseID, nil) + c.Assert(err, chk.IsNil) +} + +func (s *LeaseBlobSuite) TestReleaseLeaseNotSuccessfulBadLeaseID(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.putSingleBlockBlob([]byte("Hello!")), chk.IsNil) + proposedLeaseID := "dfe6dde8-68d5-4910-9248-c97c61768fea" + _, err := b.AcquireLease(30, proposedLeaseID, nil) + c.Assert(err, chk.IsNil) + + err = b.ReleaseLease("badleaseid", nil) + c.Assert(err, chk.NotNil) +} + +func (s *LeaseBlobSuite) TestBreakLeaseSuccessful(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.putSingleBlockBlob([]byte("Hello!")), chk.IsNil) + + proposedLeaseID := "dfe6dde8-68d5-4910-9248-c97c61768fea" + _, err := b.AcquireLease(30, proposedLeaseID, nil) + c.Assert(err, chk.IsNil) + + _, err = b.BreakLease(nil) + c.Assert(err, chk.IsNil) +} diff --git a/storage/message.go b/storage/message.go new file mode 100644 index 000000000000..3ededcd421aa --- /dev/null +++ b/storage/message.go @@ -0,0 +1,153 @@ +package storage + +import ( + "encoding/xml" + "fmt" + "net/http" + "net/url" + "strconv" + "time" +) + +// Message represents an Azure message. +type Message struct { + Queue *Queue + Text string `xml:"MessageText"` + ID string `xml:"MessageId"` + Insertion TimeRFC1123 `xml:"InsertionTime"` + Expiration TimeRFC1123 `xml:"ExpirationTime"` + PopReceipt string `xml:"PopReceipt"` + NextVisible TimeRFC1123 `xml:"TimeNextVisible"` + DequeueCount int `xml:"DequeueCount"` +} + +func (m *Message) buildPath() string { + return fmt.Sprintf("%s/%s", m.Queue.buildPathMessages(), m.ID) +} + +// PutMessageOptions is the set of options can be specified for Put Messsage +// operation. A zero struct does not use any preferences for the request. +type PutMessageOptions struct { + Timeout uint + VisibilityTimeout int + MessageTTL int + RequestID string `header:"x-ms-client-request-id"` +} + +// Put operation adds a new message to the back of the message queue. +// +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Put-Message +func (m *Message) Put(options *PutMessageOptions) error { + query := url.Values{} + headers := m.Queue.qsc.client.getStandardHeaders() + + req := putMessageRequest{MessageText: m.Text} + body, nn, err := xmlMarshal(req) + if err != nil { + return err + } + headers["Content-Length"] = strconv.Itoa(nn) + + if options != nil { + if options.VisibilityTimeout != 0 { + query.Set("visibilitytimeout", strconv.Itoa(options.VisibilityTimeout)) + } + if options.MessageTTL != 0 { + query.Set("messagettl", strconv.Itoa(options.MessageTTL)) + } + query = addTimeout(query, options.Timeout) + headers = mergeHeaders(headers, headersFromStruct(*options)) + } + + uri := m.Queue.qsc.client.getEndpoint(queueServiceName, m.Queue.buildPathMessages(), query) + resp, err := m.Queue.qsc.client.exec(http.MethodPost, uri, headers, body, m.Queue.qsc.auth) + if err != nil { + return err + } + defer readAndCloseBody(resp.body) + + err = xmlUnmarshal(resp.body, m) + if err != nil { + return err + } + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// UpdateMessageOptions is the set of options can be specified for Update Messsage +// operation. A zero struct does not use any preferences for the request. +type UpdateMessageOptions struct { + Timeout uint + VisibilityTimeout int + RequestID string `header:"x-ms-client-request-id"` +} + +// Update operation updates the specified message. +// +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Update-Message +func (m *Message) Update(options *UpdateMessageOptions) error { + query := url.Values{} + if m.PopReceipt != "" { + query.Set("popreceipt", m.PopReceipt) + } + + headers := m.Queue.qsc.client.getStandardHeaders() + req := putMessageRequest{MessageText: m.Text} + body, nn, err := xmlMarshal(req) + if err != nil { + return err + } + headers["Content-Length"] = strconv.Itoa(nn) + + if options != nil { + if options.VisibilityTimeout != 0 { + query.Set("visibilitytimeout", strconv.Itoa(options.VisibilityTimeout)) + } + query = addTimeout(query, options.Timeout) + headers = mergeHeaders(headers, headersFromStruct(*options)) + } + uri := m.Queue.qsc.client.getEndpoint(queueServiceName, m.buildPath(), query) + + resp, err := m.Queue.qsc.client.exec(http.MethodPut, uri, headers, body, m.Queue.qsc.auth) + if err != nil { + return err + } + defer readAndCloseBody(resp.body) + + m.PopReceipt = resp.headers.Get("x-ms-popreceipt") + nextTimeStr := resp.headers.Get("x-ms-time-next-visible") + if nextTimeStr != "" { + nextTime, err := time.Parse(time.RFC1123, nextTimeStr) + if err != nil { + return err + } + m.NextVisible = TimeRFC1123(nextTime) + } + + return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) +} + +// Delete operation deletes the specified message. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179347.aspx +func (m *Message) Delete(options *QueueServiceOptions) error { + params := url.Values{"popreceipt": {m.PopReceipt}} + headers := m.Queue.qsc.client.getStandardHeaders() + + if options != nil { + params = addTimeout(params, options.Timeout) + headers = mergeHeaders(headers, headersFromStruct(*options)) + } + uri := m.Queue.qsc.client.getEndpoint(queueServiceName, m.buildPath(), params) + + resp, err := m.Queue.qsc.client.exec(http.MethodDelete, uri, headers, nil, m.Queue.qsc.auth) + if err != nil { + return err + } + readAndCloseBody(resp.body) + return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) +} + +type putMessageRequest struct { + XMLName xml.Name `xml:"QueueMessage"` + MessageText string `xml:"MessageText"` +} diff --git a/storage/message_test.go b/storage/message_test.go new file mode 100644 index 000000000000..ea3e675a0c6e --- /dev/null +++ b/storage/message_test.go @@ -0,0 +1,79 @@ +package storage + +import chk "gopkg.in/check.v1" + +type StorageMessageSuite struct{} + +var _ = chk.Suite(&StorageMessageSuite{}) + +func (s *StorageMessageSuite) Test_pathForMessage(c *chk.C) { + m := getQueueClient(c).GetQueueReference("q").GetMessageReference("m") + m.ID = "ID" + c.Assert(m.buildPath(), chk.Equals, "/q/messages/ID") +} + +func (s *StorageMessageSuite) TestDeleteMessages(c *chk.C) { + cli := getQueueClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + q := cli.GetQueueReference(queueName(c)) + c.Assert(q.Create(nil), chk.IsNil) + defer q.Delete(nil) + + m := q.GetMessageReference("message") + c.Assert(m.Put(nil), chk.IsNil) + + options := GetMessagesOptions{ + VisibilityTimeout: 1, + } + list, err := q.GetMessages(&options) + c.Assert(err, chk.IsNil) + c.Assert(list, chk.HasLen, 1) + + c.Assert(list[0].Delete(nil), chk.IsNil) +} + +func (s *StorageMessageSuite) TestPutMessage_Peek(c *chk.C) { + cli := getQueueClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + queue := cli.GetQueueReference(queueName(c)) + c.Assert(queue.Create(nil), chk.IsNil) + defer queue.Delete(nil) + + msg := queue.GetMessageReference(string(content(64 * 1024))) // exercise max length + c.Assert(msg.Put(nil), chk.IsNil) + + list, err := queue.PeekMessages(nil) + c.Assert(err, chk.IsNil) + c.Assert(len(list), chk.Equals, 1) + c.Assert(list[0].Text, chk.Equals, msg.Text) +} + +func (s *StorageMessageSuite) TestPutMessage_Peek_Update_Delete(c *chk.C) { + cli := getQueueClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + queue := cli.GetQueueReference(queueName(c)) + c.Assert(queue.Create(nil), chk.IsNil) + defer queue.Delete(nil) + + msg1 := queue.GetMessageReference(string(content(64 * 1024))) // exercise max length + msg2 := queue.GetMessageReference("and other message") + c.Assert(msg1.Put(nil), chk.IsNil) + c.Assert(msg2.Put(nil), chk.IsNil) + + list, err := queue.GetMessages(&GetMessagesOptions{NumOfMessages: 2, VisibilityTimeout: 2}) + c.Assert(err, chk.IsNil) + c.Assert(len(list), chk.Equals, 2) + c.Assert(list[0].Text, chk.Equals, msg1.Text) + c.Assert(list[1].Text, chk.Equals, msg2.Text) + + list[0].Text = "updated message" + c.Assert(list[0].Update(&UpdateMessageOptions{VisibilityTimeout: 2}), chk.IsNil) + + c.Assert(list[1].Delete(nil), chk.IsNil) +} diff --git a/storage/odata.go b/storage/odata.go new file mode 100644 index 000000000000..41d832e2be11 --- /dev/null +++ b/storage/odata.go @@ -0,0 +1,33 @@ +package storage + +// MetadataLevel determines if operations should return a paylod, +// and it level of detail. +type MetadataLevel string + +// This consts are meant to help with Odata supported operations +const ( + OdataTypeSuffix = "@odata.type" + + // Types + + OdataBinary = "Edm.Binary" + OdataDateTime = "Edm.DateTime" + OdataGUID = "Edm.Guid" + OdataInt64 = "Edm.Int64" + + // Query options + + OdataFilter = "$filter" + OdataOrderBy = "$orderby" + OdataTop = "$top" + OdataSkip = "$skip" + OdataCount = "$count" + OdataExpand = "$expand" + OdataSelect = "$select" + OdataSearch = "$search" + + EmptyPayload MetadataLevel = "" + NoMetadata MetadataLevel = "application/json;odata=nometadata" + MinimalMetadata MetadataLevel = "application/json;odata=minimalmetadata" + FullMetadata MetadataLevel = "application/json;odata=fullmetadata" +) diff --git a/storage/pageblob.go b/storage/pageblob.go new file mode 100644 index 000000000000..bc5b398d3ff8 --- /dev/null +++ b/storage/pageblob.go @@ -0,0 +1,189 @@ +package storage + +import ( + "encoding/xml" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "time" +) + +// GetPageRangesResponse contains the response fields from +// Get Page Ranges call. +// +// See https://msdn.microsoft.com/en-us/library/azure/ee691973.aspx +type GetPageRangesResponse struct { + XMLName xml.Name `xml:"PageList"` + PageList []PageRange `xml:"PageRange"` +} + +// PageRange contains information about a page of a page blob from +// Get Pages Range call. +// +// See https://msdn.microsoft.com/en-us/library/azure/ee691973.aspx +type PageRange struct { + Start int64 `xml:"Start"` + End int64 `xml:"End"` +} + +var ( + errBlobCopyAborted = errors.New("storage: blob copy is aborted") + errBlobCopyIDMismatch = errors.New("storage: blob copy id is a mismatch") +) + +// PutPageOptions includes the options for a put page operation +type PutPageOptions struct { + Timeout uint + LeaseID string `header:"x-ms-lease-id"` + IfSequenceNumberLessThanOrEqualTo *int `header:"x-ms-if-sequence-number-le"` + IfSequenceNumberLessThan *int `header:"x-ms-if-sequence-number-lt"` + IfSequenceNumberEqualTo *int `header:"x-ms-if-sequence-number-eq"` + 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"` +} + +// WriteRange writes a range of pages to a page blob. +// Ranges must be aligned with 512-byte boundaries and chunk must be of size +// multiplies by 512. +// +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Put-Page +func (b *Blob) WriteRange(blobRange BlobRange, bytes io.Reader, options *PutPageOptions) error { + if bytes == nil { + return errors.New("bytes cannot be nil") + } + return b.modifyRange(blobRange, bytes, options) +} + +// ClearRange clears the given range in a page blob. +// Ranges must be aligned with 512-byte boundaries and chunk must be of size +// multiplies by 512. +// +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Put-Page +func (b *Blob) ClearRange(blobRange BlobRange, options *PutPageOptions) error { + return b.modifyRange(blobRange, nil, options) +} + +func (b *Blob) modifyRange(blobRange BlobRange, bytes io.Reader, options *PutPageOptions) error { + if blobRange.End < blobRange.Start { + return errors.New("the value for rangeEnd must be greater than or equal to rangeStart") + } + if blobRange.Start%512 != 0 { + return errors.New("the value for rangeStart must be a modulus of 512") + } + if blobRange.End%512 != 511 { + return errors.New("the value for rangeEnd must be a modulus of 511") + } + + params := url.Values{"comp": {"page"}} + + // default to clear + write := "clear" + var cl uint64 + + // if bytes is not nil then this is an update operation + if bytes != nil { + write = "update" + cl = (blobRange.End - blobRange.Start) + 1 + } + + headers := b.Container.bsc.client.getStandardHeaders() + headers["x-ms-blob-type"] = string(BlobTypePage) + headers["x-ms-page-write"] = write + headers["x-ms-range"] = blobRange.String() + headers["Content-Length"] = fmt.Sprintf("%v", cl) + + 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, b.Container.bsc.auth) + if err != nil { + return err + } + readAndCloseBody(resp.body) + + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// GetPageRangesOptions includes the options for a get page ranges operation +type GetPageRangesOptions struct { + Timeout uint + Snapshot *time.Time + PreviousSnapshot *time.Time + Range *BlobRange + LeaseID string `header:"x-ms-lease-id"` + RequestID string `header:"x-ms-client-request-id"` +} + +// GetPageRanges returns the list of valid page ranges for a page blob. +// +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Get-Page-Ranges +func (b *Blob) GetPageRanges(options *GetPageRangesOptions) (GetPageRangesResponse, error) { + params := url.Values{"comp": {"pagelist"}} + headers := b.Container.bsc.client.getStandardHeaders() + + if options != nil { + params = addTimeout(params, options.Timeout) + params = addSnapshot(params, options.Snapshot) + if options.PreviousSnapshot != nil { + params.Add("prevsnapshot", timeRfc1123Formatted(*options.PreviousSnapshot)) + } + if options.Range != nil { + headers["Range"] = options.Range.String() + } + headers = mergeHeaders(headers, headersFromStruct(*options)) + } + uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), params) + + var out GetPageRangesResponse + resp, err := b.Container.bsc.client.exec(http.MethodGet, uri, headers, nil, b.Container.bsc.auth) + if err != nil { + return out, err + } + defer resp.body.Close() + + if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + return out, err + } + err = xmlUnmarshal(resp.body, &out) + return out, err +} + +// PutPageBlob initializes an empty page blob with specified name and maximum +// size in bytes (size must be aligned to a 512-byte boundary). A page blob must +// be created using this method before writing pages. +// +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Put-Blob +func (b *Blob) PutPageBlob(options *PutBlobOptions) error { + if b.Properties.ContentLength%512 != 0 { + return errors.New("Content length must be aligned to a 512-byte boundary") + } + + params := url.Values{} + headers := b.Container.bsc.client.getStandardHeaders() + headers["x-ms-blob-type"] = string(BlobTypePage) + headers["x-ms-blob-content-length"] = fmt.Sprintf("%v", b.Properties.ContentLength) + headers["x-ms-blob-sequence-number"] = fmt.Sprintf("%v", b.Properties.SequenceNumber) + 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}) +} diff --git a/storage/pageblob_test.go b/storage/pageblob_test.go new file mode 100644 index 000000000000..de009cfe06cb --- /dev/null +++ b/storage/pageblob_test.go @@ -0,0 +1,179 @@ +package storage + +import ( + "bytes" + "io/ioutil" + + chk "gopkg.in/check.v1" +) + +type PageBlobSuite struct{} + +var _ = chk.Suite(&PageBlobSuite{}) + +func (s *PageBlobSuite) TestPutPageBlob(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) + + size := int64(10 * 1024 * 1024) + b.Properties.ContentLength = size + c.Assert(b.PutPageBlob(nil), chk.IsNil) + + // Verify + err := b.GetProperties(nil) + c.Assert(err, chk.IsNil) + c.Assert(b.Properties.ContentLength, chk.Equals, size) + c.Assert(b.Properties.BlobType, chk.Equals, BlobTypePage) +} + +func (s *PageBlobSuite) TestPutPagesUpdate(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) + + size := int64(10 * 1024 * 1024) // larger than we'll use + b.Properties.ContentLength = size + c.Assert(b.PutPageBlob(nil), chk.IsNil) + + chunk1 := content(1024) + chunk2 := content(512) + + // Append chunks + blobRange := BlobRange{ + End: uint64(len(chunk1) - 1), + } + c.Assert(b.WriteRange(blobRange, bytes.NewReader(chunk1), nil), chk.IsNil) + blobRange.Start = uint64(len(chunk1)) + blobRange.End = uint64(len(chunk1) + len(chunk2) - 1) + c.Assert(b.WriteRange(blobRange, bytes.NewReader(chunk2), nil), chk.IsNil) + + // Verify contents + options := GetBlobRangeOptions{ + Range: &BlobRange{ + 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...)) + + // Overwrite first half of chunk1 + chunk0 := content(512) + blobRange.Start = 0 + blobRange.End = uint64(len(chunk0) - 1) + c.Assert(b.WriteRange(blobRange, bytes.NewReader(chunk0), nil), chk.IsNil) + + // Verify contents + 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(append(chunk0, chunk1[512:]...), chunk2...)) +} + +func (s *PageBlobSuite) TestPutPagesClear(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) + + size := int64(10 * 1024 * 1024) // larger than we'll use + b.Properties.ContentLength = size + c.Assert(b.PutPageBlob(nil), chk.IsNil) + + // Put 0-2047 + chunk := content(2048) + blobRange := BlobRange{ + End: 2047, + } + c.Assert(b.WriteRange(blobRange, bytes.NewReader(chunk), nil), chk.IsNil) + + // Clear 512-1023 + blobRange.Start = 512 + blobRange.End = 1023 + c.Assert(b.ClearRange(blobRange, nil), chk.IsNil) + + // Verify contents + options := GetBlobRangeOptions{ + Range: &BlobRange{ + Start: 0, + End: 2047, + }, + } + out, err := b.GetRange(&options) + c.Assert(err, chk.IsNil) + contents, err := ioutil.ReadAll(out) + c.Assert(err, chk.IsNil) + defer out.Close() + c.Assert(contents, chk.DeepEquals, append(append(chunk[:512], make([]byte, 512)...), chunk[1024:]...)) +} + +func (s *PageBlobSuite) TestGetPageRanges(c *chk.C) { + cli := getBlobClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + cnt := cli.GetContainerReference(containerName(c)) + c.Assert(cnt.Create(nil), chk.IsNil) + defer cnt.Delete(nil) + + size := int64(10 * 1024) // larger than we'll use + + // Get page ranges on empty blob + blob1 := cnt.GetBlobReference(blobName(c, "1")) + blob1.Properties.ContentLength = size + c.Assert(blob1.PutPageBlob(nil), chk.IsNil) + out, err := blob1.GetPageRanges(nil) + c.Assert(err, chk.IsNil) + c.Assert(len(out.PageList), chk.Equals, 0) + + // Get page ranges with just one range + blob2 := cnt.GetBlobReference(blobName(c, "2")) + blob2.Properties.ContentLength = size + c.Assert(blob2.PutPageBlob(nil), chk.IsNil) + blobRange := []BlobRange{ + {End: 511}, + {Start: 1024, End: 2047}, + } + c.Assert(blob2.WriteRange(blobRange[0], bytes.NewReader(content(512)), nil), chk.IsNil) + + out, err = blob2.GetPageRanges(nil) + c.Assert(err, chk.IsNil) + c.Assert(len(out.PageList), chk.Equals, 1) + expected := []PageRange{ + {End: 511}, + {Start: 1024, End: 2047}, + } + c.Assert(out.PageList[0], chk.Equals, expected[0]) + + // Get page ranges with just two range + blob3 := cnt.GetBlobReference(blobName(c, "3")) + blob3.Properties.ContentLength = size + c.Assert(blob3.PutPageBlob(nil), chk.IsNil) + for _, br := range blobRange { + c.Assert(blob3.WriteRange(br, bytes.NewReader(content(int(br.End-br.Start+1))), nil), chk.IsNil) + } + out, err = blob3.GetPageRanges(nil) + c.Assert(err, chk.IsNil) + c.Assert(len(out.PageList), chk.Equals, 2) + c.Assert(out.PageList, chk.DeepEquals, expected) +} diff --git a/storage/queue.go b/storage/queue.go index 4031410aebfc..c2c7f742c452 100644 --- a/storage/queue.go +++ b/storage/queue.go @@ -2,161 +2,139 @@ package storage import ( "encoding/xml" + "errors" "fmt" + "io" "net/http" "net/url" "strconv" - "strings" + "time" ) const ( // casing is per Golang's http.Header canonicalizing the header names. - approximateMessagesCountHeader = "X-Ms-Approximate-Messages-Count" - userDefinedMetadataHeaderPrefix = "X-Ms-Meta-" + approximateMessagesCountHeader = "X-Ms-Approximate-Messages-Count" ) -func pathForQueue(queue string) string { return fmt.Sprintf("/%s", queue) } -func pathForQueueMessages(queue string) string { return fmt.Sprintf("/%s/messages", queue) } -func pathForMessage(queue, name string) string { return fmt.Sprintf("/%s/messages/%s", queue, name) } +// QueueAccessPolicy represents each access policy in the queue ACL. +type QueueAccessPolicy struct { + ID string + StartTime time.Time + ExpiryTime time.Time + CanRead bool + CanAdd bool + CanUpdate bool + CanProcess bool +} -type putMessageRequest struct { - XMLName xml.Name `xml:"QueueMessage"` - MessageText string `xml:"MessageText"` +// QueuePermissions represents the queue ACLs. +type QueuePermissions struct { + AccessPolicies []QueueAccessPolicy } -// PutMessageParameters is the set of options can be specified for Put Messsage -// operation. A zero struct does not use any preferences for the request. -type PutMessageParameters struct { - VisibilityTimeout int - MessageTTL int +// SetQueuePermissionOptions includes options for a set queue permissions operation +type SetQueuePermissionOptions struct { + Timeout uint + RequestID string `header:"x-ms-client-request-id"` } -func (p PutMessageParameters) getParameters() url.Values { - out := url.Values{} - if p.VisibilityTimeout != 0 { - out.Set("visibilitytimeout", strconv.Itoa(p.VisibilityTimeout)) - } - if p.MessageTTL != 0 { - out.Set("messagettl", strconv.Itoa(p.MessageTTL)) - } - return out +// Queue represents an Azure queue. +type Queue struct { + qsc *QueueServiceClient + Name string + Metadata map[string]string + AproxMessageCount uint64 } -// GetMessagesParameters is the set of options can be specified for Get -// Messsages operation. A zero struct does not use any preferences for the -// request. -type GetMessagesParameters struct { - NumOfMessages int - VisibilityTimeout int +func (q *Queue) buildPath() string { + return fmt.Sprintf("/%s", q.Name) } -func (p GetMessagesParameters) getParameters() url.Values { - out := url.Values{} - if p.NumOfMessages != 0 { - out.Set("numofmessages", strconv.Itoa(p.NumOfMessages)) - } - if p.VisibilityTimeout != 0 { - out.Set("visibilitytimeout", strconv.Itoa(p.VisibilityTimeout)) - } - return out +func (q *Queue) buildPathMessages() string { + return fmt.Sprintf("%s/messages", q.buildPath()) } -// PeekMessagesParameters is the set of options can be specified for Peek -// Messsage operation. A zero struct does not use any preferences for the -// request. -type PeekMessagesParameters struct { - NumOfMessages int +// QueueServiceOptions includes options for some queue service operations +type QueueServiceOptions struct { + Timeout uint + RequestID string `header:"x-ms-client-request-id"` } -func (p PeekMessagesParameters) getParameters() url.Values { - out := url.Values{"peekonly": {"true"}} // Required for peek operation - if p.NumOfMessages != 0 { - out.Set("numofmessages", strconv.Itoa(p.NumOfMessages)) +// Create operation creates a queue under the given account. +// +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Create-Queue4 +func (q *Queue) Create(options *QueueServiceOptions) error { + params := url.Values{} + headers := q.qsc.client.getStandardHeaders() + headers = q.qsc.client.addMetadataToHeaders(headers, q.Metadata) + + if options != nil { + params = addTimeout(params, options.Timeout) + headers = mergeHeaders(headers, headersFromStruct(*options)) } - return out -} + uri := q.qsc.client.getEndpoint(queueServiceName, q.buildPath(), params) -// UpdateMessageParameters is the set of options can be specified for Update Messsage -// operation. A zero struct does not use any preferences for the request. -type UpdateMessageParameters struct { - PopReceipt string - VisibilityTimeout int + resp, err := q.qsc.client.exec(http.MethodPut, uri, headers, nil, q.qsc.auth) + if err != nil { + return err + } + readAndCloseBody(resp.body) + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) } -func (p UpdateMessageParameters) getParameters() url.Values { - out := url.Values{} - if p.PopReceipt != "" { - out.Set("popreceipt", p.PopReceipt) +// Delete operation permanently deletes the specified queue. +// +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Delete-Queue3 +func (q *Queue) Delete(options *QueueServiceOptions) error { + params := url.Values{} + headers := q.qsc.client.getStandardHeaders() + + if options != nil { + params = addTimeout(params, options.Timeout) + headers = mergeHeaders(headers, headersFromStruct(*options)) } - if p.VisibilityTimeout != 0 { - out.Set("visibilitytimeout", strconv.Itoa(p.VisibilityTimeout)) + uri := q.qsc.client.getEndpoint(queueServiceName, q.buildPath(), params) + resp, err := q.qsc.client.exec(http.MethodDelete, uri, headers, nil, q.qsc.auth) + if err != nil { + return err } - return out -} - -// GetMessagesResponse represents a response returned from Get Messages -// operation. -type GetMessagesResponse struct { - XMLName xml.Name `xml:"QueueMessagesList"` - QueueMessagesList []GetMessageResponse `xml:"QueueMessage"` -} - -// GetMessageResponse represents a QueueMessage object returned from Get -// Messages operation response. -type GetMessageResponse struct { - MessageID string `xml:"MessageId"` - InsertionTime string `xml:"InsertionTime"` - ExpirationTime string `xml:"ExpirationTime"` - PopReceipt string `xml:"PopReceipt"` - TimeNextVisible string `xml:"TimeNextVisible"` - DequeueCount int `xml:"DequeueCount"` - MessageText string `xml:"MessageText"` -} - -// PeekMessagesResponse represents a response returned from Get Messages -// operation. -type PeekMessagesResponse struct { - XMLName xml.Name `xml:"QueueMessagesList"` - QueueMessagesList []PeekMessageResponse `xml:"QueueMessage"` -} - -// PeekMessageResponse represents a QueueMessage object returned from Peek -// Messages operation response. -type PeekMessageResponse struct { - MessageID string `xml:"MessageId"` - InsertionTime string `xml:"InsertionTime"` - ExpirationTime string `xml:"ExpirationTime"` - DequeueCount int `xml:"DequeueCount"` - MessageText string `xml:"MessageText"` + readAndCloseBody(resp.body) + return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) } -// QueueMetadataResponse represents user defined metadata and queue -// properties on a specific queue. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179384.aspx -type QueueMetadataResponse struct { - ApproximateMessageCount int - UserDefinedMetadata map[string]string +// Exists returns true if a queue with given name exists. +func (q *Queue) Exists() (bool, error) { + uri := q.qsc.client.getEndpoint(queueServiceName, q.buildPath(), url.Values{"comp": {"metadata"}}) + resp, err := q.qsc.client.exec(http.MethodGet, uri, q.qsc.client.getStandardHeaders(), nil, q.qsc.auth) + if resp != nil { + defer readAndCloseBody(resp.body) + if resp.statusCode == http.StatusOK || resp.statusCode == http.StatusNotFound { + return resp.statusCode == http.StatusOK, nil + } + } + return false, err } // SetMetadata operation sets user-defined metadata on the specified queue. // Metadata is associated with the queue as name-value pairs. // -// See https://msdn.microsoft.com/en-us/library/azure/dd179348.aspx -func (c QueueServiceClient) SetMetadata(name string, metadata map[string]string) error { - uri := c.client.getEndpoint(queueServiceName, pathForQueue(name), url.Values{"comp": []string{"metadata"}}) - metadata = c.client.protectUserAgent(metadata) - headers := c.client.getStandardHeaders() - for k, v := range metadata { - headers[userDefinedMetadataHeaderPrefix+k] = v +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Set-Queue-Metadata +func (q *Queue) SetMetadata(options *QueueServiceOptions) error { + params := url.Values{"comp": {"metadata"}} + headers := q.qsc.client.getStandardHeaders() + headers = q.qsc.client.addMetadataToHeaders(headers, q.Metadata) + + if options != nil { + params = addTimeout(params, options.Timeout) + headers = mergeHeaders(headers, headersFromStruct(*options)) } + uri := q.qsc.client.getEndpoint(queueServiceName, q.buildPath(), params) - resp, err := c.client.exec(http.MethodPut, uri, headers, nil, c.auth) + resp, err := q.qsc.client.exec(http.MethodPut, uri, headers, nil, q.qsc.auth) if err != nil { return err } - defer readAndCloseBody(resp.body) - + readAndCloseBody(resp.body) return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) } @@ -164,176 +142,286 @@ func (c QueueServiceClient) SetMetadata(name string, metadata map[string]string) // properties on the specified queue. Metadata is associated with // the queue as name-values pairs. // -// See https://msdn.microsoft.com/en-us/library/azure/dd179384.aspx +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Set-Queue-Metadata // // Because the way Golang's http client (and http.Header in particular) // canonicalize header names, the returned metadata names would always // be all lower case. -func (c QueueServiceClient) GetMetadata(name string) (QueueMetadataResponse, error) { - qm := QueueMetadataResponse{} - qm.UserDefinedMetadata = make(map[string]string) - uri := c.client.getEndpoint(queueServiceName, pathForQueue(name), url.Values{"comp": []string{"metadata"}}) - headers := c.client.getStandardHeaders() - resp, err := c.client.exec(http.MethodGet, uri, headers, nil, c.auth) +func (q *Queue) GetMetadata(options *QueueServiceOptions) error { + params := url.Values{"comp": {"metadata"}} + headers := q.qsc.client.getStandardHeaders() + + if options != nil { + params = addTimeout(params, options.Timeout) + headers = mergeHeaders(headers, headersFromStruct(*options)) + } + uri := q.qsc.client.getEndpoint(queueServiceName, q.buildPath(), url.Values{"comp": {"metadata"}}) + + resp, err := q.qsc.client.exec(http.MethodGet, uri, headers, nil, q.qsc.auth) if err != nil { - return qm, err + return err } defer readAndCloseBody(resp.body) - for k, v := range resp.headers { - if len(v) != 1 { - return qm, fmt.Errorf("Unexpected number of values (%d) in response header '%s'", len(v), k) - } - - value := v[0] + if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + return err + } - if k == approximateMessagesCountHeader { - qm.ApproximateMessageCount, err = strconv.Atoi(value) - if err != nil { - return qm, fmt.Errorf("Unexpected value in response header '%s': '%s' ", k, value) - } - } else if strings.HasPrefix(k, userDefinedMetadataHeaderPrefix) { - name := strings.TrimPrefix(k, userDefinedMetadataHeaderPrefix) - qm.UserDefinedMetadata[strings.ToLower(name)] = value + aproxMessagesStr := resp.headers.Get(http.CanonicalHeaderKey(approximateMessagesCountHeader)) + if aproxMessagesStr != "" { + aproxMessages, err := strconv.ParseUint(aproxMessagesStr, 10, 64) + if err != nil { + return err } + q.AproxMessageCount = aproxMessages } - return qm, checkRespCode(resp.statusCode, []int{http.StatusOK}) + q.Metadata = getMetadataFromHeaders(resp.headers) + return nil } -// CreateQueue operation creates a queue under the given account. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179342.aspx -func (c QueueServiceClient) CreateQueue(name string) error { - uri := c.client.getEndpoint(queueServiceName, pathForQueue(name), url.Values{}) - headers := c.client.getStandardHeaders() - resp, err := c.client.exec(http.MethodPut, uri, headers, nil, c.auth) - if err != nil { - return err +// GetMessageReference returns a message object with the specified text. +func (q *Queue) GetMessageReference(text string) *Message { + return &Message{ + Queue: q, + Text: text, } - defer readAndCloseBody(resp.body) - return checkRespCode(resp.statusCode, []int{http.StatusCreated}) } -// DeleteQueue operation permanently deletes the specified queue. +// GetMessagesOptions is the set of options can be specified for Get +// Messsages operation. A zero struct does not use any preferences for the +// request. +type GetMessagesOptions struct { + Timeout uint + NumOfMessages int + VisibilityTimeout int + RequestID string `header:"x-ms-client-request-id"` +} + +type messages struct { + XMLName xml.Name `xml:"QueueMessagesList"` + Messages []Message `xml:"QueueMessage"` +} + +// GetMessages operation retrieves one or more messages from the front of the +// queue. // -// See https://msdn.microsoft.com/en-us/library/azure/dd179436.aspx -func (c QueueServiceClient) DeleteQueue(name string) error { - uri := c.client.getEndpoint(queueServiceName, pathForQueue(name), url.Values{}) - resp, err := c.client.exec(http.MethodDelete, uri, c.client.getStandardHeaders(), nil, c.auth) +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Get-Messages +func (q *Queue) GetMessages(options *GetMessagesOptions) ([]Message, error) { + query := url.Values{} + headers := q.qsc.client.getStandardHeaders() + + if options != nil { + if options.NumOfMessages != 0 { + query.Set("numofmessages", strconv.Itoa(options.NumOfMessages)) + } + if options.VisibilityTimeout != 0 { + query.Set("visibilitytimeout", strconv.Itoa(options.VisibilityTimeout)) + } + query = addTimeout(query, options.Timeout) + headers = mergeHeaders(headers, headersFromStruct(*options)) + } + uri := q.qsc.client.getEndpoint(queueServiceName, q.buildPathMessages(), query) + + resp, err := q.qsc.client.exec(http.MethodGet, uri, headers, nil, q.qsc.auth) if err != nil { - return err + return []Message{}, err } defer readAndCloseBody(resp.body) - return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) -} -// QueueExists returns true if a queue with given name exists. -func (c QueueServiceClient) QueueExists(name string) (bool, error) { - uri := c.client.getEndpoint(queueServiceName, pathForQueue(name), url.Values{"comp": {"metadata"}}) - resp, err := c.client.exec(http.MethodGet, uri, c.client.getStandardHeaders(), nil, c.auth) - if resp != nil && (resp.statusCode == http.StatusOK || resp.statusCode == http.StatusNotFound) { - return resp.statusCode == http.StatusOK, nil + var out messages + err = xmlUnmarshal(resp.body, &out) + if err != nil { + return []Message{}, err } + for i := range out.Messages { + out.Messages[i].Queue = q + } + return out.Messages, err +} - return false, err +// PeekMessagesOptions is the set of options can be specified for Peek +// Messsage operation. A zero struct does not use any preferences for the +// request. +type PeekMessagesOptions struct { + Timeout uint + NumOfMessages int + RequestID string `header:"x-ms-client-request-id"` } -// PutMessage operation adds a new message to the back of the message queue. +// PeekMessages retrieves one or more messages from the front of the queue, but +// does not alter the visibility of the message. // -// See https://msdn.microsoft.com/en-us/library/azure/dd179346.aspx -func (c QueueServiceClient) PutMessage(queue string, message string, params PutMessageParameters) error { - uri := c.client.getEndpoint(queueServiceName, pathForQueueMessages(queue), params.getParameters()) - req := putMessageRequest{MessageText: message} - body, nn, err := xmlMarshal(req) - if err != nil { - return err +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Peek-Messages +func (q *Queue) PeekMessages(options *PeekMessagesOptions) ([]Message, error) { + query := url.Values{"peekonly": {"true"}} // Required for peek operation + headers := q.qsc.client.getStandardHeaders() + + if options != nil { + if options.NumOfMessages != 0 { + query.Set("numofmessages", strconv.Itoa(options.NumOfMessages)) + } + query = addTimeout(query, options.Timeout) + headers = mergeHeaders(headers, headersFromStruct(*options)) } - headers := c.client.getStandardHeaders() - headers["Content-Length"] = strconv.Itoa(nn) - resp, err := c.client.exec(http.MethodPost, uri, headers, body, c.auth) + uri := q.qsc.client.getEndpoint(queueServiceName, q.buildPathMessages(), query) + + resp, err := q.qsc.client.exec(http.MethodGet, uri, headers, nil, q.qsc.auth) if err != nil { - return err + return []Message{}, err } defer readAndCloseBody(resp.body) - return checkRespCode(resp.statusCode, []int{http.StatusCreated}) + + var out messages + err = xmlUnmarshal(resp.body, &out) + if err != nil { + return []Message{}, err + } + for i := range out.Messages { + out.Messages[i].Queue = q + } + return out.Messages, err } // ClearMessages operation deletes all messages from the specified queue. // -// See https://msdn.microsoft.com/en-us/library/azure/dd179454.aspx -func (c QueueServiceClient) ClearMessages(queue string) error { - uri := c.client.getEndpoint(queueServiceName, pathForQueueMessages(queue), url.Values{}) - resp, err := c.client.exec(http.MethodDelete, uri, c.client.getStandardHeaders(), nil, c.auth) +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Clear-Messages +func (q *Queue) ClearMessages(options *QueueServiceOptions) error { + params := url.Values{} + headers := q.qsc.client.getStandardHeaders() + + if options != nil { + params = addTimeout(params, options.Timeout) + headers = mergeHeaders(headers, headersFromStruct(*options)) + } + uri := q.qsc.client.getEndpoint(queueServiceName, q.buildPathMessages(), params) + + resp, err := q.qsc.client.exec(http.MethodDelete, uri, headers, nil, q.qsc.auth) if err != nil { return err } - defer readAndCloseBody(resp.body) + readAndCloseBody(resp.body) return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) } -// GetMessages operation retrieves one or more messages from the front of the -// queue. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179474.aspx -func (c QueueServiceClient) GetMessages(queue string, params GetMessagesParameters) (GetMessagesResponse, error) { - var r GetMessagesResponse - uri := c.client.getEndpoint(queueServiceName, pathForQueueMessages(queue), params.getParameters()) - resp, err := c.client.exec(http.MethodGet, uri, c.client.getStandardHeaders(), nil, c.auth) +// SetPermissions sets up queue permissions +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/set-queue-acl +func (q *Queue) SetPermissions(permissions QueuePermissions, options *SetQueuePermissionOptions) error { + body, length, err := generateQueueACLpayload(permissions.AccessPolicies) if err != nil { - return r, err + return err } - defer resp.body.Close() - err = xmlUnmarshal(resp.body, &r) - return r, err -} -// PeekMessages retrieves one or more messages from the front of the queue, but -// does not alter the visibility of the message. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179472.aspx -func (c QueueServiceClient) PeekMessages(queue string, params PeekMessagesParameters) (PeekMessagesResponse, error) { - var r PeekMessagesResponse - uri := c.client.getEndpoint(queueServiceName, pathForQueueMessages(queue), params.getParameters()) - resp, err := c.client.exec(http.MethodGet, uri, c.client.getStandardHeaders(), nil, c.auth) - if err != nil { - return r, err + params := url.Values{ + "comp": {"acl"}, } - defer resp.body.Close() - err = xmlUnmarshal(resp.body, &r) - return r, err -} + headers := q.qsc.client.getStandardHeaders() + headers["Content-Length"] = strconv.Itoa(length) -// DeleteMessage operation deletes the specified message. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179347.aspx -func (c QueueServiceClient) DeleteMessage(queue, messageID, popReceipt string) error { - uri := c.client.getEndpoint(queueServiceName, pathForMessage(queue, messageID), url.Values{ - "popreceipt": {popReceipt}}) - resp, err := c.client.exec(http.MethodDelete, uri, c.client.getStandardHeaders(), nil, c.auth) + if options != nil { + params = addTimeout(params, options.Timeout) + headers = mergeHeaders(headers, headersFromStruct(*options)) + } + uri := q.qsc.client.getEndpoint(queueServiceName, q.buildPath(), params) + resp, err := q.qsc.client.exec(http.MethodPut, uri, headers, body, q.qsc.auth) if err != nil { return err } defer readAndCloseBody(resp.body) - return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) + + if err := checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil { + return errors.New("Unable to set permissions") + } + + return nil } -// UpdateMessage operation deletes the specified message. -// -// See https://msdn.microsoft.com/en-us/library/azure/hh452234.aspx -func (c QueueServiceClient) UpdateMessage(queue string, messageID string, message string, params UpdateMessageParameters) error { - uri := c.client.getEndpoint(queueServiceName, pathForMessage(queue, messageID), params.getParameters()) - req := putMessageRequest{MessageText: message} - body, nn, err := xmlMarshal(req) +func generateQueueACLpayload(policies []QueueAccessPolicy) (io.Reader, int, error) { + sil := SignedIdentifiers{ + SignedIdentifiers: []SignedIdentifier{}, + } + for _, qapd := range policies { + permission := qapd.generateQueuePermissions() + signedIdentifier := convertAccessPolicyToXMLStructs(qapd.ID, qapd.StartTime, qapd.ExpiryTime, permission) + sil.SignedIdentifiers = append(sil.SignedIdentifiers, signedIdentifier) + } + return xmlMarshal(sil) +} + +func (qapd *QueueAccessPolicy) generateQueuePermissions() (permissions string) { + // generate the permissions string (raup). + // still want the end user API to have bool flags. + permissions = "" + + if qapd.CanRead { + permissions += "r" + } + + if qapd.CanAdd { + permissions += "a" + } + + if qapd.CanUpdate { + permissions += "u" + } + + if qapd.CanProcess { + permissions += "p" + } + + return permissions +} + +// GetQueuePermissionOptions includes options for a get queue permissions operation +type GetQueuePermissionOptions struct { + Timeout uint + RequestID string `header:"x-ms-client-request-id"` +} + +// GetPermissions gets the queue permissions as per https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-queue-acl +// If timeout is 0 then it will not be passed to Azure +func (q *Queue) GetPermissions(options *GetQueuePermissionOptions) (*QueuePermissions, error) { + params := url.Values{ + "comp": {"acl"}, + } + headers := q.qsc.client.getStandardHeaders() + + if options != nil { + params = addTimeout(params, options.Timeout) + headers = mergeHeaders(headers, headersFromStruct(*options)) + } + uri := q.qsc.client.getEndpoint(queueServiceName, q.buildPath(), params) + resp, err := q.qsc.client.exec(http.MethodGet, uri, headers, nil, q.qsc.auth) if err != nil { - return err + return nil, err } - headers := c.client.getStandardHeaders() - headers["Content-Length"] = fmt.Sprintf("%d", nn) - resp, err := c.client.exec(http.MethodPut, uri, headers, body, c.auth) + defer resp.body.Close() + + var ap AccessPolicy + err = xmlUnmarshal(resp.body, &ap.SignedIdentifiersList) if err != nil { - return err + return nil, err } - defer readAndCloseBody(resp.body) - return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) + return buildQueueAccessPolicy(ap, &resp.headers), nil +} + +func buildQueueAccessPolicy(ap AccessPolicy, headers *http.Header) *QueuePermissions { + permissions := QueuePermissions{ + AccessPolicies: []QueueAccessPolicy{}, + } + + for _, policy := range ap.SignedIdentifiersList.SignedIdentifiers { + qapd := QueueAccessPolicy{ + ID: policy.ID, + StartTime: policy.AccessPolicy.StartTime, + ExpiryTime: policy.AccessPolicy.ExpiryTime, + } + qapd.CanRead = updatePermissions(policy.AccessPolicy.Permission, "r") + qapd.CanAdd = updatePermissions(policy.AccessPolicy.Permission, "a") + qapd.CanUpdate = updatePermissions(policy.AccessPolicy.Permission, "u") + qapd.CanProcess = updatePermissions(policy.AccessPolicy.Permission, "p") + + permissions.AccessPolicies = append(permissions.AccessPolicies, qapd) + } + return &permissions } diff --git a/storage/queue_test.go b/storage/queue_test.go index 45a8901d6beb..dbed7cacd726 100644 --- a/storage/queue_test.go +++ b/storage/queue_test.go @@ -10,133 +10,352 @@ type StorageQueueSuite struct{} var _ = chk.Suite(&StorageQueueSuite{}) -func getQueueClient(c *chk.C) QueueServiceClient { - return getBasicClient(c).GetQueueService() +func getQueueClient(c *chk.C) *QueueServiceClient { + cli := getBasicClient(c).GetQueueService() + return &cli } func (s *StorageQueueSuite) Test_pathForQueue(c *chk.C) { - c.Assert(pathForQueue("q"), chk.Equals, "/q") + c.Assert(getQueueClient(c). + GetQueueReference("q"). + buildPath(), chk.Equals, "/q") } func (s *StorageQueueSuite) Test_pathForQueueMessages(c *chk.C) { - c.Assert(pathForQueueMessages("q"), chk.Equals, "/q/messages") -} - -func (s *StorageQueueSuite) Test_pathForMessage(c *chk.C) { - c.Assert(pathForMessage("q", "m"), chk.Equals, "/q/messages/m") + c.Assert(getQueueClient(c). + GetQueueReference("q"). + buildPathMessages(), chk.Equals, "/q/messages") } func (s *StorageQueueSuite) TestCreateQueue_DeleteQueue(c *chk.C) { cli := getQueueClient(c) - name := randString(20) - c.Assert(cli.CreateQueue(name), chk.IsNil) - c.Assert(cli.DeleteQueue(name), chk.IsNil) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + q := cli.GetQueueReference(queueName(c)) + c.Assert(q.Create(nil), chk.IsNil) + c.Assert(q.Delete(nil), chk.IsNil) } func (s *StorageQueueSuite) Test_GetMetadata_GetApproximateCount(c *chk.C) { cli := getQueueClient(c) - name := randString(20) - c.Assert(cli.CreateQueue(name), chk.IsNil) - defer cli.DeleteQueue(name) + rec := cli.client.appendRecorder(c) + defer rec.Stop() - qm, err := cli.GetMetadata(name) + queue1 := cli.GetQueueReference(queueName(c, "1")) + c.Assert(queue1.Create(nil), chk.IsNil) + defer queue1.Delete(nil) + + err := queue1.GetMetadata(nil) c.Assert(err, chk.IsNil) - c.Assert(qm.ApproximateMessageCount, chk.Equals, 0) + c.Assert(queue1.AproxMessageCount, chk.Equals, uint64(0)) + queue2 := cli.GetQueueReference(queueName(c, "2")) + c.Assert(queue2.Create(nil), chk.IsNil) + defer queue2.Delete(nil) for ix := 0; ix < 3; ix++ { - err = cli.PutMessage(name, "foobar", PutMessageParameters{}) + msg := queue2.GetMessageReference("lolrofl") + err = msg.Put(nil) c.Assert(err, chk.IsNil) } time.Sleep(1 * time.Second) - qm, err = cli.GetMetadata(name) + err = queue2.GetMetadata(nil) c.Assert(err, chk.IsNil) - c.Assert(qm.ApproximateMessageCount, chk.Equals, 3) + c.Assert(queue2.AproxMessageCount, chk.Equals, uint64(3)) } func (s *StorageQueueSuite) Test_SetMetadataGetMetadata_Roundtrips(c *chk.C) { cli := getQueueClient(c) - name := randString(20) - c.Assert(cli.CreateQueue(name), chk.IsNil) - defer cli.DeleteQueue(name) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + queue1 := cli.GetQueueReference(queueName(c, "1")) + c.Assert(queue1.Create(nil), chk.IsNil) + defer queue1.Delete(nil) metadata := make(map[string]string) - metadata["Foo1"] = "bar1" - metadata["fooBaz"] = "bar" - err := cli.SetMetadata(name, metadata) + metadata["Lol1"] = "rofl1" + metadata["lolBaz"] = "rofl" + queue1.Metadata = metadata + err := queue1.SetMetadata(nil) c.Assert(err, chk.IsNil) - qm, err := cli.GetMetadata(name) + err = queue1.GetMetadata(nil) c.Assert(err, chk.IsNil) - c.Assert(qm.UserDefinedMetadata["foo1"], chk.Equals, "bar1") - c.Assert(qm.UserDefinedMetadata["foobaz"], chk.Equals, "bar") + c.Assert(queue1.Metadata["lol1"], chk.Equals, metadata["Lol1"]) + c.Assert(queue1.Metadata["lolbaz"], chk.Equals, metadata["lolBaz"]) } func (s *StorageQueueSuite) TestQueueExists(c *chk.C) { cli := getQueueClient(c) - ok, err := cli.QueueExists("nonexistent-queue") + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + queue1 := cli.GetQueueReference(queueName(c, "nonexistent")) + ok, err := queue1.Exists() c.Assert(err, chk.IsNil) c.Assert(ok, chk.Equals, false) - name := randString(20) - c.Assert(cli.CreateQueue(name), chk.IsNil) - defer cli.DeleteQueue(name) + queue2 := cli.GetQueueReference(queueName(c, "exisiting")) + c.Assert(queue2.Create(nil), chk.IsNil) + defer queue2.Delete(nil) - ok, err = cli.QueueExists(name) + ok, err = queue2.Exists() c.Assert(err, chk.IsNil) c.Assert(ok, chk.Equals, true) } -func (s *StorageQueueSuite) TestPutMessage_PeekMessage_UpdateMessage_DeleteMessage(c *chk.C) { - q := randString(20) +func (s *StorageQueueSuite) TestGetMessages(c *chk.C) { cli := getQueueClient(c) - c.Assert(cli.CreateQueue(q), chk.IsNil) - defer cli.DeleteQueue(q) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + queue := cli.GetQueueReference(queueName(c)) + c.Assert(queue.Create(nil), chk.IsNil) + defer queue.Delete(nil) + + msg := queue.GetMessageReference("message") + n := 4 + for i := 0; i < n; i++ { + c.Assert(msg.Put(nil), chk.IsNil) + } - msg := randString(64 * 1024) // exercise max length - c.Assert(cli.PutMessage(q, msg, PutMessageParameters{}), chk.IsNil) - r, err := cli.PeekMessages(q, PeekMessagesParameters{}) + list, err := queue.GetMessages(&GetMessagesOptions{NumOfMessages: n}) c.Assert(err, chk.IsNil) - c.Assert(len(r.QueueMessagesList), chk.Equals, 1) - c.Assert(r.QueueMessagesList[0].MessageText, chk.Equals, msg) + c.Assert(len(list), chk.Equals, n) +} - gr, gerr := cli.GetMessages(q, GetMessagesParameters{NumOfMessages: 1, VisibilityTimeout: 2}) - c.Assert(gerr, chk.IsNil) +func (s *StorageQueueSuite) TestDeleteMessages(c *chk.C) { + cli := getQueueClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + queue := cli.GetQueueReference(queueName(c)) + c.Assert(queue.Create(nil), chk.IsNil) + defer queue.Delete(nil) - updatedMsg := "Test Message" - c.Assert(cli.UpdateMessage(q, r.QueueMessagesList[0].MessageID, updatedMsg, - UpdateMessageParameters{PopReceipt: gr.QueueMessagesList[0].PopReceipt, VisibilityTimeout: 2}), chk.IsNil) - r, err = cli.PeekMessages(q, PeekMessagesParameters{}) + msg := queue.GetMessageReference("message") + c.Assert(msg.Put(nil), chk.IsNil) + list, err := queue.GetMessages(&GetMessagesOptions{VisibilityTimeout: 1}) c.Assert(err, chk.IsNil) - c.Assert(len(r.QueueMessagesList), chk.Equals, 0) + c.Assert(len(list), chk.Equals, 1) + msg = &(list[0]) + c.Assert(msg.Delete(nil), chk.IsNil) } -func (s *StorageQueueSuite) TestGetMessages(c *chk.C) { - q := randString(20) +func queueName(c *chk.C, extras ...string) string { + // 63 is the max len for shares + return nameGenerator(63, "queue-", alphanum, c, extras) +} + +func (s *StorageQueueSuite) Test_SetPermissionsAllTrueNoTimeout(c *chk.C) { cli := getQueueClient(c) - c.Assert(cli.CreateQueue(q), chk.IsNil) - defer cli.DeleteQueue(q) + rec := cli.client.appendRecorder(c) + defer rec.Stop() - n := 4 - for i := 0; i < n; i++ { - c.Assert(cli.PutMessage(q, randString(10), PutMessageParameters{}), chk.IsNil) + queue1 := cli.GetQueueReference(queueName(c, "1")) + c.Assert(queue1.Create(nil), chk.IsNil) + defer queue1.Delete(nil) + + perms := QueuePermissions{} + qapd := QueueAccessPolicy{ + ID: "GolangRocksOnAzure", + StartTime: time.Date(2050, time.December, 20, 21, 55, 0, 0, time.FixedZone("GMT", -6)), + ExpiryTime: time.Date(2051, time.December, 20, 21, 55, 0, 0, time.FixedZone("GMT", -6)), + CanRead: true, + CanAdd: true, + CanUpdate: true, + CanProcess: true, + } + perms.AccessPolicies = append(perms.AccessPolicies, qapd) + err := queue1.SetPermissions(perms, nil) + c.Assert(err, chk.IsNil) +} + +func (s *StorageQueueSuite) Test_SetPermissionsAllTrueWithTimeout(c *chk.C) { + cli := getQueueClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + queue1 := cli.GetQueueReference(queueName(c, "1")) + c.Assert(queue1.Create(nil), chk.IsNil) + defer queue1.Delete(nil) + + perms := QueuePermissions{} + qapd := QueueAccessPolicy{ + ID: "GolangRocksOnAzure", + StartTime: time.Date(2050, time.December, 20, 21, 55, 0, 0, time.FixedZone("GMT", -6)), + ExpiryTime: time.Date(2051, time.December, 20, 21, 55, 0, 0, time.FixedZone("GMT", -6)), + CanRead: true, + CanAdd: true, + CanUpdate: true, + CanProcess: true, } + perms.AccessPolicies = append(perms.AccessPolicies, qapd) - r, err := cli.GetMessages(q, GetMessagesParameters{NumOfMessages: n}) + options := SetQueuePermissionOptions{Timeout: 30} + err := queue1.SetPermissions(perms, &options) c.Assert(err, chk.IsNil) - c.Assert(len(r.QueueMessagesList), chk.Equals, n) + } -func (s *StorageQueueSuite) TestDeleteMessages(c *chk.C) { - q := randString(20) +func (s *StorageQueueSuite) Test_SetPermissionsAlternateTrueNoTimeout(c *chk.C) { + cli := getQueueClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + queue1 := cli.GetQueueReference(queueName(c, "1")) + c.Assert(queue1.Create(nil), chk.IsNil) + defer queue1.Delete(nil) + + perms := QueuePermissions{} + qapd := QueueAccessPolicy{ + ID: "GolangRocksOnAzure", + StartTime: time.Date(2050, time.December, 20, 21, 55, 0, 0, time.FixedZone("GMT", -6)), + ExpiryTime: time.Date(2051, time.December, 20, 21, 55, 0, 0, time.FixedZone("GMT", -6)), + CanRead: true, + CanAdd: false, + CanUpdate: true, + CanProcess: false, + } + perms.AccessPolicies = append(perms.AccessPolicies, qapd) + err := queue1.SetPermissions(perms, nil) + c.Assert(err, chk.IsNil) +} + +func (s *StorageQueueSuite) Test_SetPermissionsAlternateTrueWithTimeout(c *chk.C) { + cli := getQueueClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + queue1 := cli.GetQueueReference(queueName(c, "1")) + c.Assert(queue1.Create(nil), chk.IsNil) + defer queue1.Delete(nil) + + perms := QueuePermissions{} + qapd := QueueAccessPolicy{ + ID: "GolangRocksOnAzure", + StartTime: time.Date(2050, time.December, 20, 21, 55, 0, 0, time.FixedZone("GMT", -6)), + ExpiryTime: time.Date(2051, time.December, 20, 21, 55, 0, 0, time.FixedZone("GMT", -6)), + CanRead: true, + CanAdd: false, + CanUpdate: true, + CanProcess: false, + } + perms.AccessPolicies = append(perms.AccessPolicies, qapd) + + options := SetQueuePermissionOptions{Timeout: 30} + err := queue1.SetPermissions(perms, &options) + c.Assert(err, chk.IsNil) +} + +func (s *StorageQueueSuite) Test_GetPermissionsAllTrueNoTimeout(c *chk.C) { + cli := getQueueClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + queue1 := cli.GetQueueReference(queueName(c, "1")) + c.Assert(queue1.Create(nil), chk.IsNil) + defer queue1.Delete(nil) + + perms := QueuePermissions{} + qapd := QueueAccessPolicy{ + ID: "GolangRocksOnAzure", + StartTime: time.Date(2050, time.December, 20, 21, 55, 0, 0, time.UTC), + ExpiryTime: time.Date(2051, time.December, 20, 21, 55, 0, 0, time.UTC), + CanRead: true, + CanAdd: true, + CanUpdate: true, + CanProcess: true, + } + perms.AccessPolicies = append(perms.AccessPolicies, qapd) + err := queue1.SetPermissions(perms, nil) + c.Assert(err, chk.IsNil) + + returnedPerms, err := queue1.GetPermissions(nil) + c.Assert(err, chk.IsNil) + c.Assert(returnedPerms.AccessPolicies, chk.HasLen, 1) + + c.Assert(returnedPerms.AccessPolicies[0].CanRead, chk.Equals, true) + c.Assert(returnedPerms.AccessPolicies[0].CanAdd, chk.Equals, true) + c.Assert(returnedPerms.AccessPolicies[0].CanUpdate, chk.Equals, true) + c.Assert(returnedPerms.AccessPolicies[0].CanProcess, chk.Equals, true) + c.Assert(returnedPerms.AccessPolicies[0].ID, chk.Equals, "GolangRocksOnAzure") + c.Assert(returnedPerms.AccessPolicies[0].StartTime, chk.Equals, qapd.StartTime) + c.Assert(returnedPerms.AccessPolicies[0].ExpiryTime, chk.Equals, qapd.ExpiryTime) +} + +func (s *StorageQueueSuite) Test_GetPermissionsAllTrueWithTimeout(c *chk.C) { + cli := getQueueClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + queue1 := cli.GetQueueReference(queueName(c, "1")) + c.Assert(queue1.Create(nil), chk.IsNil) + defer queue1.Delete(nil) + + perms := QueuePermissions{} + qapd := QueueAccessPolicy{ + ID: "GolangRocksOnAzure", + StartTime: time.Date(2050, time.December, 20, 21, 55, 0, 0, time.UTC), + ExpiryTime: time.Date(2051, time.December, 20, 21, 55, 0, 0, time.UTC), + CanRead: true, + CanAdd: true, + CanUpdate: true, + CanProcess: true, + } + perms.AccessPolicies = append(perms.AccessPolicies, qapd) + err := queue1.SetPermissions(perms, nil) + c.Assert(err, chk.IsNil) + + options := GetQueuePermissionOptions{Timeout: 30} + returnedPerms, err := queue1.GetPermissions(&options) + c.Assert(err, chk.IsNil) + c.Assert(returnedPerms.AccessPolicies, chk.HasLen, 1) + + c.Assert(returnedPerms.AccessPolicies[0].CanRead, chk.Equals, true) + c.Assert(returnedPerms.AccessPolicies[0].CanAdd, chk.Equals, true) + c.Assert(returnedPerms.AccessPolicies[0].CanUpdate, chk.Equals, true) + c.Assert(returnedPerms.AccessPolicies[0].CanProcess, chk.Equals, true) + c.Assert(returnedPerms.AccessPolicies[0].ID, chk.Equals, "GolangRocksOnAzure") + c.Assert(returnedPerms.AccessPolicies[0].StartTime, chk.Equals, qapd.StartTime) + c.Assert(returnedPerms.AccessPolicies[0].ExpiryTime, chk.Equals, qapd.ExpiryTime) + +} + +func (s *StorageQueueSuite) Test_GetPermissionsAlternateTrueNoTimeout(c *chk.C) { cli := getQueueClient(c) - c.Assert(cli.CreateQueue(q), chk.IsNil) - defer cli.DeleteQueue(q) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + queue1 := cli.GetQueueReference(queueName(c, "1")) + c.Assert(queue1.Create(nil), chk.IsNil) + defer queue1.Delete(nil) - c.Assert(cli.PutMessage(q, "message", PutMessageParameters{}), chk.IsNil) - r, err := cli.GetMessages(q, GetMessagesParameters{VisibilityTimeout: 1}) + perms := QueuePermissions{} + qapd := QueueAccessPolicy{ + ID: "GolangRocksOnAzure", + StartTime: time.Date(2050, time.December, 20, 21, 55, 0, 0, time.UTC), + ExpiryTime: time.Date(2051, time.December, 20, 21, 55, 0, 0, time.UTC), + CanRead: true, + CanAdd: false, + CanUpdate: true, + CanProcess: false, + } + perms.AccessPolicies = append(perms.AccessPolicies, qapd) + err := queue1.SetPermissions(perms, nil) + c.Assert(err, chk.IsNil) + + returnedPerms, err := queue1.GetPermissions(nil) c.Assert(err, chk.IsNil) - c.Assert(len(r.QueueMessagesList), chk.Equals, 1) - m := r.QueueMessagesList[0] - c.Assert(cli.DeleteMessage(q, m.MessageID, m.PopReceipt), chk.IsNil) + c.Assert(returnedPerms.AccessPolicies, chk.HasLen, 1) + + c.Assert(returnedPerms.AccessPolicies[0].CanRead, chk.Equals, true) + c.Assert(returnedPerms.AccessPolicies[0].CanAdd, chk.Equals, false) + c.Assert(returnedPerms.AccessPolicies[0].CanUpdate, chk.Equals, true) + c.Assert(returnedPerms.AccessPolicies[0].CanProcess, chk.Equals, false) + c.Assert(returnedPerms.AccessPolicies[0].ID, chk.Equals, "GolangRocksOnAzure") + c.Assert(returnedPerms.AccessPolicies[0].StartTime, chk.Equals, qapd.StartTime) + c.Assert(returnedPerms.AccessPolicies[0].ExpiryTime, chk.Equals, qapd.ExpiryTime) } diff --git a/storage/queueserviceclient.go b/storage/queueserviceclient.go index c26141339b73..19b44941c8cc 100644 --- a/storage/queueserviceclient.go +++ b/storage/queueserviceclient.go @@ -9,12 +9,20 @@ type QueueServiceClient struct { // GetServiceProperties gets the properties of your storage account's queue service. // See: https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-queue-service-properties -func (c *QueueServiceClient) GetServiceProperties() (*ServiceProperties, error) { - return c.client.getServiceProperties(queueServiceName, c.auth) +func (q *QueueServiceClient) GetServiceProperties() (*ServiceProperties, error) { + return q.client.getServiceProperties(queueServiceName, q.auth) } // SetServiceProperties sets the properties of your storage account's queue service. // See: https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/set-queue-service-properties -func (c *QueueServiceClient) SetServiceProperties(props ServiceProperties) error { - return c.client.setServiceProperties(props, queueServiceName, c.auth) +func (q *QueueServiceClient) SetServiceProperties(props ServiceProperties) error { + return q.client.setServiceProperties(props, queueServiceName, q.auth) +} + +// GetQueueReference returns a Container object for the specified queue name. +func (q *QueueServiceClient) GetQueueReference(name string) *Queue { + return &Queue{ + qsc: q, + Name: name, + } } diff --git a/storage/recordings/AppendBlobSuite/TestPutAppendBlob.yaml b/storage/recordings/AppendBlobSuite/TestPutAppendBlob.yaml new file mode 100644 index 000000000000..3faa753baf95 --- /dev/null +++ b/storage/recordings/AppendBlobSuite/TestPutAppendBlob.yaml @@ -0,0 +1,144 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:07kEhjVvT7scsIriqXm/Vq5FSf755FYhiTtdysdqTio= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:02 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-33appendblobsuitetestputappe?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:02 GMT + Etag: + - '"0x8D47C73B88484CF"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:02 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2776-0001-00d8-135c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:3Mfqo3fM8Si0nVB13L6crv4CkD2lhffQX7/qljGXg3w= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - AppendBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:02 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-33appendblobsuitetestputappe/blob/33appendblobsuitetestputappendblob + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:02 GMT + Etag: + - '"0x8D47C73B8774760"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:02 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac278f-0001-00d8-285c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:sZtDp+RCsUdXbCUjS7B5JdziEMO6gBUflCDIEA0QgGc= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:02 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-33appendblobsuitetestputappe/blob/33appendblobsuitetestputappendblob + method: HEAD + response: + body: "" + headers: + Accept-Ranges: + - bytes + Content-Length: + - "0" + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:02 GMT + Etag: + - '"0x8D47C73B8774760"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:02 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Committed-Block-Count: + - "0" + X-Ms-Blob-Type: + - AppendBlob + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac279a-0001-00d8-335c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:U4DxWrvscz7sFHwg2NJxbljiq3lk6BsB02gg+M28Lj4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:02 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-33appendblobsuitetestputappe?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:02 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac27ab-0001-00d8-435c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/AppendBlobSuite/TestPutAppendBlobAppendBlocks.yaml b/storage/recordings/AppendBlobSuite/TestPutAppendBlobAppendBlocks.yaml new file mode 100644 index 000000000000..49db118f9aab --- /dev/null +++ b/storage/recordings/AppendBlobSuite/TestPutAppendBlobAppendBlocks.yaml @@ -0,0 +1,338 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:XlOsbAOAYkekh490YtBgTbNrrWsSV3GbrAJiQd+QJG0= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:02 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-45appendblobsuitetestputappe?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:02 GMT + Etag: + - '"0x8D47C73B8A4BCAB"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:02 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac27b9-0001-00d8-4f5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:v2W4RsHq6pPfq9rgnND/I2PpRwBfa3mPBKzrYdwiL0Y= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - AppendBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:02 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-45appendblobsuitetestputappe/blob/45appendblobsuitetestputappendblobappendblocks + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:02 GMT + Etag: + - '"0x8D47C73B897A67A"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:02 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac27d9-0001-00d8-695c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit + volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:0aT4sgI1ivi5dNTZsCpLGxICHzbjQZh+CPKG2bVo7NA= + Content-Length: + - "1024" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - AppendBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:02 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-45appendblobsuitetestputappe/blob/45appendblobsuitetestputappendblobappendblocks?comp=appendblock + method: PUT + response: + body: "" + headers: + Content-Md5: + - 0rZVY1m4cHz874drfCSd/w== + Date: + - Wed, 05 Apr 2017 22:33:02 GMT + Etag: + - '"0x8D47C73B89ED3B6"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:02 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Append-Offset: + - "0" + X-Ms-Blob-Committed-Block-Count: + - "1" + X-Ms-Request-Id: + - 5eac27ea-0001-00d8-795c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:SIjwjmSWo1QiqvcC1hyw5KzusuuHhmTTLZuPSZUKjbY= + Range: + - bytes=0-1023 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:02 GMT + X-Ms-Range-Get-Content-Md5: + - "false" + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-45appendblobsuitetestputappe/blob/45appendblobsuitetestputappendblobappendblocks + method: GET + response: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit + volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + headers: + Accept-Ranges: + - bytes + Content-Length: + - "1024" + Content-Range: + - bytes 0-1023/1024 + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:02 GMT + Etag: + - '"0x8D47C73B89ED3B6"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:02 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Committed-Block-Count: + - "1" + X-Ms-Blob-Type: + - AppendBlob + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac2802-0001-00d8-0e5c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 206 Partial Content + code: 206 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:GGYuVRViEJhQ1gIT5RIQ4n+pYAnpmg1dXYgNdEINaNY= + Content-Length: + - "512" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - AppendBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:03 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-45appendblobsuitetestputappe/blob/45appendblobsuitetestputappendblobappendblocks?comp=appendblock + method: PUT + response: + body: "" + headers: + Content-Md5: + - 2Xr7q2sERdQmQ41hZ7sPvQ== + Date: + - Wed, 05 Apr 2017 22:33:02 GMT + Etag: + - '"0x8D47C73B8AE66E0"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:02 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Append-Offset: + - "1024" + X-Ms-Blob-Committed-Block-Count: + - "2" + X-Ms-Request-Id: + - 5eac2817-0001-00d8-225c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:/91TcnQGQMpMpGIbP8e+TNBF3z4x/Tik2sLquji9KX4= + Range: + - bytes=0-1535 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:03 GMT + X-Ms-Range-Get-Content-Md5: + - "false" + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-45appendblobsuitetestputappe/blob/45appendblobsuitetestputappendblobappendblocks + method: GET + response: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit + volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio.Lorem ipsum + dolor sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac + headers: + Accept-Ranges: + - bytes + Content-Length: + - "1536" + Content-Range: + - bytes 0-1535/1536 + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:02 GMT + Etag: + - '"0x8D47C73B8AE66E0"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:02 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Committed-Block-Count: + - "2" + X-Ms-Blob-Type: + - AppendBlob + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac2831-0001-00d8-3a5c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 206 Partial Content + code: 206 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:ISwxNOU6AKWxzk5pFfVwnZBYhZ6jfp8kizMWhyw6LLI= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:03 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-45appendblobsuitetestputappe?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:02 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2845-0001-00d8-4b5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/AuthorizationSuite/Test_allSharedKeys.yaml b/storage/recordings/AuthorizationSuite/Test_allSharedKeys.yaml new file mode 100644 index 000000000000..dd55116aa379 --- /dev/null +++ b/storage/recordings/AuthorizationSuite/Test_allSharedKeys.yaml @@ -0,0 +1,294 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:It7tOGp8rbzY+Q3pcOJdvZT6cwlJ82Hb+48q08dbHHc= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:03 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-137authorizationsuitetestall?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:02 GMT + Etag: + - '"0x8D47C73B8DA7C1C"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:03 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2853-0001-00d8-565c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:bBV/4NZR7DQezTxKv3Zw0fRbiZgL0gWwDSRbaJDPJo8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:03 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-137authorizationsuitetestall?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:02 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2862-0001-00d8-635c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: | + {"TableName":"table137authorizationsuitetestal"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:E4tcp+kirxlirJfl+WwfJ2q0EVQlLcgUspVij6QdEB8= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:03 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table137authorizationsuitetestal') + Date: + - Wed, 05 Apr 2017 22:33:03 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table137authorizationsuitetestal') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33a89a-0002-0064-575c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:62/72ceV3DJX5JiAKHkL1PpXMVHdkq309m1Eqlz3KiY= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:03 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table137authorizationsuitetestal%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:03 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33a8c0-0002-0064-7a5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:O/bbN0MM9/Ru2OYB2h0Kslgi63e8BnkfKLszBMKrC7Q= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:03 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-237authorizationsuitetestall?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:03 GMT + Etag: + - '"0x8D47C73B91F325D"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:03 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac291d-0001-00d8-095c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:cpQe7x1zi5dpaviFgn3tevZ72NMk5Nlt9dRANTcHNqQ= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:03 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-237authorizationsuitetestall?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:03 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2933-0001-00d8-1a5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: | + {"TableName":"table237authorizationsuitetestal"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKeyLite golangrocksonazure:PVhNyKcfn69NyeQcrmT8irFE17bOEiRmKrdQoEVfWzc= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:03 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table237authorizationsuitetestal') + Date: + - Wed, 05 Apr 2017 22:33:03 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table237authorizationsuitetestal') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33a8f0-0002-0064-285c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKeyLite golangrocksonazure:ffkeY+Rpp44wFaJUOHOScSSYkEoQ1YiHMLJu4Eg7uuA= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:03 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table237authorizationsuitetestal%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:03 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33a8f8-0002-0064-2f5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/BlobSASURISuite/TestBlobSASURICorrectness.yaml b/storage/recordings/BlobSASURISuite/TestBlobSASURICorrectness.yaml new file mode 100644 index 000000000000..716df90053cb --- /dev/null +++ b/storage/recordings/BlobSASURISuite/TestBlobSASURICorrectness.yaml @@ -0,0 +1,142 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:+YWsX3g2o7AtOnIS6KSvAoruvRLu6V81yAMbqPjXwUY= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:08 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-41blobsasurisuitetestblobsas?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:07 GMT + Etag: + - '"0x8D47C73BBEA9011"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:08 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac30df-0001-00d8-375c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phase + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:bkiDi+JwoJlXJnhMHH9mquD+oqtZhrg30gFxjA7rG9g= + Content-Length: + - "100" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:08 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-41blobsasurisuitetestblobsas/Lorem/Lorem-._~:%3F%23%5B%5D@%21$&%27%28%29%2A,;+=%20Lorem + method: PUT + response: + body: "" + headers: + Content-Md5: + - Bcz94Jycda959ev/eJWOhw== + Date: + - Wed, 05 Apr 2017 22:33:07 GMT + Etag: + - '"0x8D47C73BBDD2F2F"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:08 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac30f8-0001-00d8-4d5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: {} + url: https://golangrocksonazure.blob.core.windows.net/cnt-41blobsasurisuitetestblobsas/Lorem/Lorem-._~:%3F%23%5B%5D@%21$&%27%28%29%2A,;+=%20Lorem?se=2050-12-20T22%3A55%3A06Z&sig=TB9D2vV6JfVyxR2YTJUDMG76D9x0Jr8kpX%2FpwUuX0cY%3D&sp=r&spr=https%2Chttp&sr=b&sv=2016-05-31 + method: GET + response: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phase + headers: + Accept-Ranges: + - bytes + Content-Length: + - "100" + Content-Md5: + - Bcz94Jycda959ev/eJWOhw== + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:07 GMT + Etag: + - '"0x8D47C73BBDD2F2F"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:08 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac3110-0001-00d8-625c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:KDYpZYiijlG0fVsAkJEl4GtAR95p6E3PI9yS5tuIOOA= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:08 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-41blobsasurisuitetestblobsas?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:07 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3134-0001-00d8-055c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/BlockBlobSuite/TestCreateBlockBlob.yaml b/storage/recordings/BlockBlobSuite/TestCreateBlockBlob.yaml new file mode 100644 index 000000000000..4be8f256f573 --- /dev/null +++ b/storage/recordings/BlockBlobSuite/TestCreateBlockBlob.yaml @@ -0,0 +1,136 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:x+VXNUjNKEejGIM602hv8O35Q7v/pHRYYYqU0LSNlDQ= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:08 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-34blockblobsuitetestcreatebl?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:07 GMT + Etag: + - '"0x8D47C73BC08CBC4"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:08 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3164-0001-00d8-355c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:tjkT936bV3Lzb4HhpmHoZFCcvKlCwIAQbsBwN5Rs2Rs= + Content-Length: + - "0" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:08 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-34blockblobsuitetestcreatebl/blob/34blockblobsuitetestcreateblockblob + method: PUT + response: + body: "" + headers: + Content-Md5: + - 1B2M2Y8AsgTpgAmY7PhCfg== + Date: + - Wed, 05 Apr 2017 22:33:07 GMT + Etag: + - '"0x8D47C73BBFB6B06"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:08 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3184-0001-00d8-4f5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Sb6Ag91qTlpNB5pYGznRFrytSnUIYARWkgYAwj+CzA0= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:08 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-34blockblobsuitetestcreatebl/blob/34blockblobsuitetestcreateblockblob?blocklisttype=all&comp=blocklist + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x42\x6C\x6F\x63\x6B\x4C\x69\x73\x74\x3E\x3C\x43\x6F\x6D\x6D\x69\x74\x74\x65\x64\x42\x6C\x6F\x63\x6B\x73\x20\x2F\x3E\x3C\x55\x6E\x63\x6F\x6D\x6D\x69\x74\x74\x65\x64\x42\x6C\x6F\x63\x6B\x73\x20\x2F\x3E\x3C\x2F\x42\x6C\x6F\x63\x6B\x4C\x69\x73\x74\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:08 GMT + Etag: + - '"0x8D47C73BBFB6B06"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:08 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Content-Length: + - "0" + X-Ms-Request-Id: + - 5eac3193-0001-00d8-5e5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:qyPqO+vOaCElQ5K1+WP7BtqK3HNjRceS4qrSVwKxMFQ= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:08 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-34blockblobsuitetestcreatebl?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:08 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac31a6-0001-00d8-6e5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/BlockBlobSuite/TestCreateBlockBlobFromReader.yaml b/storage/recordings/BlockBlobSuite/TestCreateBlockBlobFromReader.yaml new file mode 100644 index 000000000000..cf9daabfdced --- /dev/null +++ b/storage/recordings/BlockBlobSuite/TestCreateBlockBlobFromReader.yaml @@ -0,0 +1,370 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:730+mIga/KMHk4QPUO6FbTmkaJrA7Z/MTDlWi2IRPxI= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:08 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-44blockblobsuitetestcreatebl?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:08 GMT + Etag: + - '"0x8D47C73BC277CBB"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:08 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac31b3-0001-00d8-795c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit + volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Lx2zPw0dwCDRdQi3/0gEW6w6oP8pptoS+aoXZp5/a8M= + Content-Length: + - "8888" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:08 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-44blockblobsuitetestcreatebl/blob/44blockblobsuitetestcreateblockblobfromreader + method: PUT + response: + body: "" + headers: + Content-Md5: + - Ck/NLXf/Ku+Vjw/wgLi74w== + Date: + - Wed, 05 Apr 2017 22:33:08 GMT + Etag: + - '"0x8D47C73BC1A9162"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:08 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac31be-0001-00d8-035c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:mYd/dUqJysyX2L5RnKOFHtPFveZIggZwCTb9tSyOA1g= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:08 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-44blockblobsuitetestcreatebl/blob/44blockblobsuitetestcreateblockblobfromreader + method: GET + response: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit + volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas + headers: + Accept-Ranges: + - bytes + Content-Length: + - "8888" + Content-Md5: + - Ck/NLXf/Ku+Vjw/wgLi74w== + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:08 GMT + Etag: + - '"0x8D47C73BC1A9162"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:08 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac31d1-0001-00d8-145c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:0whOCVaVlGqgIY+Q7FU//MR+ASLDo0cgV9DumYxGoqw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:08 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-44blockblobsuitetestcreatebl?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:08 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac31dd-0001-00d8-1d5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/BlockBlobSuite/TestCreateBlockBlobFromReaderWithShortData.yaml b/storage/recordings/BlockBlobSuite/TestCreateBlockBlobFromReaderWithShortData.yaml new file mode 100644 index 000000000000..f489fc777540 --- /dev/null +++ b/storage/recordings/BlockBlobSuite/TestCreateBlockBlobFromReaderWithShortData.yaml @@ -0,0 +1,93 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:1TtdjJhpJlArfKwTbLMJjrQzqcLMFUqxSpffDPAOBaE= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:08 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-57blockblobsuitetestcreatebl?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:08 GMT + Etag: + - '"0x8D47C73BC4829DB"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:08 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac31eb-0001-00d8-295c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Vuqlh8mtRnkNRB6+f/x1MCbBiKz1j7HB3sNn3IrgD8c= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:08 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-57blockblobsuitetestcreatebl/blob/57blockblobsuitetestcreateblockblobfromreaderwithshortdata + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x72\x72\x6F\x72\x3E\x3C\x43\x6F\x64\x65\x3E\x42\x6C\x6F\x62\x4E\x6F\x74\x46\x6F\x75\x6E\x64\x3C\x2F\x43\x6F\x64\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x3E\x54\x68\x65\x20\x73\x70\x65\x63\x69\x66\x69\x65\x64\x20\x62\x6C\x6F\x62\x20\x64\x6F\x65\x73\x20\x6E\x6F\x74\x20\x65\x78\x69\x73\x74\x2E\n\x52\x65\x71\x75\x65\x73\x74\x49\x64\x3A\x35\x65\x61\x63\x33\x32\x30\x61\x2D\x30\x30\x30\x31\x2D\x30\x30\x64\x38\x2D\x34\x32\x35\x63\x2D\x61\x65\x61\x35\x36\x38\x30\x30\x30\x30\x30\x30\n\x54\x69\x6D\x65\x3A\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x30\x38\x2E\x38\x35\x36\x32\x31\x34\x38\x5A\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x45\x72\x72\x6F\x72\x3E" + headers: + Content-Length: + - "215" + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:08 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac320a-0001-00d8-425c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The specified blob does not exist. + code: 404 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:PejiDBm5jfJpYo7WGgf1+EcIZFilJYvELPy6P6eVdA0= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:09 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-57blockblobsuitetestcreatebl?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:08 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac322b-0001-00d8-605c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/BlockBlobSuite/TestGetBlockList_PutBlockList.yaml b/storage/recordings/BlockBlobSuite/TestGetBlockList_PutBlockList.yaml new file mode 100644 index 000000000000..1ad9e470a720 --- /dev/null +++ b/storage/recordings/BlockBlobSuite/TestGetBlockList_PutBlockList.yaml @@ -0,0 +1,264 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:aj+Uds0qvE3hUpIBsA9+sk3QwrOqp59CLefMHeFO92o= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:09 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-44blockblobsuitetestgetblock?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:08 GMT + Etag: + - '"0x8D47C73BC6022E3"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:08 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3269-0001-00d8-175c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit + volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:dxUYQ6SDd/fNf7vkMpqfdVp1eQMwZDpwI5BcPv+va5Q= + Content-Length: + - "1024" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:09 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-44blockblobsuitetestgetblock/blob/44blockblobsuitetestgetblocklistputblocklist?blockid=bG9s&comp=block + method: PUT + response: + body: "" + headers: + Content-Md5: + - 0rZVY1m4cHz874drfCSd/w== + Date: + - Wed, 05 Apr 2017 22:33:08 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3284-0001-00d8-2e5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:JTwOCcwn/PDtRwn6socX3NusF0ojW+i80awtICTxAXc= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:09 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-44blockblobsuitetestgetblock/blob/44blockblobsuitetestgetblocklistputblocklist?blocklisttype=committed&comp=blocklist + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x42\x6C\x6F\x63\x6B\x4C\x69\x73\x74\x3E\x3C\x43\x6F\x6D\x6D\x69\x74\x74\x65\x64\x42\x6C\x6F\x63\x6B\x73\x20\x2F\x3E\x3C\x2F\x42\x6C\x6F\x63\x6B\x4C\x69\x73\x74\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:08 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac328e-0001-00d8-385c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:IuorNNFXzmFGmJJNuWYiswJXBsrh9gttfo6vhSDZO8o= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:09 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-44blockblobsuitetestgetblock/blob/44blockblobsuitetestgetblocklistputblocklist?blocklisttype=uncommitted&comp=blocklist + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x42\x6C\x6F\x63\x6B\x4C\x69\x73\x74\x3E\x3C\x55\x6E\x63\x6F\x6D\x6D\x69\x74\x74\x65\x64\x42\x6C\x6F\x63\x6B\x73\x3E\x3C\x42\x6C\x6F\x63\x6B\x3E\x3C\x4E\x61\x6D\x65\x3E\x62\x47\x39\x73\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x53\x69\x7A\x65\x3E\x31\x30\x32\x34\x3C\x2F\x53\x69\x7A\x65\x3E\x3C\x2F\x42\x6C\x6F\x63\x6B\x3E\x3C\x2F\x55\x6E\x63\x6F\x6D\x6D\x69\x74\x74\x65\x64\x42\x6C\x6F\x63\x6B\x73\x3E\x3C\x2F\x42\x6C\x6F\x63\x6B\x4C\x69\x73\x74\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:08 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac32a3-0001-00d8-455c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: bG9s + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:EkuqEYQQ/ZVy58Z62ceUQC/mgG/lzyVIGXzydeTmU7k= + Content-Length: + - "92" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:09 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-44blockblobsuitetestgetblock/blob/44blockblobsuitetestgetblocklistputblocklist?comp=blocklist + method: PUT + response: + body: "" + headers: + Content-Md5: + - LXMsw7piGMWWhhOuwh7iGA== + Date: + - Wed, 05 Apr 2017 22:33:08 GMT + Etag: + - '"0x8D47C73BC69D11A"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:09 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac32bf-0001-00d8-5f5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Xjf10Nk1LO2UzWfBqG1WpnzYSJFVkX9+doJ/vhbcaYo= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:09 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-44blockblobsuitetestgetblock/blob/44blockblobsuitetestgetblocklistputblocklist?blocklisttype=all&comp=blocklist + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x42\x6C\x6F\x63\x6B\x4C\x69\x73\x74\x3E\x3C\x43\x6F\x6D\x6D\x69\x74\x74\x65\x64\x42\x6C\x6F\x63\x6B\x73\x3E\x3C\x42\x6C\x6F\x63\x6B\x3E\x3C\x4E\x61\x6D\x65\x3E\x62\x47\x39\x73\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x53\x69\x7A\x65\x3E\x31\x30\x32\x34\x3C\x2F\x53\x69\x7A\x65\x3E\x3C\x2F\x42\x6C\x6F\x63\x6B\x3E\x3C\x2F\x43\x6F\x6D\x6D\x69\x74\x74\x65\x64\x42\x6C\x6F\x63\x6B\x73\x3E\x3C\x55\x6E\x63\x6F\x6D\x6D\x69\x74\x74\x65\x64\x42\x6C\x6F\x63\x6B\x73\x20\x2F\x3E\x3C\x2F\x42\x6C\x6F\x63\x6B\x4C\x69\x73\x74\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:08 GMT + Etag: + - '"0x8D47C73BC69D11A"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:09 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Content-Length: + - "1024" + X-Ms-Request-Id: + - 5eac32d0-0001-00d8-6e5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:YS0nPKn0l1ZbTskvpoMLUaL4Wq5GsBnTGuKUz+dkr2c= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:09 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-44blockblobsuitetestgetblock/blob/44blockblobsuitetestgetblocklistputblocklist + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:08 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac32e6-0001-00d8-7f5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:HrVonHjT2jBzGGU4vLEzHoZeP0dcwAl4bAci47evbz0= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:09 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-44blockblobsuitetestgetblock?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:08 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac32f1-0001-00d8-095c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/BlockBlobSuite/TestPutBlock.yaml b/storage/recordings/BlockBlobSuite/TestPutBlock.yaml new file mode 100644 index 000000000000..6be0f3baa5c7 --- /dev/null +++ b/storage/recordings/BlockBlobSuite/TestPutBlock.yaml @@ -0,0 +1,107 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:bpdAuttAqjy3ANr825mL4OjUB/tUFHjm+pqIuO6uSNY= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:09 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-27blockblobsuitetestputblock?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:08 GMT + Etag: + - '"0x8D47C73BC9B88A8"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:09 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac32fa-0001-00d8-115c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit + volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:h9cEbgrw3hbdEvQCNLpJXDFDvz2XKAQV+iYpYeayxeY= + Content-Length: + - "1024" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:09 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-27blockblobsuitetestputblock/blob/27blockblobsuitetestputblock?blockid=bG9s&comp=block + method: PUT + response: + body: "" + headers: + Content-Md5: + - 0rZVY1m4cHz874drfCSd/w== + Date: + - Wed, 05 Apr 2017 22:33:08 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3307-0001-00d8-1b5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:2Q5qLq26mnuT/e38b11ulL/1/c5WJQ1l2K9ZwBWABvo= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:09 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-27blockblobsuitetestputblock?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:09 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac330e-0001-00d8-225c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/BlockBlobSuite/TestPutEmptyBlockBlob.yaml b/storage/recordings/BlockBlobSuite/TestPutEmptyBlockBlob.yaml new file mode 100644 index 000000000000..0faaff474a6c --- /dev/null +++ b/storage/recordings/BlockBlobSuite/TestPutEmptyBlockBlob.yaml @@ -0,0 +1,148 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:1Um6Np2laSFA2/9LIlnoxelOxi4O9oJaHD41uoiVez4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:09 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-36blockblobsuitetestputempty?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:09 GMT + Etag: + - '"0x8D47C73BCB2700C"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:09 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3320-0001-00d8-315c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:7YKkIUEe8HtX5oz19KMHsVcL/+k4eEsennYTBqsqEAA= + Content-Length: + - "6" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:09 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-36blockblobsuitetestputempty/blob/36blockblobsuitetestputemptyblockblob + method: PUT + response: + body: "" + headers: + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Date: + - Wed, 05 Apr 2017 22:33:09 GMT + Etag: + - '"0x8D47C73BCA5371A"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:09 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac333b-0001-00d8-495c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:SrgBc7FWmZSezaK/S+zeijAEg1RxJgR1/v0m2PhZZRI= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:09 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-36blockblobsuitetestputempty/blob/36blockblobsuitetestputemptyblockblob + method: HEAD + response: + body: "" + headers: + Accept-Ranges: + - bytes + Content-Length: + - "6" + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:09 GMT + Etag: + - '"0x8D47C73BCA5371A"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:09 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac3348-0001-00d8-535c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:FhILYilbCYtRaiblbXOc7kzLf2GBVHO/XjHRTsIwQ9c= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:09 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-36blockblobsuitetestputempty?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:09 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3355-0001-00d8-5e5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/ContainerSuite/TestContainerExists.yaml b/storage/recordings/ContainerSuite/TestContainerExists.yaml new file mode 100644 index 000000000000..f7358110232b --- /dev/null +++ b/storage/recordings/ContainerSuite/TestContainerExists.yaml @@ -0,0 +1,124 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:VbziVYphAJqdy58Mc5VB/ZwP22GjGaMkYlM9EAzbJDU= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:09 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-134containersuitetestcontain?restype=container + method: HEAD + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:09 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3379-0001-00d8-795c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The specified container does not exist. + code: 404 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:b481+dpQtmF7zoLWaIyVqsS30qf0W7NxQ1D4YEmP6Hg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:09 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-234containersuitetestcontain?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:09 GMT + Etag: + - '"0x8D47C73BCEB8B7E"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:09 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3385-0001-00d8-015c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:gkUCXmBlCQyJTY01AOOYOogKVRqijKyuTK54DDvwclg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-234containersuitetestcontain?restype=container + method: HEAD + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:09 GMT + Etag: + - '"0x8D47C73BCEB8B7E"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:09 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac3393-0001-00d8-0c5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:DLx/9U7PIOMKL+VWL8QTTXsdwzD78NKk/qETwMQs4oE= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-234containersuitetestcontain?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:09 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac339f-0001-00d8-145c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/ContainerSuite/TestCreateContainerDeleteContainer.yaml b/storage/recordings/ContainerSuite/TestCreateContainerDeleteContainer.yaml new file mode 100644 index 000000000000..93f11c06d92b --- /dev/null +++ b/storage/recordings/ContainerSuite/TestCreateContainerDeleteContainer.yaml @@ -0,0 +1,62 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:cyK/FWc/oK0SSk7fSCTrjJF7xstQSlEM08Bvcx8hYn4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-49containersuitetestcreateco?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:09 GMT + Etag: + - '"0x8D47C73BD016163"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:10 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac33aa-0001-00d8-1f5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:KZt3lfXe2+Zp+No79CJmsn9xg0nccDDbg1Fogv8kmb4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-49containersuitetestcreateco?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:09 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac33b7-0001-00d8-295c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/ContainerSuite/TestCreateContainerIfExists.yaml b/storage/recordings/ContainerSuite/TestCreateContainerIfExists.yaml new file mode 100644 index 000000000000..dbdacca77dd7 --- /dev/null +++ b/storage/recordings/ContainerSuite/TestCreateContainerIfExists.yaml @@ -0,0 +1,35 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:a+2QseFVOPlou96cdy3rOHCa7II4R8vL3pjti9m2OVE= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-42containersuitetestcreateco?restype=container + method: PUT + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x72\x72\x6F\x72\x3E\x3C\x43\x6F\x64\x65\x3E\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x41\x6C\x72\x65\x61\x64\x79\x45\x78\x69\x73\x74\x73\x3C\x2F\x43\x6F\x64\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x3E\x54\x68\x65\x20\x73\x70\x65\x63\x69\x66\x69\x65\x64\x20\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x20\x61\x6C\x72\x65\x61\x64\x79\x20\x65\x78\x69\x73\x74\x73\x2E\n\x52\x65\x71\x75\x65\x73\x74\x49\x64\x3A\x35\x65\x61\x63\x33\x33\x64\x63\x2D\x30\x30\x30\x31\x2D\x30\x30\x64\x38\x2D\x34\x61\x35\x63\x2D\x61\x65\x61\x35\x36\x38\x30\x30\x30\x30\x30\x30\n\x54\x69\x6D\x65\x3A\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x31\x30\x2E\x31\x37\x30\x31\x31\x34\x38\x5A\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x45\x72\x72\x6F\x72\x3E" + headers: + Content-Length: + - "230" + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:09 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac33dc-0001-00d8-4a5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 409 The specified container already exists. + code: 409 diff --git a/storage/recordings/ContainerSuite/TestCreateContainerIfNotExists.yaml b/storage/recordings/ContainerSuite/TestCreateContainerIfNotExists.yaml new file mode 100644 index 000000000000..91855c66c17f --- /dev/null +++ b/storage/recordings/ContainerSuite/TestCreateContainerIfNotExists.yaml @@ -0,0 +1,62 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:qMhk61Z/Xk4NhMaGcfY0qYwOewJ36ufAfaZGthAj2a4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-45containersuitetestcreateco?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:09 GMT + Etag: + - '"0x8D47C73BD285114"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:10 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3406-0001-00d8-6f5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:NbaeGrXLyCIF4v8NwIqzMtRnNmEW17CNndCLthWc9ac= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-45containersuitetestcreateco?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:09 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac341c-0001-00d8-805c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/ContainerSuite/TestDeleteContainerIfExists.yaml b/storage/recordings/ContainerSuite/TestDeleteContainerIfExists.yaml new file mode 100644 index 000000000000..5345eac782ff --- /dev/null +++ b/storage/recordings/ContainerSuite/TestDeleteContainerIfExists.yaml @@ -0,0 +1,120 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Xox9cA8T0hKJnhVSFRSvSqwvB4mJ7NshRZPJpAYkeNc= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-142containersuitetestdeletec?restype=container + method: HEAD + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:09 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3428-0001-00d8-0c5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The specified container does not exist. + code: 404 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:zhJcPqeMLyyR2o5YKzXFL8LNOaB3oAqcnULfbziIWy8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-142containersuitetestdeletec?restype=container + method: DELETE + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x72\x72\x6F\x72\x3E\x3C\x43\x6F\x64\x65\x3E\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x4E\x6F\x74\x46\x6F\x75\x6E\x64\x3C\x2F\x43\x6F\x64\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x3E\x54\x68\x65\x20\x73\x70\x65\x63\x69\x66\x69\x65\x64\x20\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x20\x64\x6F\x65\x73\x20\x6E\x6F\x74\x20\x65\x78\x69\x73\x74\x2E\n\x52\x65\x71\x75\x65\x73\x74\x49\x64\x3A\x35\x65\x61\x63\x33\x34\x33\x63\x2D\x30\x30\x30\x31\x2D\x30\x30\x64\x38\x2D\x31\x62\x35\x63\x2D\x61\x65\x61\x35\x36\x38\x30\x30\x30\x30\x30\x30\n\x54\x69\x6D\x65\x3A\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x31\x30\x2E\x34\x33\x38\x33\x30\x30\x30\x5A\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x45\x72\x72\x6F\x72\x3E" + headers: + Content-Length: + - "225" + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:09 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac343c-0001-00d8-1b5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The specified container does not exist. + code: 404 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:V5nP9+hg+jbiudZEQ0Vix5YaSIMA2g0IICjBYroPIrI= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-242containersuitetestdeletec?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:10 GMT + Etag: + - '"0x8D47C73BD492548"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:10 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac344a-0001-00d8-255c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:B+mRH3dKvKnCnmMYCtu+slW/GemSdspZQ0P41tbCGpo= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-242containersuitetestdeletec?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:10 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3459-0001-00d8-305c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/ContainerSuite/TestListBlobsPagination.yaml b/storage/recordings/ContainerSuite/TestListBlobsPagination.yaml new file mode 100644 index 000000000000..e587e6aecc16 --- /dev/null +++ b/storage/recordings/ContainerSuite/TestListBlobsPagination.yaml @@ -0,0 +1,344 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:rm0Di9T4afhrHvyjaBfjq8sTYQfxg1T0ip9tV6bbmk0= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-38containersuitetestlistblob?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:10 GMT + Etag: + - '"0x8D47C73BD5CD7CF"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:10 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3467-0001-00d8-395c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello, world! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:vk3KgO7KgiMYzvjvPJLBnl2B/SR3HL3vu29X6JotMgE= + Content-Length: + - "13" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-38containersuitetestlistblob/blob/038containersuitetestlistblobspagination + method: PUT + response: + body: "" + headers: + Content-Md5: + - bNNVbesNpUvKBgtMOUeYOQ== + Date: + - Wed, 05 Apr 2017 22:33:10 GMT + Etag: + - '"0x8D47C73BD4F9F8E"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:10 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac347b-0001-00d8-4b5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello, world! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:NpKqNFmYV+6QMvRDRmbhOWx8gExVMIa8r8qOqm0pgbs= + Content-Length: + - "13" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-38containersuitetestlistblob/blob/138containersuitetestlistblobspagination + method: PUT + response: + body: "" + headers: + Content-Md5: + - bNNVbesNpUvKBgtMOUeYOQ== + Date: + - Wed, 05 Apr 2017 22:33:10 GMT + Etag: + - '"0x8D47C73BD5AEC3C"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:10 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac34a0-0001-00d8-6c5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello, world! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:HIx3n3W/jzvJad4atAaQJkxiwB4sM3uIjiXbTM356kY= + Content-Length: + - "13" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-38containersuitetestlistblob/blob/238containersuitetestlistblobspagination + method: PUT + response: + body: "" + headers: + Content-Md5: + - bNNVbesNpUvKBgtMOUeYOQ== + Date: + - Wed, 05 Apr 2017 22:33:10 GMT + Etag: + - '"0x8D47C73BD62408E"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:10 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac34af-0001-00d8-795c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello, world! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:7R/ZMcuXUS/ZTeoCxgUqnOZuPRb2RAoGgbPoEk4W7bI= + Content-Length: + - "13" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-38containersuitetestlistblob/blob/338containersuitetestlistblobspagination + method: PUT + response: + body: "" + headers: + Content-Md5: + - bNNVbesNpUvKBgtMOUeYOQ== + Date: + - Wed, 05 Apr 2017 22:33:10 GMT + Etag: + - '"0x8D47C73BD6994E0"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:10 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac34c1-0001-00d8-0b5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello, world! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:1UkmGJspqTPPNn6Kn83lLqzqs37NvrERz8iMXtRcSno= + Content-Length: + - "13" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-38containersuitetestlistblob/blob/438containersuitetestlistblobspagination + method: PUT + response: + body: "" + headers: + Content-Md5: + - bNNVbesNpUvKBgtMOUeYOQ== + Date: + - Wed, 05 Apr 2017 22:33:10 GMT + Etag: + - '"0x8D47C73BD70E92D"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:10 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac34cc-0001-00d8-155c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:HW6zlDnwAnA4UjmcVUBYxR0N2XYru4Bkz0MaXm3KqSc= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:11 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-38containersuitetestlistblob?comp=list&maxresults=2&restype=container + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x20\x53\x65\x72\x76\x69\x63\x65\x45\x6E\x64\x70\x6F\x69\x6E\x74\x3D\"\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x6F\x6C\x61\x6E\x67\x72\x6F\x63\x6B\x73\x6F\x6E\x61\x7A\x75\x72\x65\x2E\x62\x6C\x6F\x62\x2E\x63\x6F\x72\x65\x2E\x77\x69\x6E\x64\x6F\x77\x73\x2E\x6E\x65\x74\x2F\"\x20\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x4E\x61\x6D\x65\x3D\"\x63\x6E\x74\x2D\x33\x38\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\"\x3E\x3C\x4D\x61\x78\x52\x65\x73\x75\x6C\x74\x73\x3E\x32\x3C\x2F\x4D\x61\x78\x52\x65\x73\x75\x6C\x74\x73\x3E\x3C\x42\x6C\x6F\x62\x73\x3E\x3C\x42\x6C\x6F\x62\x3E\x3C\x4E\x61\x6D\x65\x3E\x62\x6C\x6F\x62\x2F\x30\x33\x38\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x70\x61\x67\x69\x6E\x61\x74\x69\x6F\x6E\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x31\x30\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\x30\x78\x38\x44\x34\x37\x43\x37\x33\x42\x44\x34\x46\x39\x46\x38\x45\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x31\x33\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x61\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x2F\x6F\x63\x74\x65\x74\x2D\x73\x74\x72\x65\x61\x6D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x45\x6E\x63\x6F\x64\x69\x6E\x67\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x61\x6E\x67\x75\x61\x67\x65\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x62\x4E\x4E\x56\x62\x65\x73\x4E\x70\x55\x76\x4B\x42\x67\x74\x4D\x4F\x55\x65\x59\x4F\x51\x3D\x3D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x3C\x43\x61\x63\x68\x65\x2D\x43\x6F\x6E\x74\x72\x6F\x6C\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x20\x2F\x3E\x3C\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x42\x6C\x6F\x63\x6B\x42\x6C\x6F\x62\x3C\x2F\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x75\x6E\x6C\x6F\x63\x6B\x65\x64\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x61\x76\x61\x69\x6C\x61\x62\x6C\x65\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x3C\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x2F\x42\x6C\x6F\x62\x3E\x3C\x42\x6C\x6F\x62\x3E\x3C\x4E\x61\x6D\x65\x3E\x62\x6C\x6F\x62\x2F\x31\x33\x38\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x70\x61\x67\x69\x6E\x61\x74\x69\x6F\x6E\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x31\x30\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\x30\x78\x38\x44\x34\x37\x43\x37\x33\x42\x44\x35\x41\x45\x43\x33\x43\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x31\x33\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x61\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x2F\x6F\x63\x74\x65\x74\x2D\x73\x74\x72\x65\x61\x6D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x45\x6E\x63\x6F\x64\x69\x6E\x67\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x61\x6E\x67\x75\x61\x67\x65\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x62\x4E\x4E\x56\x62\x65\x73\x4E\x70\x55\x76\x4B\x42\x67\x74\x4D\x4F\x55\x65\x59\x4F\x51\x3D\x3D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x3C\x43\x61\x63\x68\x65\x2D\x43\x6F\x6E\x74\x72\x6F\x6C\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x20\x2F\x3E\x3C\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x42\x6C\x6F\x63\x6B\x42\x6C\x6F\x62\x3C\x2F\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x75\x6E\x6C\x6F\x63\x6B\x65\x64\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x61\x76\x61\x69\x6C\x61\x62\x6C\x65\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x3C\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x2F\x42\x6C\x6F\x62\x3E\x3C\x2F\x42\x6C\x6F\x62\x73\x3E\x3C\x4E\x65\x78\x74\x4D\x61\x72\x6B\x65\x72\x3E\x32\x21\x31\x32\x30\x21\x4D\x44\x41\x77\x4D\x44\x51\x31\x49\x57\x4A\x73\x62\x32\x49\x76\x4D\x6A\x4D\x34\x59\x32\x39\x75\x64\x47\x46\x70\x62\x6D\x56\x79\x63\x33\x56\x70\x64\x47\x56\x30\x5A\x58\x4E\x30\x62\x47\x6C\x7A\x64\x47\x4A\x73\x62\x32\x4A\x7A\x63\x47\x46\x6E\x61\x57\x35\x68\x64\x47\x6C\x76\x62\x69\x45\x77\x4D\x44\x41\x77\x4D\x6A\x67\x68\x4F\x54\x6B\x35\x4F\x53\x30\x78\x4D\x69\x30\x7A\x4D\x56\x51\x79\x4D\x7A\x6F\x31\x4F\x54\x6F\x31\x4F\x53\x34\x35\x4F\x54\x6B\x35\x4F\x54\x6B\x35\x57\x69\x45\x2D\x3C\x2F\x4E\x65\x78\x74\x4D\x61\x72\x6B\x65\x72\x3E\x3C\x2F\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:10 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac34d5-0001-00d8-1d5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:9cb+HQHoJnhZQ5fzKTQxwsKL/bklGBVEam/gF4DWC7k= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:11 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-38containersuitetestlistblob?comp=list&marker=2%21120%21MDAwMDQ1IWJsb2IvMjM4Y29udGFpbmVyc3VpdGV0ZXN0bGlzdGJsb2JzcGFnaW5hdGlvbiEwMDAwMjghOTk5OS0xMi0zMVQyMzo1OTo1OS45OTk5OTk5WiE-&maxresults=2&restype=container + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x20\x53\x65\x72\x76\x69\x63\x65\x45\x6E\x64\x70\x6F\x69\x6E\x74\x3D\"\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x6F\x6C\x61\x6E\x67\x72\x6F\x63\x6B\x73\x6F\x6E\x61\x7A\x75\x72\x65\x2E\x62\x6C\x6F\x62\x2E\x63\x6F\x72\x65\x2E\x77\x69\x6E\x64\x6F\x77\x73\x2E\x6E\x65\x74\x2F\"\x20\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x4E\x61\x6D\x65\x3D\"\x63\x6E\x74\x2D\x33\x38\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\"\x3E\x3C\x4D\x61\x72\x6B\x65\x72\x3E\x62\x6C\x6F\x62\x2F\x32\x33\x38\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x70\x61\x67\x69\x6E\x61\x74\x69\x6F\x6E\x3C\x2F\x4D\x61\x72\x6B\x65\x72\x3E\x3C\x4D\x61\x78\x52\x65\x73\x75\x6C\x74\x73\x3E\x32\x3C\x2F\x4D\x61\x78\x52\x65\x73\x75\x6C\x74\x73\x3E\x3C\x42\x6C\x6F\x62\x73\x3E\x3C\x42\x6C\x6F\x62\x3E\x3C\x4E\x61\x6D\x65\x3E\x62\x6C\x6F\x62\x2F\x32\x33\x38\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x70\x61\x67\x69\x6E\x61\x74\x69\x6F\x6E\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x31\x30\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\x30\x78\x38\x44\x34\x37\x43\x37\x33\x42\x44\x36\x32\x34\x30\x38\x45\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x31\x33\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x61\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x2F\x6F\x63\x74\x65\x74\x2D\x73\x74\x72\x65\x61\x6D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x45\x6E\x63\x6F\x64\x69\x6E\x67\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x61\x6E\x67\x75\x61\x67\x65\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x62\x4E\x4E\x56\x62\x65\x73\x4E\x70\x55\x76\x4B\x42\x67\x74\x4D\x4F\x55\x65\x59\x4F\x51\x3D\x3D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x3C\x43\x61\x63\x68\x65\x2D\x43\x6F\x6E\x74\x72\x6F\x6C\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x20\x2F\x3E\x3C\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x42\x6C\x6F\x63\x6B\x42\x6C\x6F\x62\x3C\x2F\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x75\x6E\x6C\x6F\x63\x6B\x65\x64\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x61\x76\x61\x69\x6C\x61\x62\x6C\x65\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x3C\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x2F\x42\x6C\x6F\x62\x3E\x3C\x42\x6C\x6F\x62\x3E\x3C\x4E\x61\x6D\x65\x3E\x62\x6C\x6F\x62\x2F\x33\x33\x38\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x70\x61\x67\x69\x6E\x61\x74\x69\x6F\x6E\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x31\x30\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\x30\x78\x38\x44\x34\x37\x43\x37\x33\x42\x44\x36\x39\x39\x34\x45\x30\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x31\x33\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x61\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x2F\x6F\x63\x74\x65\x74\x2D\x73\x74\x72\x65\x61\x6D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x45\x6E\x63\x6F\x64\x69\x6E\x67\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x61\x6E\x67\x75\x61\x67\x65\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x62\x4E\x4E\x56\x62\x65\x73\x4E\x70\x55\x76\x4B\x42\x67\x74\x4D\x4F\x55\x65\x59\x4F\x51\x3D\x3D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x3C\x43\x61\x63\x68\x65\x2D\x43\x6F\x6E\x74\x72\x6F\x6C\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x20\x2F\x3E\x3C\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x42\x6C\x6F\x63\x6B\x42\x6C\x6F\x62\x3C\x2F\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x75\x6E\x6C\x6F\x63\x6B\x65\x64\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x61\x76\x61\x69\x6C\x61\x62\x6C\x65\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x3C\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x2F\x42\x6C\x6F\x62\x3E\x3C\x2F\x42\x6C\x6F\x62\x73\x3E\x3C\x4E\x65\x78\x74\x4D\x61\x72\x6B\x65\x72\x3E\x32\x21\x31\x32\x30\x21\x4D\x44\x41\x77\x4D\x44\x51\x31\x49\x57\x4A\x73\x62\x32\x49\x76\x4E\x44\x4D\x34\x59\x32\x39\x75\x64\x47\x46\x70\x62\x6D\x56\x79\x63\x33\x56\x70\x64\x47\x56\x30\x5A\x58\x4E\x30\x62\x47\x6C\x7A\x64\x47\x4A\x73\x62\x32\x4A\x7A\x63\x47\x46\x6E\x61\x57\x35\x68\x64\x47\x6C\x76\x62\x69\x45\x77\x4D\x44\x41\x77\x4D\x6A\x67\x68\x4F\x54\x6B\x35\x4F\x53\x30\x78\x4D\x69\x30\x7A\x4D\x56\x51\x79\x4D\x7A\x6F\x31\x4F\x54\x6F\x31\x4F\x53\x34\x35\x4F\x54\x6B\x35\x4F\x54\x6B\x35\x57\x69\x45\x2D\x3C\x2F\x4E\x65\x78\x74\x4D\x61\x72\x6B\x65\x72\x3E\x3C\x2F\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:10 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac34e9-0001-00d8-305c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Uyc7J218G+6tmKrHbhcZQV5IZJLukq6CclvHCg/P8gM= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:11 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-38containersuitetestlistblob?comp=list&marker=2%21120%21MDAwMDQ1IWJsb2IvNDM4Y29udGFpbmVyc3VpdGV0ZXN0bGlzdGJsb2JzcGFnaW5hdGlvbiEwMDAwMjghOTk5OS0xMi0zMVQyMzo1OTo1OS45OTk5OTk5WiE-&maxresults=2&restype=container + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x20\x53\x65\x72\x76\x69\x63\x65\x45\x6E\x64\x70\x6F\x69\x6E\x74\x3D\"\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x6F\x6C\x61\x6E\x67\x72\x6F\x63\x6B\x73\x6F\x6E\x61\x7A\x75\x72\x65\x2E\x62\x6C\x6F\x62\x2E\x63\x6F\x72\x65\x2E\x77\x69\x6E\x64\x6F\x77\x73\x2E\x6E\x65\x74\x2F\"\x20\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x4E\x61\x6D\x65\x3D\"\x63\x6E\x74\x2D\x33\x38\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\"\x3E\x3C\x4D\x61\x72\x6B\x65\x72\x3E\x62\x6C\x6F\x62\x2F\x34\x33\x38\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x70\x61\x67\x69\x6E\x61\x74\x69\x6F\x6E\x3C\x2F\x4D\x61\x72\x6B\x65\x72\x3E\x3C\x4D\x61\x78\x52\x65\x73\x75\x6C\x74\x73\x3E\x32\x3C\x2F\x4D\x61\x78\x52\x65\x73\x75\x6C\x74\x73\x3E\x3C\x42\x6C\x6F\x62\x73\x3E\x3C\x42\x6C\x6F\x62\x3E\x3C\x4E\x61\x6D\x65\x3E\x62\x6C\x6F\x62\x2F\x34\x33\x38\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x70\x61\x67\x69\x6E\x61\x74\x69\x6F\x6E\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x31\x30\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\x30\x78\x38\x44\x34\x37\x43\x37\x33\x42\x44\x37\x30\x45\x39\x32\x44\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x31\x33\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x61\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x2F\x6F\x63\x74\x65\x74\x2D\x73\x74\x72\x65\x61\x6D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x45\x6E\x63\x6F\x64\x69\x6E\x67\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x61\x6E\x67\x75\x61\x67\x65\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x62\x4E\x4E\x56\x62\x65\x73\x4E\x70\x55\x76\x4B\x42\x67\x74\x4D\x4F\x55\x65\x59\x4F\x51\x3D\x3D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x3C\x43\x61\x63\x68\x65\x2D\x43\x6F\x6E\x74\x72\x6F\x6C\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x20\x2F\x3E\x3C\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x42\x6C\x6F\x63\x6B\x42\x6C\x6F\x62\x3C\x2F\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x75\x6E\x6C\x6F\x63\x6B\x65\x64\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x61\x76\x61\x69\x6C\x61\x62\x6C\x65\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x3C\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x2F\x42\x6C\x6F\x62\x3E\x3C\x2F\x42\x6C\x6F\x62\x73\x3E\x3C\x4E\x65\x78\x74\x4D\x61\x72\x6B\x65\x72\x20\x2F\x3E\x3C\x2F\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:10 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac34fd-0001-00d8-415c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:ksAQWQ4YrUToDIbA6MCWVq8j7ff1jsDfM/pkCBEfbho= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:11 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-38containersuitetestlistblob?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:10 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3512-0001-00d8-555c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/ContainerSuite/TestListBlobsTraversal.yaml b/storage/recordings/ContainerSuite/TestListBlobsTraversal.yaml new file mode 100644 index 000000000000..db5b88d98add --- /dev/null +++ b/storage/recordings/ContainerSuite/TestListBlobsTraversal.yaml @@ -0,0 +1,402 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:3GUIiNsP7eC9ChOVsT2Vn9NurSKUnhHEpk5AmxDcHCw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:11 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-37containersuitetestlistblob?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:10 GMT + Etag: + - '"0x8D47C73BDAADE80"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:11 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac352b-0001-00d8-6e5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:O61HK2klIIpDJrg6mGtcnZ5N1EUsrgkZ+V6cMmT3gKA= + Content-Length: + - "0" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:11 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-37containersuitetestlistblob//usr/bin/ls + method: PUT + response: + body: "" + headers: + Content-Md5: + - 1B2M2Y8AsgTpgAmY7PhCfg== + Date: + - Wed, 05 Apr 2017 22:33:10 GMT + Etag: + - '"0x8D47C73BD9D5863"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:11 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3546-0001-00d8-055c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Wg1pns/LeRaZHz0MulOxh0YiUV63o2jXvzAQ6AJ9Lu0= + Content-Length: + - "0" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:11 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-37containersuitetestlistblob//usr/bin/cat + method: PUT + response: + body: "" + headers: + Content-Md5: + - 1B2M2Y8AsgTpgAmY7PhCfg== + Date: + - Wed, 05 Apr 2017 22:33:10 GMT + Etag: + - '"0x8D47C73BDA4859E"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:11 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3557-0001-00d8-145c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Jf9ppMX9Bae6Yigi12jN6bxSF2gnt7rUi7mE/66DyYQ= + Content-Length: + - "0" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:11 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-37containersuitetestlistblob//usr/lib64/libc.so + method: PUT + response: + body: "" + headers: + Content-Md5: + - 1B2M2Y8AsgTpgAmY7PhCfg== + Date: + - Wed, 05 Apr 2017 22:33:10 GMT + Etag: + - '"0x8D47C73BDABD9F1"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:11 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3565-0001-00d8-215c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:gsFWwAUM+kYMr8n4YF9zTLbDgXqb54kL5op5LtZM9wk= + Content-Length: + - "0" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:11 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-37containersuitetestlistblob//etc/hosts + method: PUT + response: + body: "" + headers: + Content-Md5: + - 1B2M2Y8AsgTpgAmY7PhCfg== + Date: + - Wed, 05 Apr 2017 22:33:10 GMT + Etag: + - '"0x8D47C73BDB30727"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:11 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3573-0001-00d8-2e5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:yV0gM94Yt0kSk+MQEPG7dAUkLxeuOTbC/BB6vy1QxXE= + Content-Length: + - "0" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:11 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-37containersuitetestlistblob//etc/init.d/iptables + method: PUT + response: + body: "" + headers: + Content-Md5: + - 1B2M2Y8AsgTpgAmY7PhCfg== + Date: + - Wed, 05 Apr 2017 22:33:10 GMT + Etag: + - '"0x8D47C73BDBA3462"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:11 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac357d-0001-00d8-355c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:EG6SjdwRFmuUYdsdef9V/8u+LlEt1t9veYzza/daXfg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:11 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-37containersuitetestlistblob?comp=list&delimiter=%2F&prefix=%2F&restype=container + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x20\x53\x65\x72\x76\x69\x63\x65\x45\x6E\x64\x70\x6F\x69\x6E\x74\x3D\"\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x6F\x6C\x61\x6E\x67\x72\x6F\x63\x6B\x73\x6F\x6E\x61\x7A\x75\x72\x65\x2E\x62\x6C\x6F\x62\x2E\x63\x6F\x72\x65\x2E\x77\x69\x6E\x64\x6F\x77\x73\x2E\x6E\x65\x74\x2F\"\x20\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x4E\x61\x6D\x65\x3D\"\x63\x6E\x74\x2D\x33\x37\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\"\x3E\x3C\x50\x72\x65\x66\x69\x78\x3E\x2F\x3C\x2F\x50\x72\x65\x66\x69\x78\x3E\x3C\x44\x65\x6C\x69\x6D\x69\x74\x65\x72\x3E\x2F\x3C\x2F\x44\x65\x6C\x69\x6D\x69\x74\x65\x72\x3E\x3C\x42\x6C\x6F\x62\x73\x3E\x3C\x42\x6C\x6F\x62\x50\x72\x65\x66\x69\x78\x3E\x3C\x4E\x61\x6D\x65\x3E\x2F\x65\x74\x63\x2F\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x2F\x42\x6C\x6F\x62\x50\x72\x65\x66\x69\x78\x3E\x3C\x42\x6C\x6F\x62\x50\x72\x65\x66\x69\x78\x3E\x3C\x4E\x61\x6D\x65\x3E\x2F\x75\x73\x72\x2F\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x2F\x42\x6C\x6F\x62\x50\x72\x65\x66\x69\x78\x3E\x3C\x2F\x42\x6C\x6F\x62\x73\x3E\x3C\x4E\x65\x78\x74\x4D\x61\x72\x6B\x65\x72\x20\x2F\x3E\x3C\x2F\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:10 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac358d-0001-00d8-425c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:SQxc+nTXMP5RJy/cRpmhQpNh6VWiGQsKEOO9c9vjqrY= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:11 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-37containersuitetestlistblob?comp=list&delimiter=%2F&prefix=%2Fetc%2F&restype=container + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x20\x53\x65\x72\x76\x69\x63\x65\x45\x6E\x64\x70\x6F\x69\x6E\x74\x3D\"\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x6F\x6C\x61\x6E\x67\x72\x6F\x63\x6B\x73\x6F\x6E\x61\x7A\x75\x72\x65\x2E\x62\x6C\x6F\x62\x2E\x63\x6F\x72\x65\x2E\x77\x69\x6E\x64\x6F\x77\x73\x2E\x6E\x65\x74\x2F\"\x20\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x4E\x61\x6D\x65\x3D\"\x63\x6E\x74\x2D\x33\x37\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\"\x3E\x3C\x50\x72\x65\x66\x69\x78\x3E\x2F\x65\x74\x63\x2F\x3C\x2F\x50\x72\x65\x66\x69\x78\x3E\x3C\x44\x65\x6C\x69\x6D\x69\x74\x65\x72\x3E\x2F\x3C\x2F\x44\x65\x6C\x69\x6D\x69\x74\x65\x72\x3E\x3C\x42\x6C\x6F\x62\x73\x3E\x3C\x42\x6C\x6F\x62\x3E\x3C\x4E\x61\x6D\x65\x3E\x2F\x65\x74\x63\x2F\x68\x6F\x73\x74\x73\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x31\x31\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\x30\x78\x38\x44\x34\x37\x43\x37\x33\x42\x44\x42\x33\x30\x37\x32\x37\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x30\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x61\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x2F\x6F\x63\x74\x65\x74\x2D\x73\x74\x72\x65\x61\x6D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x45\x6E\x63\x6F\x64\x69\x6E\x67\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x61\x6E\x67\x75\x61\x67\x65\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x31\x42\x32\x4D\x32\x59\x38\x41\x73\x67\x54\x70\x67\x41\x6D\x59\x37\x50\x68\x43\x66\x67\x3D\x3D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x3C\x43\x61\x63\x68\x65\x2D\x43\x6F\x6E\x74\x72\x6F\x6C\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x20\x2F\x3E\x3C\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x42\x6C\x6F\x63\x6B\x42\x6C\x6F\x62\x3C\x2F\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x75\x6E\x6C\x6F\x63\x6B\x65\x64\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x61\x76\x61\x69\x6C\x61\x62\x6C\x65\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x3C\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x2F\x42\x6C\x6F\x62\x3E\x3C\x42\x6C\x6F\x62\x50\x72\x65\x66\x69\x78\x3E\x3C\x4E\x61\x6D\x65\x3E\x2F\x65\x74\x63\x2F\x69\x6E\x69\x74\x2E\x64\x2F\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x2F\x42\x6C\x6F\x62\x50\x72\x65\x66\x69\x78\x3E\x3C\x2F\x42\x6C\x6F\x62\x73\x3E\x3C\x4E\x65\x78\x74\x4D\x61\x72\x6B\x65\x72\x20\x2F\x3E\x3C\x2F\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:11 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac359b-0001-00d8-4f5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Bw8FUx8n/Wn5SstZbGvkCDh3c0E237FcjaZlQoxC+J4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:11 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-37containersuitetestlistblob?comp=list&delimiter=%2F&prefix=%2Fetc%2Finit.d%2F&restype=container + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x20\x53\x65\x72\x76\x69\x63\x65\x45\x6E\x64\x70\x6F\x69\x6E\x74\x3D\"\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x6F\x6C\x61\x6E\x67\x72\x6F\x63\x6B\x73\x6F\x6E\x61\x7A\x75\x72\x65\x2E\x62\x6C\x6F\x62\x2E\x63\x6F\x72\x65\x2E\x77\x69\x6E\x64\x6F\x77\x73\x2E\x6E\x65\x74\x2F\"\x20\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x4E\x61\x6D\x65\x3D\"\x63\x6E\x74\x2D\x33\x37\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\"\x3E\x3C\x50\x72\x65\x66\x69\x78\x3E\x2F\x65\x74\x63\x2F\x69\x6E\x69\x74\x2E\x64\x2F\x3C\x2F\x50\x72\x65\x66\x69\x78\x3E\x3C\x44\x65\x6C\x69\x6D\x69\x74\x65\x72\x3E\x2F\x3C\x2F\x44\x65\x6C\x69\x6D\x69\x74\x65\x72\x3E\x3C\x42\x6C\x6F\x62\x73\x3E\x3C\x42\x6C\x6F\x62\x3E\x3C\x4E\x61\x6D\x65\x3E\x2F\x65\x74\x63\x2F\x69\x6E\x69\x74\x2E\x64\x2F\x69\x70\x74\x61\x62\x6C\x65\x73\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x31\x31\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\x30\x78\x38\x44\x34\x37\x43\x37\x33\x42\x44\x42\x41\x33\x34\x36\x32\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x30\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x61\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x2F\x6F\x63\x74\x65\x74\x2D\x73\x74\x72\x65\x61\x6D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x45\x6E\x63\x6F\x64\x69\x6E\x67\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x61\x6E\x67\x75\x61\x67\x65\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x31\x42\x32\x4D\x32\x59\x38\x41\x73\x67\x54\x70\x67\x41\x6D\x59\x37\x50\x68\x43\x66\x67\x3D\x3D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x3C\x43\x61\x63\x68\x65\x2D\x43\x6F\x6E\x74\x72\x6F\x6C\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x20\x2F\x3E\x3C\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x42\x6C\x6F\x63\x6B\x42\x6C\x6F\x62\x3C\x2F\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x75\x6E\x6C\x6F\x63\x6B\x65\x64\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x61\x76\x61\x69\x6C\x61\x62\x6C\x65\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x3C\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x2F\x42\x6C\x6F\x62\x3E\x3C\x2F\x42\x6C\x6F\x62\x73\x3E\x3C\x4E\x65\x78\x74\x4D\x61\x72\x6B\x65\x72\x20\x2F\x3E\x3C\x2F\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:11 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac35a6-0001-00d8-565c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:TR+0oDLjIbsJozE7o6o3uJo6C6D3fZnkeytqrOc7PmM= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:11 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-37containersuitetestlistblob?comp=list&delimiter=%2F&prefix=%2Fusr%2F&restype=container + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x20\x53\x65\x72\x76\x69\x63\x65\x45\x6E\x64\x70\x6F\x69\x6E\x74\x3D\"\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x6F\x6C\x61\x6E\x67\x72\x6F\x63\x6B\x73\x6F\x6E\x61\x7A\x75\x72\x65\x2E\x62\x6C\x6F\x62\x2E\x63\x6F\x72\x65\x2E\x77\x69\x6E\x64\x6F\x77\x73\x2E\x6E\x65\x74\x2F\"\x20\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x4E\x61\x6D\x65\x3D\"\x63\x6E\x74\x2D\x33\x37\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\"\x3E\x3C\x50\x72\x65\x66\x69\x78\x3E\x2F\x75\x73\x72\x2F\x3C\x2F\x50\x72\x65\x66\x69\x78\x3E\x3C\x44\x65\x6C\x69\x6D\x69\x74\x65\x72\x3E\x2F\x3C\x2F\x44\x65\x6C\x69\x6D\x69\x74\x65\x72\x3E\x3C\x42\x6C\x6F\x62\x73\x3E\x3C\x42\x6C\x6F\x62\x50\x72\x65\x66\x69\x78\x3E\x3C\x4E\x61\x6D\x65\x3E\x2F\x75\x73\x72\x2F\x62\x69\x6E\x2F\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x2F\x42\x6C\x6F\x62\x50\x72\x65\x66\x69\x78\x3E\x3C\x42\x6C\x6F\x62\x50\x72\x65\x66\x69\x78\x3E\x3C\x4E\x61\x6D\x65\x3E\x2F\x75\x73\x72\x2F\x6C\x69\x62\x36\x34\x2F\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x2F\x42\x6C\x6F\x62\x50\x72\x65\x66\x69\x78\x3E\x3C\x2F\x42\x6C\x6F\x62\x73\x3E\x3C\x4E\x65\x78\x74\x4D\x61\x72\x6B\x65\x72\x20\x2F\x3E\x3C\x2F\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:11 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac35b9-0001-00d8-665c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:T2u5NXENCmLER0EnyW2s5efXAlyWY8TM+pVlYhagssQ= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:11 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-37containersuitetestlistblob?comp=list&delimiter=%2F&prefix=%2Fusr%2Fbin%2F&restype=container + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x20\x53\x65\x72\x76\x69\x63\x65\x45\x6E\x64\x70\x6F\x69\x6E\x74\x3D\"\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x6F\x6C\x61\x6E\x67\x72\x6F\x63\x6B\x73\x6F\x6E\x61\x7A\x75\x72\x65\x2E\x62\x6C\x6F\x62\x2E\x63\x6F\x72\x65\x2E\x77\x69\x6E\x64\x6F\x77\x73\x2E\x6E\x65\x74\x2F\"\x20\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x4E\x61\x6D\x65\x3D\"\x63\x6E\x74\x2D\x33\x37\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\"\x3E\x3C\x50\x72\x65\x66\x69\x78\x3E\x2F\x75\x73\x72\x2F\x62\x69\x6E\x2F\x3C\x2F\x50\x72\x65\x66\x69\x78\x3E\x3C\x44\x65\x6C\x69\x6D\x69\x74\x65\x72\x3E\x2F\x3C\x2F\x44\x65\x6C\x69\x6D\x69\x74\x65\x72\x3E\x3C\x42\x6C\x6F\x62\x73\x3E\x3C\x42\x6C\x6F\x62\x3E\x3C\x4E\x61\x6D\x65\x3E\x2F\x75\x73\x72\x2F\x62\x69\x6E\x2F\x63\x61\x74\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x31\x31\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\x30\x78\x38\x44\x34\x37\x43\x37\x33\x42\x44\x41\x34\x38\x35\x39\x45\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x30\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x61\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x2F\x6F\x63\x74\x65\x74\x2D\x73\x74\x72\x65\x61\x6D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x45\x6E\x63\x6F\x64\x69\x6E\x67\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x61\x6E\x67\x75\x61\x67\x65\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x31\x42\x32\x4D\x32\x59\x38\x41\x73\x67\x54\x70\x67\x41\x6D\x59\x37\x50\x68\x43\x66\x67\x3D\x3D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x3C\x43\x61\x63\x68\x65\x2D\x43\x6F\x6E\x74\x72\x6F\x6C\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x20\x2F\x3E\x3C\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x42\x6C\x6F\x63\x6B\x42\x6C\x6F\x62\x3C\x2F\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x75\x6E\x6C\x6F\x63\x6B\x65\x64\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x61\x76\x61\x69\x6C\x61\x62\x6C\x65\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x3C\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x2F\x42\x6C\x6F\x62\x3E\x3C\x42\x6C\x6F\x62\x3E\x3C\x4E\x61\x6D\x65\x3E\x2F\x75\x73\x72\x2F\x62\x69\x6E\x2F\x6C\x73\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x31\x31\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\x30\x78\x38\x44\x34\x37\x43\x37\x33\x42\x44\x39\x44\x35\x38\x36\x33\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x30\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x61\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x2F\x6F\x63\x74\x65\x74\x2D\x73\x74\x72\x65\x61\x6D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x45\x6E\x63\x6F\x64\x69\x6E\x67\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x61\x6E\x67\x75\x61\x67\x65\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x31\x42\x32\x4D\x32\x59\x38\x41\x73\x67\x54\x70\x67\x41\x6D\x59\x37\x50\x68\x43\x66\x67\x3D\x3D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x3C\x43\x61\x63\x68\x65\x2D\x43\x6F\x6E\x74\x72\x6F\x6C\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x20\x2F\x3E\x3C\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x42\x6C\x6F\x63\x6B\x42\x6C\x6F\x62\x3C\x2F\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x75\x6E\x6C\x6F\x63\x6B\x65\x64\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x61\x76\x61\x69\x6C\x61\x62\x6C\x65\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x3C\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x2F\x42\x6C\x6F\x62\x3E\x3C\x2F\x42\x6C\x6F\x62\x73\x3E\x3C\x4E\x65\x78\x74\x4D\x61\x72\x6B\x65\x72\x20\x2F\x3E\x3C\x2F\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:11 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac35db-0001-00d8-035c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:opOTsDisGmgskNaIqGoPts/av/KvW4bF/yNdXJuC4Ww= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:11 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-37containersuitetestlistblob?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:11 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac35e1-0001-00d8-095c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/ContainerSuite/TestListBlobsWithMetadata.yaml b/storage/recordings/ContainerSuite/TestListBlobsWithMetadata.yaml new file mode 100644 index 000000000000..ddcd830e3db3 --- /dev/null +++ b/storage/recordings/ContainerSuite/TestListBlobsWithMetadata.yaml @@ -0,0 +1,582 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:iWLThoDaJ6jAtKj/zrTmSHAM1LT/GTNKwJxZo/k8E1M= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:11 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40containersuitetestlistblob?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:11 GMT + Etag: + - '"0x8D47C73BE062DEE"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:11 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac35f2-0001-00d8-185c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello, world! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:QBcuMmyJCBmizF0G86MaLqKstbM7tcGttprsoGC22sI= + Content-Length: + - "13" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:11 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40containersuitetestlistblob/blob/040containersuitetestlistblobswithmetadata + method: PUT + response: + body: "" + headers: + Content-Md5: + - bNNVbesNpUvKBgtMOUeYOQ== + Date: + - Wed, 05 Apr 2017 22:33:11 GMT + Etag: + - '"0x8D47C73BDF992C2"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:11 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3607-0001-00d8-2b5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:qi2yAlTq57ArYlEx0X+SEVg6Vl9WphAqp+5yM9FTNYg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:11 GMT + X-Ms-Meta-Lol: + - blob/040containersuitetestlistblobswithmetadata + X-Ms-Meta-Rofl_baz: + - Waz Qux + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40containersuitetestlistblob/blob/040containersuitetestlistblobswithmetadata?comp=metadata + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:11 GMT + Etag: + - '"0x8D47C73BE00BFFD"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:11 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3617-0001-00d8-365c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:ZpZRwhgbT8v1civqNVzXAMmewBIgBd2FaARvLGbefs4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:12 GMT + X-Ms-Meta-Lol: + - blob/040containersuitetestlistblobswithmetadata + X-Ms-Meta-Rofl_baz: + - Waz Qux + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40containersuitetestlistblob/blob/040containersuitetestlistblobswithmetadata?comp=snapshot + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:11 GMT + Etag: + - '"0x8D47C73BE0AD3EE"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:11 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac362f-0001-00d8-485c-aea568000000 + X-Ms-Snapshot: + - 2017-04-05T22:33:11.7546478Z + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello, world! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Rd6EOYPNn2fb+jMFaegyZwsTh+hTlmTn9XCpY7Tw0UM= + Content-Length: + - "13" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:12 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40containersuitetestlistblob/blob/140containersuitetestlistblobswithmetadata + method: PUT + response: + body: "" + headers: + Content-Md5: + - bNNVbesNpUvKBgtMOUeYOQ== + Date: + - Wed, 05 Apr 2017 22:33:11 GMT + Etag: + - '"0x8D47C73BE122840"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:11 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3646-0001-00d8-5b5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:lc4kc38SPeaKb3RclX3gC9eyFa2frwqWtiPG3CDLR3s= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:12 GMT + X-Ms-Meta-Lol: + - blob/140containersuitetestlistblobswithmetadata + X-Ms-Meta-Rofl_baz: + - Waz Qux + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40containersuitetestlistblob/blob/140containersuitetestlistblobswithmetadata?comp=metadata + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:11 GMT + Etag: + - '"0x8D47C73BE19557B"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:11 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac365b-0001-00d8-6c5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Jd+pH/agJrsV0G9hMa5Ms1EM1lnXAozvb181GQ5ZXmk= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:12 GMT + X-Ms-Meta-Lol: + - blob/140containersuitetestlistblobswithmetadata + X-Ms-Meta-Rofl_baz: + - Waz Qux + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40containersuitetestlistblob/blob/140containersuitetestlistblobswithmetadata?comp=snapshot + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:11 GMT + Etag: + - '"0x8D47C73BE205B9F"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:11 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac366f-0001-00d8-7e5c-aea568000000 + X-Ms-Snapshot: + - 2017-04-05T22:33:11.8957471Z + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello, world! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:TOkzvBGYlt2N/dqTj/2YRIhbCwpHalGGPjR5O9WPPkc= + Content-Length: + - "13" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:12 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40containersuitetestlistblob/blob/240containersuitetestlistblobswithmetadata + method: PUT + response: + body: "" + headers: + Content-Md5: + - bNNVbesNpUvKBgtMOUeYOQ== + Date: + - Wed, 05 Apr 2017 22:33:11 GMT + Etag: + - '"0x8D47C73BE2B812D"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:11 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac368c-0001-00d8-165c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:ONnlCa52v2qUSgPO9bPncbcXwdQN2A/cwtIx/6vnxRQ= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:12 GMT + X-Ms-Meta-Lol: + - blob/240containersuitetestlistblobswithmetadata + X-Ms-Meta-Rofl_baz: + - Waz Qux + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40containersuitetestlistblob/blob/240containersuitetestlistblobswithmetadata?comp=metadata + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:11 GMT + Etag: + - '"0x8D47C73BE38CA06"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:12 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac369e-0001-00d8-265c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:PtLLvfBingpPx1ZT67hu/akvO48sFwYoS5vwUWlLap4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:12 GMT + X-Ms-Meta-Lol: + - blob/240containersuitetestlistblobswithmetadata + X-Ms-Meta-Rofl_baz: + - Waz Qux + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40containersuitetestlistblob/blob/240containersuitetestlistblobswithmetadata?comp=snapshot + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:11 GMT + Etag: + - '"0x8D47C73BE401E6D"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:12 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac36b0-0001-00d8-385c-aea568000000 + X-Ms-Snapshot: + - 2017-04-05T22:33:12.1038957Z + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello, world! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Xw6lLR7X43Xqvoe9y4KoIbeuhEopwjRWs/ojEOCF+EY= + Content-Length: + - "13" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:12 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40containersuitetestlistblob/blob/340containersuitetestlistblobswithmetadata + method: PUT + response: + body: "" + headers: + Content-Md5: + - bNNVbesNpUvKBgtMOUeYOQ== + Date: + - Wed, 05 Apr 2017 22:33:11 GMT + Etag: + - '"0x8D47C73BE4772AE"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:12 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac36ce-0001-00d8-525c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:bOHf3GWRV6wodzAhFqn3vhP7kl/B+rAvWQbdwJhu9qU= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:12 GMT + X-Ms-Meta-Lol: + - blob/340containersuitetestlistblobswithmetadata + X-Ms-Meta-Rofl_baz: + - Waz Qux + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40containersuitetestlistblob/blob/340containersuitetestlistblobswithmetadata?comp=metadata + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:11 GMT + Etag: + - '"0x8D47C73BE4E9FE1"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:12 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac36e0-0001-00d8-645c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:JKsGBVxWPhWPRExBUdmLr+7G+NeGoggEJ9A2ch15Rqs= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:12 GMT + X-Ms-Meta-Lol: + - blob/340containersuitetestlistblobswithmetadata + X-Ms-Meta-Rofl_baz: + - Waz Qux + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40containersuitetestlistblob/blob/340containersuitetestlistblobswithmetadata?comp=snapshot + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:11 GMT + Etag: + - '"0x8D47C73BE590204"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:12 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac36f2-0001-00d8-6f5c-aea568000000 + X-Ms-Snapshot: + - 2017-04-05T22:33:12.2670084Z + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello, world! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:YkGmjHzh4H2KXUs+PvcuR8V19hj4U2NzTfemOFahkHU= + Content-Length: + - "13" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:12 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40containersuitetestlistblob/blob/nometa40containersuitetestlistblobswithmetadata + method: PUT + response: + body: "" + headers: + Content-Md5: + - bNNVbesNpUvKBgtMOUeYOQ== + Date: + - Wed, 05 Apr 2017 22:33:11 GMT + Etag: + - '"0x8D47C73BE602F3F"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:12 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac370f-0001-00d8-0a5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Lr+sEDmUABGg4IJ3tFrSDZrKhm9rX3O5t6FJmUDBnKI= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:12 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40containersuitetestlistblob?comp=list&include=snapshots%2Cmetadata&restype=container + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x20\x53\x65\x72\x76\x69\x63\x65\x45\x6E\x64\x70\x6F\x69\x6E\x74\x3D\"\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x6F\x6C\x61\x6E\x67\x72\x6F\x63\x6B\x73\x6F\x6E\x61\x7A\x75\x72\x65\x2E\x62\x6C\x6F\x62\x2E\x63\x6F\x72\x65\x2E\x77\x69\x6E\x64\x6F\x77\x73\x2E\x6E\x65\x74\x2F\"\x20\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x4E\x61\x6D\x65\x3D\"\x63\x6E\x74\x2D\x34\x30\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\"\x3E\x3C\x42\x6C\x6F\x62\x73\x3E\x3C\x42\x6C\x6F\x62\x3E\x3C\x4E\x61\x6D\x65\x3E\x62\x6C\x6F\x62\x2F\x30\x34\x30\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x77\x69\x74\x68\x6D\x65\x74\x61\x64\x61\x74\x61\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x53\x6E\x61\x70\x73\x68\x6F\x74\x3E\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x31\x31\x2E\x37\x35\x34\x36\x34\x37\x38\x5A\x3C\x2F\x53\x6E\x61\x70\x73\x68\x6F\x74\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x31\x31\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\x30\x78\x38\x44\x34\x37\x43\x37\x33\x42\x45\x30\x41\x44\x33\x45\x45\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x31\x33\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x61\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x2F\x6F\x63\x74\x65\x74\x2D\x73\x74\x72\x65\x61\x6D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x45\x6E\x63\x6F\x64\x69\x6E\x67\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x61\x6E\x67\x75\x61\x67\x65\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x62\x4E\x4E\x56\x62\x65\x73\x4E\x70\x55\x76\x4B\x42\x67\x74\x4D\x4F\x55\x65\x59\x4F\x51\x3D\x3D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x3C\x43\x61\x63\x68\x65\x2D\x43\x6F\x6E\x74\x72\x6F\x6C\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x20\x2F\x3E\x3C\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x42\x6C\x6F\x63\x6B\x42\x6C\x6F\x62\x3C\x2F\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x3C\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4D\x65\x74\x61\x64\x61\x74\x61\x3E\x3C\x4C\x6F\x6C\x3E\x62\x6C\x6F\x62\x2F\x30\x34\x30\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x77\x69\x74\x68\x6D\x65\x74\x61\x64\x61\x74\x61\x3C\x2F\x4C\x6F\x6C\x3E\x3C\x52\x6F\x66\x6C\x5F\x62\x61\x7A\x3E\x57\x61\x7A\x20\x51\x75\x78\x3C\x2F\x52\x6F\x66\x6C\x5F\x62\x61\x7A\x3E\x3C\x2F\x4D\x65\x74\x61\x64\x61\x74\x61\x3E\x3C\x2F\x42\x6C\x6F\x62\x3E\x3C\x42\x6C\x6F\x62\x3E\x3C\x4E\x61\x6D\x65\x3E\x62\x6C\x6F\x62\x2F\x30\x34\x30\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x77\x69\x74\x68\x6D\x65\x74\x61\x64\x61\x74\x61\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x31\x31\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\x30\x78\x38\x44\x34\x37\x43\x37\x33\x42\x45\x30\x30\x42\x46\x46\x44\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x31\x33\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x61\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x2F\x6F\x63\x74\x65\x74\x2D\x73\x74\x72\x65\x61\x6D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x45\x6E\x63\x6F\x64\x69\x6E\x67\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x61\x6E\x67\x75\x61\x67\x65\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x62\x4E\x4E\x56\x62\x65\x73\x4E\x70\x55\x76\x4B\x42\x67\x74\x4D\x4F\x55\x65\x59\x4F\x51\x3D\x3D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x3C\x43\x61\x63\x68\x65\x2D\x43\x6F\x6E\x74\x72\x6F\x6C\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x20\x2F\x3E\x3C\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x42\x6C\x6F\x63\x6B\x42\x6C\x6F\x62\x3C\x2F\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x75\x6E\x6C\x6F\x63\x6B\x65\x64\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x61\x76\x61\x69\x6C\x61\x62\x6C\x65\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x3C\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4D\x65\x74\x61\x64\x61\x74\x61\x3E\x3C\x4C\x6F\x6C\x3E\x62\x6C\x6F\x62\x2F\x30\x34\x30\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x77\x69\x74\x68\x6D\x65\x74\x61\x64\x61\x74\x61\x3C\x2F\x4C\x6F\x6C\x3E\x3C\x52\x6F\x66\x6C\x5F\x62\x61\x7A\x3E\x57\x61\x7A\x20\x51\x75\x78\x3C\x2F\x52\x6F\x66\x6C\x5F\x62\x61\x7A\x3E\x3C\x2F\x4D\x65\x74\x61\x64\x61\x74\x61\x3E\x3C\x2F\x42\x6C\x6F\x62\x3E\x3C\x42\x6C\x6F\x62\x3E\x3C\x4E\x61\x6D\x65\x3E\x62\x6C\x6F\x62\x2F\x31\x34\x30\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x77\x69\x74\x68\x6D\x65\x74\x61\x64\x61\x74\x61\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x53\x6E\x61\x70\x73\x68\x6F\x74\x3E\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x31\x31\x2E\x38\x39\x35\x37\x34\x37\x31\x5A\x3C\x2F\x53\x6E\x61\x70\x73\x68\x6F\x74\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x31\x31\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\x30\x78\x38\x44\x34\x37\x43\x37\x33\x42\x45\x32\x30\x35\x42\x39\x46\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x31\x33\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x61\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x2F\x6F\x63\x74\x65\x74\x2D\x73\x74\x72\x65\x61\x6D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x45\x6E\x63\x6F\x64\x69\x6E\x67\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x61\x6E\x67\x75\x61\x67\x65\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x62\x4E\x4E\x56\x62\x65\x73\x4E\x70\x55\x76\x4B\x42\x67\x74\x4D\x4F\x55\x65\x59\x4F\x51\x3D\x3D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x3C\x43\x61\x63\x68\x65\x2D\x43\x6F\x6E\x74\x72\x6F\x6C\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x20\x2F\x3E\x3C\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x42\x6C\x6F\x63\x6B\x42\x6C\x6F\x62\x3C\x2F\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x3C\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4D\x65\x74\x61\x64\x61\x74\x61\x3E\x3C\x4C\x6F\x6C\x3E\x62\x6C\x6F\x62\x2F\x31\x34\x30\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x77\x69\x74\x68\x6D\x65\x74\x61\x64\x61\x74\x61\x3C\x2F\x4C\x6F\x6C\x3E\x3C\x52\x6F\x66\x6C\x5F\x62\x61\x7A\x3E\x57\x61\x7A\x20\x51\x75\x78\x3C\x2F\x52\x6F\x66\x6C\x5F\x62\x61\x7A\x3E\x3C\x2F\x4D\x65\x74\x61\x64\x61\x74\x61\x3E\x3C\x2F\x42\x6C\x6F\x62\x3E\x3C\x42\x6C\x6F\x62\x3E\x3C\x4E\x61\x6D\x65\x3E\x62\x6C\x6F\x62\x2F\x31\x34\x30\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x77\x69\x74\x68\x6D\x65\x74\x61\x64\x61\x74\x61\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x31\x31\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\x30\x78\x38\x44\x34\x37\x43\x37\x33\x42\x45\x31\x39\x35\x35\x37\x42\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x31\x33\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x61\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x2F\x6F\x63\x74\x65\x74\x2D\x73\x74\x72\x65\x61\x6D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x45\x6E\x63\x6F\x64\x69\x6E\x67\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x61\x6E\x67\x75\x61\x67\x65\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x62\x4E\x4E\x56\x62\x65\x73\x4E\x70\x55\x76\x4B\x42\x67\x74\x4D\x4F\x55\x65\x59\x4F\x51\x3D\x3D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x3C\x43\x61\x63\x68\x65\x2D\x43\x6F\x6E\x74\x72\x6F\x6C\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x20\x2F\x3E\x3C\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x42\x6C\x6F\x63\x6B\x42\x6C\x6F\x62\x3C\x2F\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x75\x6E\x6C\x6F\x63\x6B\x65\x64\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x61\x76\x61\x69\x6C\x61\x62\x6C\x65\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x3C\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4D\x65\x74\x61\x64\x61\x74\x61\x3E\x3C\x4C\x6F\x6C\x3E\x62\x6C\x6F\x62\x2F\x31\x34\x30\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x77\x69\x74\x68\x6D\x65\x74\x61\x64\x61\x74\x61\x3C\x2F\x4C\x6F\x6C\x3E\x3C\x52\x6F\x66\x6C\x5F\x62\x61\x7A\x3E\x57\x61\x7A\x20\x51\x75\x78\x3C\x2F\x52\x6F\x66\x6C\x5F\x62\x61\x7A\x3E\x3C\x2F\x4D\x65\x74\x61\x64\x61\x74\x61\x3E\x3C\x2F\x42\x6C\x6F\x62\x3E\x3C\x42\x6C\x6F\x62\x3E\x3C\x4E\x61\x6D\x65\x3E\x62\x6C\x6F\x62\x2F\x32\x34\x30\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x77\x69\x74\x68\x6D\x65\x74\x61\x64\x61\x74\x61\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x53\x6E\x61\x70\x73\x68\x6F\x74\x3E\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x31\x32\x2E\x31\x30\x33\x38\x39\x35\x37\x5A\x3C\x2F\x53\x6E\x61\x70\x73\x68\x6F\x74\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x31\x32\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\x30\x78\x38\x44\x34\x37\x43\x37\x33\x42\x45\x34\x30\x31\x45\x36\x44\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x31\x33\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x61\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x2F\x6F\x63\x74\x65\x74\x2D\x73\x74\x72\x65\x61\x6D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x45\x6E\x63\x6F\x64\x69\x6E\x67\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x61\x6E\x67\x75\x61\x67\x65\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x62\x4E\x4E\x56\x62\x65\x73\x4E\x70\x55\x76\x4B\x42\x67\x74\x4D\x4F\x55\x65\x59\x4F\x51\x3D\x3D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x3C\x43\x61\x63\x68\x65\x2D\x43\x6F\x6E\x74\x72\x6F\x6C\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x20\x2F\x3E\x3C\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x42\x6C\x6F\x63\x6B\x42\x6C\x6F\x62\x3C\x2F\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x3C\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4D\x65\x74\x61\x64\x61\x74\x61\x3E\x3C\x4C\x6F\x6C\x3E\x62\x6C\x6F\x62\x2F\x32\x34\x30\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x77\x69\x74\x68\x6D\x65\x74\x61\x64\x61\x74\x61\x3C\x2F\x4C\x6F\x6C\x3E\x3C\x52\x6F\x66\x6C\x5F\x62\x61\x7A\x3E\x57\x61\x7A\x20\x51\x75\x78\x3C\x2F\x52\x6F\x66\x6C\x5F\x62\x61\x7A\x3E\x3C\x2F\x4D\x65\x74\x61\x64\x61\x74\x61\x3E\x3C\x2F\x42\x6C\x6F\x62\x3E\x3C\x42\x6C\x6F\x62\x3E\x3C\x4E\x61\x6D\x65\x3E\x62\x6C\x6F\x62\x2F\x32\x34\x30\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x77\x69\x74\x68\x6D\x65\x74\x61\x64\x61\x74\x61\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x31\x32\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\x30\x78\x38\x44\x34\x37\x43\x37\x33\x42\x45\x33\x38\x43\x41\x30\x36\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x31\x33\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x61\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x2F\x6F\x63\x74\x65\x74\x2D\x73\x74\x72\x65\x61\x6D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x45\x6E\x63\x6F\x64\x69\x6E\x67\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x61\x6E\x67\x75\x61\x67\x65\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x62\x4E\x4E\x56\x62\x65\x73\x4E\x70\x55\x76\x4B\x42\x67\x74\x4D\x4F\x55\x65\x59\x4F\x51\x3D\x3D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x3C\x43\x61\x63\x68\x65\x2D\x43\x6F\x6E\x74\x72\x6F\x6C\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x20\x2F\x3E\x3C\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x42\x6C\x6F\x63\x6B\x42\x6C\x6F\x62\x3C\x2F\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x75\x6E\x6C\x6F\x63\x6B\x65\x64\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x61\x76\x61\x69\x6C\x61\x62\x6C\x65\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x3C\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4D\x65\x74\x61\x64\x61\x74\x61\x3E\x3C\x4C\x6F\x6C\x3E\x62\x6C\x6F\x62\x2F\x32\x34\x30\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x77\x69\x74\x68\x6D\x65\x74\x61\x64\x61\x74\x61\x3C\x2F\x4C\x6F\x6C\x3E\x3C\x52\x6F\x66\x6C\x5F\x62\x61\x7A\x3E\x57\x61\x7A\x20\x51\x75\x78\x3C\x2F\x52\x6F\x66\x6C\x5F\x62\x61\x7A\x3E\x3C\x2F\x4D\x65\x74\x61\x64\x61\x74\x61\x3E\x3C\x2F\x42\x6C\x6F\x62\x3E\x3C\x42\x6C\x6F\x62\x3E\x3C\x4E\x61\x6D\x65\x3E\x62\x6C\x6F\x62\x2F\x33\x34\x30\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x77\x69\x74\x68\x6D\x65\x74\x61\x64\x61\x74\x61\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x53\x6E\x61\x70\x73\x68\x6F\x74\x3E\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x31\x32\x2E\x32\x36\x37\x30\x30\x38\x34\x5A\x3C\x2F\x53\x6E\x61\x70\x73\x68\x6F\x74\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x31\x32\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\x30\x78\x38\x44\x34\x37\x43\x37\x33\x42\x45\x35\x39\x30\x32\x30\x34\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x31\x33\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x61\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x2F\x6F\x63\x74\x65\x74\x2D\x73\x74\x72\x65\x61\x6D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x45\x6E\x63\x6F\x64\x69\x6E\x67\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x61\x6E\x67\x75\x61\x67\x65\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x62\x4E\x4E\x56\x62\x65\x73\x4E\x70\x55\x76\x4B\x42\x67\x74\x4D\x4F\x55\x65\x59\x4F\x51\x3D\x3D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x3C\x43\x61\x63\x68\x65\x2D\x43\x6F\x6E\x74\x72\x6F\x6C\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x20\x2F\x3E\x3C\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x42\x6C\x6F\x63\x6B\x42\x6C\x6F\x62\x3C\x2F\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x3C\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4D\x65\x74\x61\x64\x61\x74\x61\x3E\x3C\x4C\x6F\x6C\x3E\x62\x6C\x6F\x62\x2F\x33\x34\x30\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x77\x69\x74\x68\x6D\x65\x74\x61\x64\x61\x74\x61\x3C\x2F\x4C\x6F\x6C\x3E\x3C\x52\x6F\x66\x6C\x5F\x62\x61\x7A\x3E\x57\x61\x7A\x20\x51\x75\x78\x3C\x2F\x52\x6F\x66\x6C\x5F\x62\x61\x7A\x3E\x3C\x2F\x4D\x65\x74\x61\x64\x61\x74\x61\x3E\x3C\x2F\x42\x6C\x6F\x62\x3E\x3C\x42\x6C\x6F\x62\x3E\x3C\x4E\x61\x6D\x65\x3E\x62\x6C\x6F\x62\x2F\x33\x34\x30\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x77\x69\x74\x68\x6D\x65\x74\x61\x64\x61\x74\x61\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x31\x32\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\x30\x78\x38\x44\x34\x37\x43\x37\x33\x42\x45\x34\x45\x39\x46\x45\x31\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x31\x33\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x61\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x2F\x6F\x63\x74\x65\x74\x2D\x73\x74\x72\x65\x61\x6D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x45\x6E\x63\x6F\x64\x69\x6E\x67\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x61\x6E\x67\x75\x61\x67\x65\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x62\x4E\x4E\x56\x62\x65\x73\x4E\x70\x55\x76\x4B\x42\x67\x74\x4D\x4F\x55\x65\x59\x4F\x51\x3D\x3D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x3C\x43\x61\x63\x68\x65\x2D\x43\x6F\x6E\x74\x72\x6F\x6C\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x20\x2F\x3E\x3C\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x42\x6C\x6F\x63\x6B\x42\x6C\x6F\x62\x3C\x2F\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x75\x6E\x6C\x6F\x63\x6B\x65\x64\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x61\x76\x61\x69\x6C\x61\x62\x6C\x65\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x3C\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4D\x65\x74\x61\x64\x61\x74\x61\x3E\x3C\x4C\x6F\x6C\x3E\x62\x6C\x6F\x62\x2F\x33\x34\x30\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x77\x69\x74\x68\x6D\x65\x74\x61\x64\x61\x74\x61\x3C\x2F\x4C\x6F\x6C\x3E\x3C\x52\x6F\x66\x6C\x5F\x62\x61\x7A\x3E\x57\x61\x7A\x20\x51\x75\x78\x3C\x2F\x52\x6F\x66\x6C\x5F\x62\x61\x7A\x3E\x3C\x2F\x4D\x65\x74\x61\x64\x61\x74\x61\x3E\x3C\x2F\x42\x6C\x6F\x62\x3E\x3C\x42\x6C\x6F\x62\x3E\x3C\x4E\x61\x6D\x65\x3E\x62\x6C\x6F\x62\x2F\x6E\x6F\x6D\x65\x74\x61\x34\x30\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x62\x6C\x6F\x62\x73\x77\x69\x74\x68\x6D\x65\x74\x61\x64\x61\x74\x61\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x31\x32\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\x30\x78\x38\x44\x34\x37\x43\x37\x33\x42\x45\x36\x30\x32\x46\x33\x46\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x31\x33\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x61\x70\x70\x6C\x69\x63\x61\x74\x69\x6F\x6E\x2F\x6F\x63\x74\x65\x74\x2D\x73\x74\x72\x65\x61\x6D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x54\x79\x70\x65\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x45\x6E\x63\x6F\x64\x69\x6E\x67\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x61\x6E\x67\x75\x61\x67\x65\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x62\x4E\x4E\x56\x62\x65\x73\x4E\x70\x55\x76\x4B\x42\x67\x74\x4D\x4F\x55\x65\x59\x4F\x51\x3D\x3D\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4D\x44\x35\x3E\x3C\x43\x61\x63\x68\x65\x2D\x43\x6F\x6E\x74\x72\x6F\x6C\x20\x2F\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x44\x69\x73\x70\x6F\x73\x69\x74\x69\x6F\x6E\x20\x2F\x3E\x3C\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x42\x6C\x6F\x63\x6B\x42\x6C\x6F\x62\x3C\x2F\x42\x6C\x6F\x62\x54\x79\x70\x65\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x75\x6E\x6C\x6F\x63\x6B\x65\x64\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x61\x76\x61\x69\x6C\x61\x62\x6C\x65\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x3C\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x53\x65\x72\x76\x65\x72\x45\x6E\x63\x72\x79\x70\x74\x65\x64\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4D\x65\x74\x61\x64\x61\x74\x61\x20\x2F\x3E\x3C\x2F\x42\x6C\x6F\x62\x3E\x3C\x2F\x42\x6C\x6F\x62\x73\x3E\x3C\x4E\x65\x78\x74\x4D\x61\x72\x6B\x65\x72\x20\x2F\x3E\x3C\x2F\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:12 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3728-0001-00d8-225c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:IqNb3Oq6mLrEVU9TU2vtZ272a+nEftNW+lYk0KDzewo= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:12 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40containersuitetestlistblob?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:12 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3753-0001-00d8-495c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/ContainerSuite/TestListContainersPagination.yaml b/storage/recordings/ContainerSuite/TestListContainersPagination.yaml new file mode 100644 index 000000000000..541aea681960 --- /dev/null +++ b/storage/recordings/ContainerSuite/TestListContainersPagination.yaml @@ -0,0 +1,381 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:+a3Lm6EqRMw7S9m19q+6Trc8t6BljXgciGdnzPX+faw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:12 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-043containersuitetestlistcon?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:12 GMT + Etag: + - '"0x8D47C73BE9BF898"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:12 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3779-0001-00d8-6e5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:mdLvxOeZxKlVXlsuvEq65UAWkp4oIENzeFo9t19r+K4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:12 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-143containersuitetestlistcon?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:12 GMT + Etag: + - '"0x8D47C73BEA4ACB8"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:12 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3794-0001-00d8-065c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:3SyYBYeteaZI2a+sKGZucy9/S4TGHxSf61T65m41Pkg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:12 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-243containersuitetestlistcon?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:12 GMT + Etag: + - '"0x8D47C73BEAD60C8"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:12 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac37b9-0001-00d8-275c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:RwEdYP9JqyVrQV8xJIGMj6lya2Kv5Yw5M74+XzBjSX4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:12 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-343containersuitetestlistcon?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:12 GMT + Etag: + - '"0x8D47C73BEB5EDCE"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:12 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac37d0-0001-00d8-3a5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:M95YM9KFRo60/ZeAH8K6aaB2i3LfqMlATYWPDK6Y+4Y= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:13 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-443containersuitetestlistcon?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:12 GMT + Etag: + - '"0x8D47C73BEBD421C"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:12 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac37e9-0001-00d8-525c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:MMHBTl3/x0idwxrA/r0Ib4g20450nD9YwYyeDTImsh8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:13 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/?comp=list&maxresults=2 + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x20\x53\x65\x72\x76\x69\x63\x65\x45\x6E\x64\x70\x6F\x69\x6E\x74\x3D\"\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x6F\x6C\x61\x6E\x67\x72\x6F\x63\x6B\x73\x6F\x6E\x61\x7A\x75\x72\x65\x2E\x62\x6C\x6F\x62\x2E\x63\x6F\x72\x65\x2E\x77\x69\x6E\x64\x6F\x77\x73\x2E\x6E\x65\x74\x2F\"\x3E\x3C\x4D\x61\x78\x52\x65\x73\x75\x6C\x74\x73\x3E\x32\x3C\x2F\x4D\x61\x78\x52\x65\x73\x75\x6C\x74\x73\x3E\x3C\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x3E\x3C\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x3E\x3C\x4E\x61\x6D\x65\x3E\x63\x6E\x74\x2D\x30\x34\x33\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x63\x6F\x6E\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x31\x32\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\"\x30\x78\x38\x44\x34\x37\x43\x37\x33\x42\x45\x39\x42\x46\x38\x39\x38\"\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x75\x6E\x6C\x6F\x63\x6B\x65\x64\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x61\x76\x61\x69\x6C\x61\x62\x6C\x65\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x2F\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x3E\x3C\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x3E\x3C\x4E\x61\x6D\x65\x3E\x63\x6E\x74\x2D\x31\x34\x33\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x63\x6F\x6E\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x31\x32\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\"\x30\x78\x38\x44\x34\x37\x43\x37\x33\x42\x45\x41\x34\x41\x43\x42\x38\"\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x75\x6E\x6C\x6F\x63\x6B\x65\x64\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x61\x76\x61\x69\x6C\x61\x62\x6C\x65\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x2F\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x3E\x3C\x2F\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x3E\x3C\x4E\x65\x78\x74\x4D\x61\x72\x6B\x65\x72\x3E\x2F\x67\x6F\x6C\x61\x6E\x67\x72\x6F\x63\x6B\x73\x6F\x6E\x61\x7A\x75\x72\x65\x2F\x63\x6E\x74\x2D\x32\x33\x34\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x63\x6F\x6E\x74\x61\x69\x6E\x3C\x2F\x4E\x65\x78\x74\x4D\x61\x72\x6B\x65\x72\x3E\x3C\x2F\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:12 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3801-0001-00d8-665c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:7cdFNVdvLukb62FLeWLeqZqLiq22AGYtcyYWAcTwUV0= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:13 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/?comp=list&marker=%2Fgolangrocksonazure%2Fcnt-234containersuitetestcontain&maxresults=2 + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x20\x53\x65\x72\x76\x69\x63\x65\x45\x6E\x64\x70\x6F\x69\x6E\x74\x3D\"\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x6F\x6C\x61\x6E\x67\x72\x6F\x63\x6B\x73\x6F\x6E\x61\x7A\x75\x72\x65\x2E\x62\x6C\x6F\x62\x2E\x63\x6F\x72\x65\x2E\x77\x69\x6E\x64\x6F\x77\x73\x2E\x6E\x65\x74\x2F\"\x3E\x3C\x4D\x61\x72\x6B\x65\x72\x3E\x2F\x67\x6F\x6C\x61\x6E\x67\x72\x6F\x63\x6B\x73\x6F\x6E\x61\x7A\x75\x72\x65\x2F\x63\x6E\x74\x2D\x32\x33\x34\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x63\x6F\x6E\x74\x61\x69\x6E\x3C\x2F\x4D\x61\x72\x6B\x65\x72\x3E\x3C\x4D\x61\x78\x52\x65\x73\x75\x6C\x74\x73\x3E\x32\x3C\x2F\x4D\x61\x78\x52\x65\x73\x75\x6C\x74\x73\x3E\x3C\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x3E\x3C\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x3E\x3C\x4E\x61\x6D\x65\x3E\x63\x6E\x74\x2D\x32\x34\x33\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x63\x6F\x6E\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x31\x32\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\"\x30\x78\x38\x44\x34\x37\x43\x37\x33\x42\x45\x41\x44\x36\x30\x43\x38\"\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x75\x6E\x6C\x6F\x63\x6B\x65\x64\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x61\x76\x61\x69\x6C\x61\x62\x6C\x65\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x2F\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x3E\x3C\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x3E\x3C\x4E\x61\x6D\x65\x3E\x63\x6E\x74\x2D\x33\x34\x33\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x63\x6F\x6E\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x31\x32\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\"\x30\x78\x38\x44\x34\x37\x43\x37\x33\x42\x45\x42\x35\x45\x44\x43\x45\"\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x75\x6E\x6C\x6F\x63\x6B\x65\x64\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x61\x76\x61\x69\x6C\x61\x62\x6C\x65\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x2F\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x3E\x3C\x2F\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x3E\x3C\x4E\x65\x78\x74\x4D\x61\x72\x6B\x65\x72\x3E\x2F\x67\x6F\x6C\x61\x6E\x67\x72\x6F\x63\x6B\x73\x6F\x6E\x61\x7A\x75\x72\x65\x2F\x63\x6E\x74\x2D\x33\x34\x62\x6C\x6F\x63\x6B\x62\x6C\x6F\x62\x73\x75\x69\x74\x65\x74\x65\x73\x74\x63\x72\x65\x61\x74\x65\x62\x6C\x3C\x2F\x4E\x65\x78\x74\x4D\x61\x72\x6B\x65\x72\x3E\x3C\x2F\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:12 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3815-0001-00d8-775c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:hbTUFTGPhZrrfPf01j9CV9ZVbkKN3IzDNjDa4Mhcvkw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:13 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/?comp=list&marker=%2Fgolangrocksonazure%2Fcnt-34blockblobsuitetestcreatebl&maxresults=2 + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x20\x53\x65\x72\x76\x69\x63\x65\x45\x6E\x64\x70\x6F\x69\x6E\x74\x3D\"\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x6F\x6C\x61\x6E\x67\x72\x6F\x63\x6B\x73\x6F\x6E\x61\x7A\x75\x72\x65\x2E\x62\x6C\x6F\x62\x2E\x63\x6F\x72\x65\x2E\x77\x69\x6E\x64\x6F\x77\x73\x2E\x6E\x65\x74\x2F\"\x3E\x3C\x4D\x61\x72\x6B\x65\x72\x3E\x2F\x67\x6F\x6C\x61\x6E\x67\x72\x6F\x63\x6B\x73\x6F\x6E\x61\x7A\x75\x72\x65\x2F\x63\x6E\x74\x2D\x33\x34\x62\x6C\x6F\x63\x6B\x62\x6C\x6F\x62\x73\x75\x69\x74\x65\x74\x65\x73\x74\x63\x72\x65\x61\x74\x65\x62\x6C\x3C\x2F\x4D\x61\x72\x6B\x65\x72\x3E\x3C\x4D\x61\x78\x52\x65\x73\x75\x6C\x74\x73\x3E\x32\x3C\x2F\x4D\x61\x78\x52\x65\x73\x75\x6C\x74\x73\x3E\x3C\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x3E\x3C\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x3E\x3C\x4E\x61\x6D\x65\x3E\x63\x6E\x74\x2D\x34\x34\x33\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x63\x6F\x6E\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x31\x32\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\"\x30\x78\x38\x44\x34\x37\x43\x37\x33\x42\x45\x42\x44\x34\x32\x31\x43\"\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x75\x6E\x6C\x6F\x63\x6B\x65\x64\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x75\x73\x3E\x3C\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x61\x76\x61\x69\x6C\x61\x62\x6C\x65\x3C\x2F\x4C\x65\x61\x73\x65\x53\x74\x61\x74\x65\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x2F\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x3E\x3C\x2F\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x73\x3E\x3C\x4E\x65\x78\x74\x4D\x61\x72\x6B\x65\x72\x20\x2F\x3E\x3C\x2F\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:12 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3830-0001-00d8-0d5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:TbWFHgPU6J+hkbZRASZgO8cQtgCo7vS0rv7UAUT73ho= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:13 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-443containersuitetestlistcon?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:12 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3847-0001-00d8-245c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:rkwvrusvW1OAzuGhKvVdwrAtVI8SR/Z/4PzmghkISOw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:13 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-343containersuitetestlistcon?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:12 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3866-0001-00d8-425c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:gcnoNEkcIwwXJ/EVY1nev7lEUY6Fb0khdLmsmp7zBm8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:13 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-243containersuitetestlistcon?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:12 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac388c-0001-00d8-645c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:L2M4mlrnmsmXkN3po0Rl0PW9cOyw/6QE2PQuxx4ip1A= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:13 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-143containersuitetestlistcon?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:12 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac389f-0001-00d8-755c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:zaYJ+NF9ArU23f6nSjY5RFL5d24fBLO2SDhEZVMiY/s= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:13 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-043containersuitetestlistcon?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:12 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac38c3-0001-00d8-105c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/ContainerSuite/TestSetContainerPermissionsOnlySuccessfully.yaml b/storage/recordings/ContainerSuite/TestSetContainerPermissionsOnlySuccessfully.yaml new file mode 100644 index 000000000000..ef6f9055a1d9 --- /dev/null +++ b/storage/recordings/ContainerSuite/TestSetContainerPermissionsOnlySuccessfully.yaml @@ -0,0 +1,97 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:HxlXNyznIblPu2IwuXYvfPlunwGl72wbViAEzTXBM+o= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:13 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-58containersuitetestsetconta?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:12 GMT + Etag: + - '"0x8D47C73BF068CFF"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:13 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac38e7-0001-00d8-325c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: GolangRocksOnAzure2050-12-20T21:55:06Z2050-12-21T07:55:06Zrwd + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:8c7R60g2g8LXKkVejSZ84kAw/nznBVUlMJQFDpHlSgg= + Content-Length: + - "232" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Public-Access: + - blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:13 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-58containersuitetestsetconta?comp=acl&restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:12 GMT + Etag: + - '"0x8D47C73BF777FD3"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3904-0001-00d8-495c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:CTvatk4+qCzESakKLftn0RL37sNLrGjUQhN5KCXYaMQ= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:13 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-58containersuitetestsetconta?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:13 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3914-0001-00d8-585c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/ContainerSuite/TestSetContainerPermissionsSuccessfully.yaml b/storage/recordings/ContainerSuite/TestSetContainerPermissionsSuccessfully.yaml new file mode 100644 index 000000000000..e1a16d717287 --- /dev/null +++ b/storage/recordings/ContainerSuite/TestSetContainerPermissionsSuccessfully.yaml @@ -0,0 +1,97 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:8VkKbR0FvS1Vn+JTJh4D8udFrvHKY+jn3SYs6OaEFSA= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:13 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-54containersuitetestsetconta?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:13 GMT + Etag: + - '"0x8D47C73BF1EFB65"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:13 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3939-0001-00d8-795c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: GolangRocksOnAzure2050-12-20T21:55:06Z2050-12-21T07:55:06Zrwd + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:dtC7uzyVvuRP615pAtNY9jdrn8VbVKn3rA1B5lKbqa8= + Content-Length: + - "232" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Public-Access: + - blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:13 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-54containersuitetestsetconta?comp=acl&restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:13 GMT + Etag: + - '"0x8D47C73BF912725"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac394a-0001-00d8-085c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:QEd3WBufl+C8z7TJQ+yNYonTSNZQaR29i8e7cliwuh0= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:13 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-54containersuitetestsetconta?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:13 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac396b-0001-00d8-225c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/ContainerSuite/TestSetContainerPermissionsWithTimeoutSuccessfully.yaml b/storage/recordings/ContainerSuite/TestSetContainerPermissionsWithTimeoutSuccessfully.yaml new file mode 100644 index 000000000000..95fa4c6eff58 --- /dev/null +++ b/storage/recordings/ContainerSuite/TestSetContainerPermissionsWithTimeoutSuccessfully.yaml @@ -0,0 +1,97 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:8xMxTjXwyxmY58ibXtgn7jiW6wxq6obudk1RFnO+xMU= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:13 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-65containersuitetestsetconta?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:13 GMT + Etag: + - '"0x8D47C73BF37DEEE"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:13 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3984-0001-00d8-385c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: GolangRocksOnAzure2050-12-20T21:55:06Z2050-12-21T07:55:06Zrwd + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:bru8OJdPK9W50qzkfhNOOpfbnI+A8hyU+gOWb2IOMtI= + Content-Length: + - "232" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Public-Access: + - blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:13 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-65containersuitetestsetconta?comp=acl&restype=container&timeout=30 + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:13 GMT + Etag: + - '"0x8D47C73BFA8F968"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac39a2-0001-00d8-525c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:IAc3hy3qylHS07/RI8/DpHriNw/Lf3BmCafjR/+bw0I= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:13 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-65containersuitetestsetconta?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:13 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac39bc-0001-00d8-6a5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/ContainerSuite/TestSetThenGetContainerPermissionsOnlySuccessfully.yaml b/storage/recordings/ContainerSuite/TestSetThenGetContainerPermissionsOnlySuccessfully.yaml new file mode 100644 index 000000000000..a450fd9df7f4 --- /dev/null +++ b/storage/recordings/ContainerSuite/TestSetThenGetContainerPermissionsOnlySuccessfully.yaml @@ -0,0 +1,132 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:VZgV2RvtEYAniUSGIbhC2ES8ysvCwztyyQx8ellQFfA= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:14 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-65containersuitetestsettheng?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:13 GMT + Etag: + - '"0x8D47C73BF5137B8"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:13 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac39ca-0001-00d8-785c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:gEmHMIvTw4VhB+JEaQVJG1AZ//W3b6S4uqfeHdi1eKs= + Content-Length: + - "39" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Public-Access: + - blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:14 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-65containersuitetestsettheng?comp=acl&restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:13 GMT + Etag: + - '"0x8D47C73BFC25290"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac39e9-0001-00d8-135c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:ISJ+IwjOGcc7Zp9g7iChhOuxHA9yEClKpfmYb2qjuXU= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:14 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-65containersuitetestsettheng?comp=acl&restype=container + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x73\x20\x2F\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:13 GMT + Etag: + - '"0x8D47C73BFC25290"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Public-Access: + - blob + X-Ms-Request-Id: + - 5eac3a01-0001-00d8-275c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:SrnkzkWIGRlO7IUMAnH6YdnSk6FmwH0YTkBUdFesOFg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:14 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-65containersuitetestsettheng?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:13 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3a15-0001-00d8-3b5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/ContainerSuite/TestSetThenGetContainerPermissionsSuccessfully.yaml b/storage/recordings/ContainerSuite/TestSetThenGetContainerPermissionsSuccessfully.yaml new file mode 100644 index 000000000000..57bd37344e2b --- /dev/null +++ b/storage/recordings/ContainerSuite/TestSetThenGetContainerPermissionsSuccessfully.yaml @@ -0,0 +1,132 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:UYKJKPR/Rmy1V7CWvygqIWOFax0js3LjNvk9qhpVtDc= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:14 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-61containersuitetestsettheng?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:13 GMT + Etag: + - '"0x8D47C73BF74F29E"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3a36-0001-00d8-575c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: AutoRestIsSuperCool2050-12-20T21:55:06Z2050-12-21T07:55:06ZrwdGolangRocksOnAzure2050-12-21T17:55:06Z2050-12-22T03:55:06Zr + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:fH9cWNFAFiZlRSIKbiZ0vbVFm119SpFZXLmsUt7M2SI= + Content-Length: + - "424" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Public-Access: + - blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:14 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-61containersuitetestsettheng?comp=acl&restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:13 GMT + Etag: + - '"0x8D47C73BFEDB07E"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3a5d-0001-00d8-745c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:jnbR9LonAgS9z3RUiw3XJCA4eE5spGm/bssX1IomQxg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:14 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-61containersuitetestsettheng?comp=acl&restype=container + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x73\x3E\x3C\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x3E\x3C\x49\x64\x3E\x41\x75\x74\x6F\x52\x65\x73\x74\x49\x73\x53\x75\x70\x65\x72\x43\x6F\x6F\x6C\x3C\x2F\x49\x64\x3E\x3C\x41\x63\x63\x65\x73\x73\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x53\x74\x61\x72\x74\x3E\x32\x30\x35\x30\x2D\x31\x32\x2D\x32\x30\x54\x32\x31\x3A\x35\x35\x3A\x30\x36\x2E\x30\x30\x30\x30\x30\x30\x30\x5A\x3C\x2F\x53\x74\x61\x72\x74\x3E\x3C\x45\x78\x70\x69\x72\x79\x3E\x32\x30\x35\x30\x2D\x31\x32\x2D\x32\x31\x54\x30\x37\x3A\x35\x35\x3A\x30\x36\x2E\x30\x30\x30\x30\x30\x30\x30\x5A\x3C\x2F\x45\x78\x70\x69\x72\x79\x3E\x3C\x50\x65\x72\x6D\x69\x73\x73\x69\x6F\x6E\x3E\x72\x77\x64\x3C\x2F\x50\x65\x72\x6D\x69\x73\x73\x69\x6F\x6E\x3E\x3C\x2F\x41\x63\x63\x65\x73\x73\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x2F\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x3E\x3C\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x3E\x3C\x49\x64\x3E\x47\x6F\x6C\x61\x6E\x67\x52\x6F\x63\x6B\x73\x4F\x6E\x41\x7A\x75\x72\x65\x3C\x2F\x49\x64\x3E\x3C\x41\x63\x63\x65\x73\x73\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x53\x74\x61\x72\x74\x3E\x32\x30\x35\x30\x2D\x31\x32\x2D\x32\x31\x54\x31\x37\x3A\x35\x35\x3A\x30\x36\x2E\x30\x30\x30\x30\x30\x30\x30\x5A\x3C\x2F\x53\x74\x61\x72\x74\x3E\x3C\x45\x78\x70\x69\x72\x79\x3E\x32\x30\x35\x30\x2D\x31\x32\x2D\x32\x32\x54\x30\x33\x3A\x35\x35\x3A\x30\x36\x2E\x30\x30\x30\x30\x30\x30\x30\x5A\x3C\x2F\x45\x78\x70\x69\x72\x79\x3E\x3C\x50\x65\x72\x6D\x69\x73\x73\x69\x6F\x6E\x3E\x72\x3C\x2F\x50\x65\x72\x6D\x69\x73\x73\x69\x6F\x6E\x3E\x3C\x2F\x41\x63\x63\x65\x73\x73\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x2F\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x3E\x3C\x2F\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x73\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:13 GMT + Etag: + - '"0x8D47C73BFEDB07E"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Public-Access: + - blob + X-Ms-Request-Id: + - 5eac3a6d-0001-00d8-805c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:aQw3v5t/gB4bVZhWx+0D95x3UiBXpuRaLIKej2JatBg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:14 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-61containersuitetestsettheng?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:13 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3a80-0001-00d8-105c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/CopyBlobSuite/TestAbortBlobCopy.yaml b/storage/recordings/CopyBlobSuite/TestAbortBlobCopy.yaml new file mode 100644 index 000000000000..0efca2366a6e --- /dev/null +++ b/storage/recordings/CopyBlobSuite/TestAbortBlobCopy.yaml @@ -0,0 +1,267 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:tJe4MHOTpb1fw/E8qPHlKfCd6PB4e6RUgz9w3wxWBFo= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:14 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31copyblobsuitetestabortblob?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:13 GMT + Etag: + - '"0x8D47C73BFA001D2"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3a9a-0001-00d8-245c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit + volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:dhNUlvHltwWU7btOMdUL0XBN0khASlz9WvoMYRsiusE= + Content-Length: + - "1024" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:14 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31copyblobsuitetestabortblob/blob/src31copyblobsuitetestabortblobcopy + method: PUT + response: + body: "" + headers: + Content-Md5: + - 0rZVY1m4cHz874drfCSd/w== + Date: + - Wed, 05 Apr 2017 22:33:14 GMT + Etag: + - '"0x8D47C73BF92CBFA"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3ab8-0001-00d8-3d5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:XrO7sRyw2UAlm7V75rylmGyj/1r2gDid8GRYyqyM7xU= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Copy-Source: + - https://golangrocksonazure.blob.core.windows.net/cnt-31copyblobsuitetestabortblob/blob/src31copyblobsuitetestabortblobcopy + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:14 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31copyblobsuitetestabortblob/blob/dst31copyblobsuitetestabortblobcopy + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:14 GMT + Etag: + - '"0x8D47C73BF9A9595"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Copy-Id: + - f814d858-1ab2-4f1b-bfb2-5d293b7000e6 + X-Ms-Copy-Status: + - success + X-Ms-Request-Id: + - 5eac3ac0-0001-00d8-445c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:0X1kyvws7KdbDDXk59IXN4GbhaiXdE1Rl0wKZZnhoZo= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:14 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31copyblobsuitetestabortblob/blob/dst31copyblobsuitetestabortblobcopy + method: HEAD + response: + body: "" + headers: + Accept-Ranges: + - bytes + Content-Length: + - "1024" + Content-Md5: + - 0rZVY1m4cHz874drfCSd/w== + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:14 GMT + Etag: + - '"0x8D47C73BF9A9595"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Copy-Completion-Time: + - Wed, 05 Apr 2017 22:33:14 GMT + X-Ms-Copy-Id: + - f814d858-1ab2-4f1b-bfb2-5d293b7000e6 + X-Ms-Copy-Progress: + - 1024/1024 + X-Ms-Copy-Source: + - https://golangrocksonazure.blob.core.windows.net/cnt-31copyblobsuitetestabortblob/blob/src31copyblobsuitetestabortblobcopy + X-Ms-Copy-Status: + - success + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac3adb-0001-00d8-5b5c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:z2s16trMrdgKCaeqC+7QtVT/TLBnqbvcydaMlXIUh0Q= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Copy-Action: + - abort + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:14 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31copyblobsuitetestabortblob/blob/dst31copyblobsuitetestabortblobcopy?comp=copy©id=f814d858-1ab2-4f1b-bfb2-5d293b7000e6 + method: PUT + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x72\x72\x6F\x72\x3E\x3C\x43\x6F\x64\x65\x3E\x4E\x6F\x50\x65\x6E\x64\x69\x6E\x67\x43\x6F\x70\x79\x4F\x70\x65\x72\x61\x74\x69\x6F\x6E\x3C\x2F\x43\x6F\x64\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x3E\x54\x68\x65\x72\x65\x20\x69\x73\x20\x63\x75\x72\x72\x65\x6E\x74\x6C\x79\x20\x6E\x6F\x20\x70\x65\x6E\x64\x69\x6E\x67\x20\x63\x6F\x70\x79\x20\x6F\x70\x65\x72\x61\x74\x69\x6F\x6E\x2E\n\x52\x65\x71\x75\x65\x73\x74\x49\x64\x3A\x35\x65\x61\x63\x33\x62\x32\x65\x2D\x30\x30\x30\x31\x2D\x30\x30\x64\x38\x2D\x32\x32\x35\x63\x2D\x61\x65\x61\x35\x36\x38\x30\x30\x30\x30\x30\x30\n\x54\x69\x6D\x65\x3A\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x31\x34\x2E\x36\x37\x31\x32\x31\x30\x32\x5A\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x45\x72\x72\x6F\x72\x3E" + headers: + Content-Length: + - "236" + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3b2e-0001-00d8-225c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 409 There is currently no pending copy operation. + code: 409 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:6GW5Bi5Dpfzm4zVqcyT6pFCZxpGqGPfqX72jso8WeOE= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:14 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31copyblobsuitetestabortblob/blob/src31copyblobsuitetestabortblobcopy + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3b50-0001-00d8-405c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:PsTSLtTYhHPYfBZTUVlpFgT+snbjvrkOGQiJYbGF8fU= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:14 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31copyblobsuitetestabortblob?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3b6f-0001-00d8-555c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/CopyBlobSuite/TestBlobCopy.yaml b/storage/recordings/CopyBlobSuite/TestBlobCopy.yaml new file mode 100644 index 000000000000..94139dab6994 --- /dev/null +++ b/storage/recordings/CopyBlobSuite/TestBlobCopy.yaml @@ -0,0 +1,330 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:YG3y1l7rmCuOU4sw5/P72hm3JWZuHieHzbkwkwWiXoI= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:14 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-26copyblobsuitetestblobcopy?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:14 GMT + Etag: + - '"0x8D47C73BFDE2732"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3b7a-0001-00d8-5f5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit + volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:QRUQV8j6ECiqbVQpCkZhHzmkVtrUoCrMw0w5C286AFs= + Content-Length: + - "1024" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:14 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-26copyblobsuitetestblobcopy/blob/src26copyblobsuitetestblobcopy + method: PUT + response: + body: "" + headers: + Content-Md5: + - 0rZVY1m4cHz874drfCSd/w== + Date: + - Wed, 05 Apr 2017 22:33:14 GMT + Etag: + - '"0x8D47C73BFD0F1A1"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3b8f-0001-00d8-705c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:/XtwYjuW6Jy/b+3JdIUBaJ6ua58BF8N/ucIxv4X3re8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Copy-Source: + - https://golangrocksonazure.blob.core.windows.net/cnt-26copyblobsuitetestblobcopy/blob/src26copyblobsuitetestblobcopy + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:15 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-26copyblobsuitetestblobcopy/blob/dst26copyblobsuitetestblobcopy + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:14 GMT + Etag: + - '"0x8D47C73BFDFC158"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Copy-Id: + - 9ea2b204-bd54-4b3c-b54b-efdf2dfa7e46 + X-Ms-Copy-Status: + - success + X-Ms-Request-Id: + - 5eac3bd0-0001-00d8-295c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:m/kdNIQ96T8prSckvgu6mbEjtaZGvNW+/2VF18zrCmA= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:15 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-26copyblobsuitetestblobcopy/blob/dst26copyblobsuitetestblobcopy + method: HEAD + response: + body: "" + headers: + Accept-Ranges: + - bytes + Content-Length: + - "1024" + Content-Md5: + - 0rZVY1m4cHz874drfCSd/w== + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:14 GMT + Etag: + - '"0x8D47C73BFDFC158"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Copy-Completion-Time: + - Wed, 05 Apr 2017 22:33:14 GMT + X-Ms-Copy-Id: + - 9ea2b204-bd54-4b3c-b54b-efdf2dfa7e46 + X-Ms-Copy-Progress: + - 1024/1024 + X-Ms-Copy-Source: + - https://golangrocksonazure.blob.core.windows.net/cnt-26copyblobsuitetestblobcopy/blob/src26copyblobsuitetestblobcopy + X-Ms-Copy-Status: + - success + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac3c02-0001-00d8-565c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:pgDEuByINAUzpGTFfmUUn9AM4uQ0l3agAmcYGlDNsbc= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:15 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-26copyblobsuitetestblobcopy/blob/dst26copyblobsuitetestblobcopy + method: GET + response: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit + volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + headers: + Accept-Ranges: + - bytes + Content-Length: + - "1024" + Content-Md5: + - 0rZVY1m4cHz874drfCSd/w== + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:14 GMT + Etag: + - '"0x8D47C73BFDFC158"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Copy-Completion-Time: + - Wed, 05 Apr 2017 22:33:14 GMT + X-Ms-Copy-Id: + - 9ea2b204-bd54-4b3c-b54b-efdf2dfa7e46 + X-Ms-Copy-Progress: + - 1024/1024 + X-Ms-Copy-Source: + - https://golangrocksonazure.blob.core.windows.net/cnt-26copyblobsuitetestblobcopy/blob/src26copyblobsuitetestblobcopy + X-Ms-Copy-Status: + - success + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac3c1f-0001-00d8-715c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:x9v747HCXf/2qEjp2/ba7aVv76A6o8vTF7C8wxmZPYw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:15 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-26copyblobsuitetestblobcopy/blob/dst26copyblobsuitetestblobcopy + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3c33-0001-00d8-035c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:3uKPkMnfPSfA6LsOyoZ6ZFAZtwrzkNkonQSTZyARE6w= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:15 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-26copyblobsuitetestblobcopy/blob/src26copyblobsuitetestblobcopy + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3c48-0001-00d8-145c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:e/PJJhgMv3RyO2MEJCR8+CGPGEK6bwKOAVPvK5VRPZw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:15 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-26copyblobsuitetestblobcopy?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3c62-0001-00d8-2c5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/CopyBlobSuite/TestIncrementalCopyBlobNoTimeout.yaml b/storage/recordings/CopyBlobSuite/TestIncrementalCopyBlobNoTimeout.yaml new file mode 100644 index 000000000000..661b840c7f2e --- /dev/null +++ b/storage/recordings/CopyBlobSuite/TestIncrementalCopyBlobNoTimeout.yaml @@ -0,0 +1,173 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:mGOPcENCBz4vZgGrGPAK9mDczpYl0WmwrvQwUhslesk= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Public-Access: + - blob + X-Ms-Date: + - Thu, 06 Apr 2017 18:41:40 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-46copyblobsuitetestincrement?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Thu, 06 Apr 2017 18:41:39 GMT + Etag: + - '"0x8D47D1C90B6FB0A"' + Last-Modified: + - Thu, 06 Apr 2017 18:41:40 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 21d2f37c-0001-006f-7905-afaa6d000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:hy8xP8hx6pOb1r/beX0cvlB2gFseMCSn0uTANiOYZlw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Content-Length: + - "10485760" + X-Ms-Blob-Sequence-Number: + - "0" + X-Ms-Blob-Type: + - PageBlob + X-Ms-Date: + - Thu, 06 Apr 2017 18:41:40 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-46copyblobsuitetestincrement/blob/src46copyblobsuitetestincrementalcopyblobnotimeout + method: PUT + response: + body: "" + headers: + Date: + - Thu, 06 Apr 2017 18:41:39 GMT + Etag: + - '"0x8D47D1C9061F86F"' + Last-Modified: + - Thu, 06 Apr 2017 18:41:40 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 21d2f386-0001-006f-8005-afaa6d000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:pyLKN+3uf1ddMdmdgQEtHBGbl/ip7q0ZrjNPng4tGh8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Thu, 06 Apr 2017 18:41:40 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-46copyblobsuitetestincrement/blob/src46copyblobsuitetestincrementalcopyblobnotimeout?comp=snapshot + method: PUT + response: + body: "" + headers: + Date: + - Thu, 06 Apr 2017 18:41:39 GMT + Etag: + - '"0x8D47D1C9061F86F"' + Last-Modified: + - Thu, 06 Apr 2017 18:41:40 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 21d2f397-0001-006f-0e05-afaa6d000000 + X-Ms-Snapshot: + - 2017-04-06T18:41:40.1448864Z + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:WFzBK3SazAwNPjBAs+3U0sUK8qZ9fddHp7Zcmpg1o4M= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Copy-Source: + - https://golangrocksonazure.blob.core.windows.net/cnt-46copyblobsuitetestincrement/blob/src46copyblobsuitetestincrementalcopyblobnotimeout?snapshot=2017-04-06T18:41:40.1448864Z + X-Ms-Date: + - Thu, 06 Apr 2017 18:41:40 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-46copyblobsuitetestincrement/blob/dst46copyblobsuitetestincrementalcopyblobnotimeout?comp=incrementalcopy + method: PUT + response: + body: "" + headers: + Date: + - Thu, 06 Apr 2017 18:41:39 GMT + Etag: + - '"0x8D47D1C9086018D"' + Last-Modified: + - Thu, 06 Apr 2017 18:41:40 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Copy-Id: + - 08155c6c-e234-4e37-9051-844fc1b15fbb + X-Ms-Copy-Status: + - pending + X-Ms-Request-Id: + - 21d2f3ad-0001-006f-2105-afaa6d000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:kQ8Z78M2Pls6F879UhxoxwT/7uuZkJTKOxaC1K6pALk= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Thu, 06 Apr 2017 18:41:41 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-46copyblobsuitetestincrement?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Thu, 06 Apr 2017 18:41:40 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 21d2f3e6-0001-006f-5305-afaa6d000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/CopyBlobSuite/TestIncrementalCopyBlobWithTimeout.yaml b/storage/recordings/CopyBlobSuite/TestIncrementalCopyBlobWithTimeout.yaml new file mode 100644 index 000000000000..54e376a1f84f --- /dev/null +++ b/storage/recordings/CopyBlobSuite/TestIncrementalCopyBlobWithTimeout.yaml @@ -0,0 +1,173 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:PzyDyDfBXDbRroLytuHxs/slIOF9asQnBqmSpRMlRjg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Public-Access: + - blob + X-Ms-Date: + - Thu, 06 Apr 2017 18:41:41 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-48copyblobsuitetestincrement?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Thu, 06 Apr 2017 18:41:40 GMT + Etag: + - '"0x8D47D1C90FA9FCA"' + Last-Modified: + - Thu, 06 Apr 2017 18:41:41 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 21d2f40d-0001-006f-7505-afaa6d000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:4BtQaQHSP4lUaifMXa3sImIncgtnaGtD0wPU+RQyDVA= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Content-Length: + - "10485760" + X-Ms-Blob-Sequence-Number: + - "0" + X-Ms-Blob-Type: + - PageBlob + X-Ms-Date: + - Thu, 06 Apr 2017 18:41:41 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-48copyblobsuitetestincrement/blob/src48copyblobsuitetestincrementalcopyblobwithtimeout + method: PUT + response: + body: "" + headers: + Date: + - Thu, 06 Apr 2017 18:41:40 GMT + Etag: + - '"0x8D47D1C90A835A0"' + Last-Modified: + - Thu, 06 Apr 2017 18:41:40 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 21d2f41f-0001-006f-0305-afaa6d000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:FwSIjINEz3pdU2koCg/7v2lVjPfrGcmmYi0ONQRVdII= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Thu, 06 Apr 2017 18:41:41 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-48copyblobsuitetestincrement/blob/src48copyblobsuitetestincrementalcopyblobwithtimeout?comp=snapshot + method: PUT + response: + body: "" + headers: + Date: + - Thu, 06 Apr 2017 18:41:40 GMT + Etag: + - '"0x8D47D1C90A835A0"' + Last-Modified: + - Thu, 06 Apr 2017 18:41:40 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 21d2f43c-0001-006f-1d05-afaa6d000000 + X-Ms-Snapshot: + - 2017-04-06T18:41:40.6052049Z + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:DLAuUwIf9UGlnqfBOWLE4mRoht+FkPr5L95/WvGJV6k= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Copy-Source: + - https://golangrocksonazure.blob.core.windows.net/cnt-48copyblobsuitetestincrement/blob/src48copyblobsuitetestincrementalcopyblobwithtimeout?snapshot=2017-04-06T18:41:40.6052049Z + X-Ms-Date: + - Thu, 06 Apr 2017 18:41:41 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-48copyblobsuitetestincrement/blob/dst48copyblobsuitetestincrementalcopyblobwithtimeout?comp=incrementalcopy&timeout=30 + method: PUT + response: + body: "" + headers: + Date: + - Thu, 06 Apr 2017 18:41:40 GMT + Etag: + - '"0x8D47D1C90B9C4EC"' + Last-Modified: + - Thu, 06 Apr 2017 18:41:40 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Copy-Id: + - 68efe3d5-3793-46eb-bbb9-47b8fbbd228b + X-Ms-Copy-Status: + - pending + X-Ms-Request-Id: + - 21d2f444-0001-006f-2505-afaa6d000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:2GacoRO4v8Z0OUHc6pJvmtkCDf+v5vZqH9NQBANVSY4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Thu, 06 Apr 2017 18:41:41 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-48copyblobsuitetestincrement?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Thu, 06 Apr 2017 18:41:40 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 21d2f45a-0001-006f-3b05-afaa6d000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/CopyBlobSuite/TestStartBlobCopy.yaml b/storage/recordings/CopyBlobSuite/TestStartBlobCopy.yaml new file mode 100644 index 000000000000..ac6393ad2b9c --- /dev/null +++ b/storage/recordings/CopyBlobSuite/TestStartBlobCopy.yaml @@ -0,0 +1,177 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:DT7yP+COrjJFlj6iXHzlg+UryC1HvYDtS14efLNGf3w= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:15 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31copyblobsuiteteststartblob?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:14 GMT + Etag: + - '"0x8D47C73C0228F39"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:15 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3c88-0001-00d8-4d5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit + volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:6FfF8+Y5nZFUxXf/fZkJQpDJnmlKpvXfCPQs920SVFo= + Content-Length: + - "1024" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:15 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31copyblobsuiteteststartblob/blob/src31copyblobsuiteteststartblobcopy + method: PUT + response: + body: "" + headers: + Content-Md5: + - 0rZVY1m4cHz874drfCSd/w== + Date: + - Wed, 05 Apr 2017 22:33:14 GMT + Etag: + - '"0x8D47C73C016B9C8"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:15 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3c9f-0001-00d8-605c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:FpzEleEFTGZ5tB3Q8VlRnZRKYVmyoNza6/YtF0HWyY4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Copy-Source: + - https://golangrocksonazure.blob.core.windows.net/cnt-31copyblobsuiteteststartblob/blob/src31copyblobsuiteteststartblobcopy + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:15 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31copyblobsuiteteststartblob/blob/dst31copyblobsuiteteststartblobcopy + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:14 GMT + Etag: + - '"0x8D47C73C01E8356"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:15 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Copy-Id: + - 9e266b6d-a433-4286-be66-34d22e018e99 + X-Ms-Copy-Status: + - success + X-Ms-Request-Id: + - 5eac3ca4-0001-00d8-655c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:JuV7n0npIE6mVzwZOiU3C9a9Oxd3wELAJKSVzujyZmk= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:15 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31copyblobsuiteteststartblob/blob/src31copyblobsuiteteststartblobcopy + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:14 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3cb7-0001-00d8-745c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:MeW6bCi5Uc/ZSUmjx2mGwHfHv+Fqu2hpwNy6oTAg0dE= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:15 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31copyblobsuiteteststartblob?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:15 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3cc3-0001-00d8-805c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/LeaseBlobSuite/TestAcquireInfiniteLease.yaml b/storage/recordings/LeaseBlobSuite/TestAcquireInfiniteLease.yaml new file mode 100644 index 000000000000..ad86b40a9f2d --- /dev/null +++ b/storage/recordings/LeaseBlobSuite/TestAcquireInfiniteLease.yaml @@ -0,0 +1,140 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:/TxslLjfP6iW5WDOz4DexmhfUAAqjUczGuhJiD7P2pk= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Fri, 21 Apr 2017 02:57:04 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-39leaseblobsuitetestacquirei?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Fri, 21 Apr 2017 02:57:04 GMT + Etag: + - '"0x8D488621753FA2E"' + Last-Modified: + - Fri, 21 Apr 2017 02:57:04 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - a68a1e96-0001-0003-174a-ba01be000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:cQnLL5ZMgcZVbdYFBxPPWKF8VI24LhjWPgMEM50LvOY= + Content-Length: + - "6" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Fri, 21 Apr 2017 02:57:04 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-39leaseblobsuitetestacquirei/blob/39leaseblobsuitetestacquireinfinitelease + method: PUT + response: + body: "" + headers: + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Date: + - Fri, 21 Apr 2017 02:57:04 GMT + Etag: + - '"0x8D48862172DE5D9"' + Last-Modified: + - Fri, 21 Apr 2017 02:57:04 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - a68a1e9c-0001-0003-1c4a-ba01be000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:nCwSRG6YOK776VPfk756miIfDe+WXGYH+J+jV5lSawg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Fri, 21 Apr 2017 02:57:04 GMT + X-Ms-Lease-Action: + - acquire + X-Ms-Lease-Duration: + - "-1" + X-Ms-Proposed-Lease-Id: + - dfe6dde8-68d5-4910-9248-c97c61768fea + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-39leaseblobsuitetestacquirei/blob/39leaseblobsuitetestacquireinfinitelease?comp=lease + method: PUT + response: + body: "" + headers: + Date: + - Fri, 21 Apr 2017 02:57:04 GMT + Etag: + - '"0x8D48862172DE5D9"' + Last-Modified: + - Fri, 21 Apr 2017 02:57:04 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Lease-Id: + - dfe6dde8-68d5-4910-9248-c97c61768fea + X-Ms-Request-Id: + - a68a1ea7-0001-0003-264a-ba01be000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Ef9xwrB5zWWfkdXCUrgpqFnPkmTN5pVd2pAfKVuIvMs= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Fri, 21 Apr 2017 02:57:04 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-39leaseblobsuitetestacquirei?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Fri, 21 Apr 2017 02:57:04 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - a68a1ead-0001-0003-2c4a-ba01be000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/LeaseBlobSuite/TestAcquireLeaseWithBadProposedLeaseID.yaml b/storage/recordings/LeaseBlobSuite/TestAcquireLeaseWithBadProposedLeaseID.yaml new file mode 100644 index 000000000000..678a701d2863 --- /dev/null +++ b/storage/recordings/LeaseBlobSuite/TestAcquireLeaseWithBadProposedLeaseID.yaml @@ -0,0 +1,138 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:FDqaMsqumePFxoKgiRM9mS10k/78wGt0mZs8gRgcDx4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:27 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-53leaseblobsuitetestacquirel?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:26 GMT + Etag: + - '"0x8D47C73C752A95A"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:27 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac4fdd-0001-00d8-375c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:uQCkHCm0B7QBSGK6cETJC3wtLBqOUSRTPY/4xRqaHcc= + Content-Length: + - "6" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:27 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-53leaseblobsuitetestacquirel/blob/53leaseblobsuitetestacquireleasewithbadproposedleaseid + method: PUT + response: + body: "" + headers: + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Date: + - Wed, 05 Apr 2017 22:33:26 GMT + Etag: + - '"0x8D47C73C7468D51"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:27 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac4fef-0001-00d8-445c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:YOse8rdgNUgRVlSye3hXhoyAENZJTC6ZkVN1B11M9DE= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:27 GMT + X-Ms-Lease-Action: + - acquire + X-Ms-Lease-Duration: + - "30" + X-Ms-Proposed-Lease-Id: + - badbadbad + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-53leaseblobsuitetestacquirel/blob/53leaseblobsuitetestacquireleasewithbadproposedleaseid?comp=lease + method: PUT + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x72\x72\x6F\x72\x3E\x3C\x43\x6F\x64\x65\x3E\x49\x6E\x76\x61\x6C\x69\x64\x48\x65\x61\x64\x65\x72\x56\x61\x6C\x75\x65\x3C\x2F\x43\x6F\x64\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x3E\x54\x68\x65\x20\x76\x61\x6C\x75\x65\x20\x66\x6F\x72\x20\x6F\x6E\x65\x20\x6F\x66\x20\x74\x68\x65\x20\x48\x54\x54\x50\x20\x68\x65\x61\x64\x65\x72\x73\x20\x69\x73\x20\x6E\x6F\x74\x20\x69\x6E\x20\x74\x68\x65\x20\x63\x6F\x72\x72\x65\x63\x74\x20\x66\x6F\x72\x6D\x61\x74\x2E\n\x52\x65\x71\x75\x65\x73\x74\x49\x64\x3A\x35\x65\x61\x63\x34\x66\x66\x62\x2D\x30\x30\x30\x31\x2D\x30\x30\x64\x38\x2D\x34\x65\x35\x63\x2D\x61\x65\x61\x35\x36\x38\x30\x30\x30\x30\x30\x30\n\x54\x69\x6D\x65\x3A\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x32\x37\x2E\x34\x32\x35\x39\x38\x30\x39\x5A\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x48\x65\x61\x64\x65\x72\x4E\x61\x6D\x65\x3E\x78\x2D\x6D\x73\x2D\x70\x72\x6F\x70\x6F\x73\x65\x64\x2D\x6C\x65\x61\x73\x65\x2D\x69\x64\x3C\x2F\x48\x65\x61\x64\x65\x72\x4E\x61\x6D\x65\x3E\x3C\x48\x65\x61\x64\x65\x72\x56\x61\x6C\x75\x65\x3E\x62\x61\x64\x62\x61\x64\x62\x61\x64\x3C\x2F\x48\x65\x61\x64\x65\x72\x56\x61\x6C\x75\x65\x3E\x3C\x2F\x45\x72\x72\x6F\x72\x3E" + headers: + Content-Length: + - "337" + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:26 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac4ffb-0001-00d8-4e5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 400 The value for one of the HTTP headers is not in the correct format. + code: 400 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:PZJhTD6CWE4oPaRHfnjhZzxyn73Qo+IsV+gD2guD2YM= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:27 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-53leaseblobsuitetestacquirel?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:26 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac500c-0001-00d8-5c5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/LeaseBlobSuite/TestAcquireLeaseWithNoProposedLeaseID.yaml b/storage/recordings/LeaseBlobSuite/TestAcquireLeaseWithNoProposedLeaseID.yaml new file mode 100644 index 000000000000..4a5af8d651d7 --- /dev/null +++ b/storage/recordings/LeaseBlobSuite/TestAcquireLeaseWithNoProposedLeaseID.yaml @@ -0,0 +1,138 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:sulqnP6xOBga/qO6u3tApM8kjHbwVpQbX5ioOG/f0d8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:27 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-52leaseblobsuitetestacquirel?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:27 GMT + Etag: + - '"0x8D47C73C771CF91"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:27 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac501b-0001-00d8-695c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:As+uTAF3nfcbrtb1cBGIeCL2CiHk+xHz0OC0r4/eCgc= + Content-Length: + - "6" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:27 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-52leaseblobsuitetestacquirel/blob/52leaseblobsuitetestacquireleasewithnoproposedleaseid + method: PUT + response: + body: "" + headers: + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Date: + - Wed, 05 Apr 2017 22:33:27 GMT + Etag: + - '"0x8D47C73C7647AF6"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:27 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac502d-0001-00d8-765c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:OK5qTFY+WyKOn/CSK0+rwMnQ5tZPOBi35CGrVc1Hd6U= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:27 GMT + X-Ms-Lease-Action: + - acquire + X-Ms-Lease-Duration: + - "30" + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-52leaseblobsuitetestacquirel/blob/52leaseblobsuitetestacquireleasewithnoproposedleaseid?comp=lease + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:27 GMT + Etag: + - '"0x8D47C73C7647AF6"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:27 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Lease-Id: + - bbcad337-7837-49ae-889c-270321f9946e + X-Ms-Request-Id: + - 5eac503f-0001-00d8-035c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:mZqprUEKW+gOl0FWOu6KJ2JUfrXSgMiEcE+MGpy3zSg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:27 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-52leaseblobsuitetestacquirel?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:27 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac504b-0001-00d8-0d5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/LeaseBlobSuite/TestAcquireLeaseWithProposedLeaseID.yaml b/storage/recordings/LeaseBlobSuite/TestAcquireLeaseWithProposedLeaseID.yaml new file mode 100644 index 000000000000..767393e18c06 --- /dev/null +++ b/storage/recordings/LeaseBlobSuite/TestAcquireLeaseWithProposedLeaseID.yaml @@ -0,0 +1,140 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:QOwficM83KsFF4dJ6YmJXYJ1UY3tIj+tydYCyMLtDbw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:27 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-50leaseblobsuitetestacquirel?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:27 GMT + Etag: + - '"0x8D47C73C793B569"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:27 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac5060-0001-00d8-205c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:SIgUjtLsmbBcnj+AOBax5u1JmuOy/7TR1pZHclcy5NY= + Content-Length: + - "6" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:27 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-50leaseblobsuitetestacquirel/blob/50leaseblobsuitetestacquireleasewithproposedleaseid + method: PUT + response: + body: "" + headers: + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Date: + - Wed, 05 Apr 2017 22:33:27 GMT + Etag: + - '"0x8D47C73C7868809"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:27 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac5075-0001-00d8-335c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:mkYw/hWssxhtLcTF6iHfo8ErV+yzj6G7n70SUvSTZZg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:27 GMT + X-Ms-Lease-Action: + - acquire + X-Ms-Lease-Duration: + - "30" + X-Ms-Proposed-Lease-Id: + - dfe6dde8-68d5-4910-9248-c97c61768fea + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-50leaseblobsuitetestacquirel/blob/50leaseblobsuitetestacquireleasewithproposedleaseid?comp=lease + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:27 GMT + Etag: + - '"0x8D47C73C7868809"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:27 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Lease-Id: + - dfe6dde8-68d5-4910-9248-c97c61768fea + X-Ms-Request-Id: + - 5eac5082-0001-00d8-405c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:AsCBOc501cfj1wVpcz/yVKQ+YDee1VCXqqLtJwY5EmM= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:28 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-50leaseblobsuitetestacquirel?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:27 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac508f-0001-00d8-4c5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/LeaseBlobSuite/TestBreakLeaseSuccessful.yaml b/storage/recordings/LeaseBlobSuite/TestBreakLeaseSuccessful.yaml new file mode 100644 index 000000000000..63f2ff64bc87 --- /dev/null +++ b/storage/recordings/LeaseBlobSuite/TestBreakLeaseSuccessful.yaml @@ -0,0 +1,175 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:o4+iXrTDxdzWhGPGP1NWfX/JvHGcLqu7kK7K8pgqNxY= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:28 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-39leaseblobsuitetestbreaklea?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:27 GMT + Etag: + - '"0x8D47C73C7B489A0"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:27 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac509e-0001-00d8-595c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:MkeFneicuafPmQCmjEXv4dzC1QcpG+e82xmTDNV3jCM= + Content-Length: + - "6" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:28 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-39leaseblobsuitetestbreaklea/blob/39leaseblobsuitetestbreakleasesuccessful + method: PUT + response: + body: "" + headers: + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Date: + - Wed, 05 Apr 2017 22:33:27 GMT + Etag: + - '"0x8D47C73C7A7837A"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:27 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac50b4-0001-00d8-695c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:IW9sqw07TlX21Ri4nEPIiDAa8GqXkU20vYxKcqiFMGg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:28 GMT + X-Ms-Lease-Action: + - acquire + X-Ms-Lease-Duration: + - "30" + X-Ms-Proposed-Lease-Id: + - dfe6dde8-68d5-4910-9248-c97c61768fea + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-39leaseblobsuitetestbreaklea/blob/39leaseblobsuitetestbreakleasesuccessful?comp=lease + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:27 GMT + Etag: + - '"0x8D47C73C7A7837A"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:27 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Lease-Id: + - dfe6dde8-68d5-4910-9248-c97c61768fea + X-Ms-Request-Id: + - 5eac50c2-0001-00d8-775c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:PnZuavUuDrw8ANxIeBiHhKYgX445cqXnXlg7KVvf/dA= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:28 GMT + X-Ms-Lease-Action: + - break + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-39leaseblobsuitetestbreaklea/blob/39leaseblobsuitetestbreakleasesuccessful?comp=lease + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:27 GMT + Etag: + - '"0x8D47C73C7A7837A"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:27 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Lease-Time: + - "29" + X-Ms-Request-Id: + - 5eac50f6-0001-00d8-205c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:UMJzbQ1Rj1IklNNVPFwFAK7vUdFgSxCltapC6Qd5++g= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:28 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-39leaseblobsuitetestbreaklea?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:27 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac510d-0001-00d8-335c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/LeaseBlobSuite/TestChangeLeaseNotSuccessfulbadProposedLeaseID.yaml b/storage/recordings/LeaseBlobSuite/TestChangeLeaseNotSuccessfulbadProposedLeaseID.yaml new file mode 100644 index 000000000000..12d71a35db2e --- /dev/null +++ b/storage/recordings/LeaseBlobSuite/TestChangeLeaseNotSuccessfulbadProposedLeaseID.yaml @@ -0,0 +1,177 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:TTJzVoJLE5RrdFHTZwN1cS+VkSuxHIL6RGff+NeI/OE= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:28 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-61leaseblobsuitetestchangele?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:27 GMT + Etag: + - '"0x8D47C73C7E93776"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:28 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac5124-0001-00d8-495c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:KNPtEe3xrFPagbRAu9kWpJckhX6F35EWuNv+SFYxdtE= + Content-Length: + - "6" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:28 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-61leaseblobsuitetestchangele/blob/61leaseblobsuitetestchangeleasenotsuccessfulbadproposedleaseid + method: PUT + response: + body: "" + headers: + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Date: + - Wed, 05 Apr 2017 22:33:27 GMT + Etag: + - '"0x8D47C73C7DC0A75"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:28 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac5131-0001-00d8-545c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:jScj1joo4CLKQU2ciKwNV1RmWTJLJ2ew+xHL0fiMrjM= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:28 GMT + X-Ms-Lease-Action: + - acquire + X-Ms-Lease-Duration: + - "30" + X-Ms-Proposed-Lease-Id: + - dfe6dde8-68d5-4910-9248-c97c61768fea + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-61leaseblobsuitetestchangele/blob/61leaseblobsuitetestchangeleasenotsuccessfulbadproposedleaseid?comp=lease + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:27 GMT + Etag: + - '"0x8D47C73C7DC0A75"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:28 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Lease-Id: + - dfe6dde8-68d5-4910-9248-c97c61768fea + X-Ms-Request-Id: + - 5eac513a-0001-00d8-5d5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:3KvZLj6XIe4P3/mPtMnR+dukdYHnpMOoTVJQOGkM8AA= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:28 GMT + X-Ms-Lease-Action: + - change + X-Ms-Lease-Id: + - dfe6dde8-68d5-4910-9248-c97c61768fea + X-Ms-Proposed-Lease-Id: + - 1f812371-a41d-49e6-b123-f4b542e + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-61leaseblobsuitetestchangele/blob/61leaseblobsuitetestchangeleasenotsuccessfulbadproposedleaseid?comp=lease + method: PUT + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x72\x72\x6F\x72\x3E\x3C\x43\x6F\x64\x65\x3E\x49\x6E\x76\x61\x6C\x69\x64\x48\x65\x61\x64\x65\x72\x56\x61\x6C\x75\x65\x3C\x2F\x43\x6F\x64\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x3E\x54\x68\x65\x20\x76\x61\x6C\x75\x65\x20\x66\x6F\x72\x20\x6F\x6E\x65\x20\x6F\x66\x20\x74\x68\x65\x20\x48\x54\x54\x50\x20\x68\x65\x61\x64\x65\x72\x73\x20\x69\x73\x20\x6E\x6F\x74\x20\x69\x6E\x20\x74\x68\x65\x20\x63\x6F\x72\x72\x65\x63\x74\x20\x66\x6F\x72\x6D\x61\x74\x2E\n\x52\x65\x71\x75\x65\x73\x74\x49\x64\x3A\x35\x65\x61\x63\x35\x31\x34\x64\x2D\x30\x30\x30\x31\x2D\x30\x30\x64\x38\x2D\x36\x62\x35\x63\x2D\x61\x65\x61\x35\x36\x38\x30\x30\x30\x30\x30\x30\n\x54\x69\x6D\x65\x3A\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x32\x38\x2E\x34\x36\x30\x36\x39\x32\x34\x5A\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x48\x65\x61\x64\x65\x72\x4E\x61\x6D\x65\x3E\x78\x2D\x6D\x73\x2D\x70\x72\x6F\x70\x6F\x73\x65\x64\x2D\x6C\x65\x61\x73\x65\x2D\x69\x64\x3C\x2F\x48\x65\x61\x64\x65\x72\x4E\x61\x6D\x65\x3E\x3C\x48\x65\x61\x64\x65\x72\x56\x61\x6C\x75\x65\x3E\x31\x66\x38\x31\x32\x33\x37\x31\x2D\x61\x34\x31\x64\x2D\x34\x39\x65\x36\x2D\x62\x31\x32\x33\x2D\x66\x34\x62\x35\x34\x32\x65\x3C\x2F\x48\x65\x61\x64\x65\x72\x56\x61\x6C\x75\x65\x3E\x3C\x2F\x45\x72\x72\x6F\x72\x3E" + headers: + Content-Length: + - "359" + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:27 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac514d-0001-00d8-6b5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 400 The value for one of the HTTP headers is not in the correct format. + code: 400 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:UG4g1ou5tuIKGPZp8hR0fLc7EF4jU9J8zRoQJ/240VQ= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:28 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-61leaseblobsuitetestchangele?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:28 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac515b-0001-00d8-755c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/LeaseBlobSuite/TestChangeLeaseSuccessful.yaml b/storage/recordings/LeaseBlobSuite/TestChangeLeaseSuccessful.yaml new file mode 100644 index 000000000000..2794bb391aaf --- /dev/null +++ b/storage/recordings/LeaseBlobSuite/TestChangeLeaseSuccessful.yaml @@ -0,0 +1,179 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:HbN3gbtWk4C6zEKoNArLeQY0sZm9T6XmG7+f2eLq7+I= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:28 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40leaseblobsuitetestchangele?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:28 GMT + Etag: + - '"0x8D47C73C810C39C"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:28 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac516f-0001-00d8-085c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:HQrWY3TzeOXKq7uJnF/mcbdr1tNzGfi+M0P7n5Dnv50= + Content-Length: + - "6" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:28 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40leaseblobsuitetestchangele/blob/40leaseblobsuitetestchangeleasesuccessful + method: PUT + response: + body: "" + headers: + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Date: + - Wed, 05 Apr 2017 22:33:28 GMT + Etag: + - '"0x8D47C73C8043322"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:28 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac5174-0001-00d8-0c5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:NI76+D9I30SCpMQGVPaAKWnPBdeg9HUgLnCtiKPeY7U= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:28 GMT + X-Ms-Lease-Action: + - acquire + X-Ms-Lease-Duration: + - "30" + X-Ms-Proposed-Lease-Id: + - dfe6dde8-68d5-4910-9248-c97c61768fea + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40leaseblobsuitetestchangele/blob/40leaseblobsuitetestchangeleasesuccessful?comp=lease + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:28 GMT + Etag: + - '"0x8D47C73C8043322"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:28 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Lease-Id: + - dfe6dde8-68d5-4910-9248-c97c61768fea + X-Ms-Request-Id: + - 5eac5189-0001-00d8-1e5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:5pm6hIIg93ELs3kAT3MLvADOwrQglbsSJzralgDuMG0= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:28 GMT + X-Ms-Lease-Action: + - change + X-Ms-Lease-Id: + - dfe6dde8-68d5-4910-9248-c97c61768fea + X-Ms-Proposed-Lease-Id: + - dfe6dde8-68d5-4910-9248-c97c61768fbb + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40leaseblobsuitetestchangele/blob/40leaseblobsuitetestchangeleasesuccessful?comp=lease + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:28 GMT + Etag: + - '"0x8D47C73C8043322"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:28 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Lease-Id: + - dfe6dde8-68d5-4910-9248-c97c61768fbb + X-Ms-Request-Id: + - 5eac51a4-0001-00d8-335c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:7rOSWW3GB4mve009n98SsvQgAp7XnoMl2fvXDRzyHlk= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:28 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40leaseblobsuitetestchangele?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:28 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac51bd-0001-00d8-4a5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/LeaseBlobSuite/TestReleaseLeaseNotSuccessfulBadLeaseID.yaml b/storage/recordings/LeaseBlobSuite/TestReleaseLeaseNotSuccessfulBadLeaseID.yaml new file mode 100644 index 000000000000..8bf1db9ebea3 --- /dev/null +++ b/storage/recordings/LeaseBlobSuite/TestReleaseLeaseNotSuccessfulBadLeaseID.yaml @@ -0,0 +1,175 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:NAXegyCuqomzxQWPmBFM3pMHVj+xXjQ1u8hyy4O4ooY= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:28 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-54leaseblobsuitetestreleasel?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:28 GMT + Etag: + - '"0x8D47C73C83A7303"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:28 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac51d5-0001-00d8-5f5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:GLu9allkgkswNeo+g80c9+6yTwk+hIMA7Lnn5T26GeI= + Content-Length: + - "6" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:29 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-54leaseblobsuitetestreleasel/blob/54leaseblobsuitetestreleaseleasenotsuccessfulbadleaseid + method: PUT + response: + body: "" + headers: + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Date: + - Wed, 05 Apr 2017 22:33:28 GMT + Etag: + - '"0x8D47C73C82D1F3D"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:28 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac51ed-0001-00d8-735c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:yYPGkcygK8sjVQ5xgySZIykMsCIo3MH4kSApbtKuXAA= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:29 GMT + X-Ms-Lease-Action: + - acquire + X-Ms-Lease-Duration: + - "30" + X-Ms-Proposed-Lease-Id: + - dfe6dde8-68d5-4910-9248-c97c61768fea + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-54leaseblobsuitetestreleasel/blob/54leaseblobsuitetestreleaseleasenotsuccessfulbadleaseid?comp=lease + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:28 GMT + Etag: + - '"0x8D47C73C82D1F3D"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:28 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Lease-Id: + - dfe6dde8-68d5-4910-9248-c97c61768fea + X-Ms-Request-Id: + - 5eac5208-0001-00d8-0c5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:fBNuI8zacAo33OflXrsJld96Egjy7IPRfOwPtMR5++0= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:29 GMT + X-Ms-Lease-Action: + - release + X-Ms-Lease-Id: + - badleaseid + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-54leaseblobsuitetestreleasel/blob/54leaseblobsuitetestreleaseleasenotsuccessfulbadleaseid?comp=lease + method: PUT + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x72\x72\x6F\x72\x3E\x3C\x43\x6F\x64\x65\x3E\x49\x6E\x76\x61\x6C\x69\x64\x48\x65\x61\x64\x65\x72\x56\x61\x6C\x75\x65\x3C\x2F\x43\x6F\x64\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x3E\x54\x68\x65\x20\x76\x61\x6C\x75\x65\x20\x66\x6F\x72\x20\x6F\x6E\x65\x20\x6F\x66\x20\x74\x68\x65\x20\x48\x54\x54\x50\x20\x68\x65\x61\x64\x65\x72\x73\x20\x69\x73\x20\x6E\x6F\x74\x20\x69\x6E\x20\x74\x68\x65\x20\x63\x6F\x72\x72\x65\x63\x74\x20\x66\x6F\x72\x6D\x61\x74\x2E\n\x52\x65\x71\x75\x65\x73\x74\x49\x64\x3A\x35\x65\x61\x63\x35\x32\x31\x61\x2D\x30\x30\x30\x31\x2D\x30\x30\x64\x38\x2D\x31\x64\x35\x63\x2D\x61\x65\x61\x35\x36\x38\x30\x30\x30\x30\x30\x30\n\x54\x69\x6D\x65\x3A\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x32\x39\x2E\x30\x30\x34\x30\x36\x36\x30\x5A\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x48\x65\x61\x64\x65\x72\x4E\x61\x6D\x65\x3E\x78\x2D\x6D\x73\x2D\x6C\x65\x61\x73\x65\x2D\x69\x64\x3C\x2F\x48\x65\x61\x64\x65\x72\x4E\x61\x6D\x65\x3E\x3C\x48\x65\x61\x64\x65\x72\x56\x61\x6C\x75\x65\x3E\x62\x61\x64\x6C\x65\x61\x73\x65\x69\x64\x3C\x2F\x48\x65\x61\x64\x65\x72\x56\x61\x6C\x75\x65\x3E\x3C\x2F\x45\x72\x72\x6F\x72\x3E" + headers: + Content-Length: + - "329" + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:28 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac521a-0001-00d8-1d5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 400 The value for one of the HTTP headers is not in the correct format. + code: 400 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:zY7LYpIEg76A4MjcuN/Tbs1Lc8tsEhP2cKYY9tB7nMM= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:29 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-54leaseblobsuitetestreleasel?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:28 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac522f-0001-00d8-305c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/LeaseBlobSuite/TestReleaseLeaseSuccessful.yaml b/storage/recordings/LeaseBlobSuite/TestReleaseLeaseSuccessful.yaml new file mode 100644 index 000000000000..9cec2ac34712 --- /dev/null +++ b/storage/recordings/LeaseBlobSuite/TestReleaseLeaseSuccessful.yaml @@ -0,0 +1,175 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:vyil4bAoMXJClIl8INmNp5ugOLnklaoEEZ5I5YZ/kDc= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:29 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-41leaseblobsuitetestreleasel?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:28 GMT + Etag: + - '"0x8D47C73C8627472"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:29 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac525f-0001-00d8-5c5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:B6sWW0Ham+4Cbn73eI3LAPWqicViGT2kdaXHelSZSEc= + Content-Length: + - "6" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:29 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-41leaseblobsuitetestreleasel/blob/41leaseblobsuitetestreleaseleasesuccessful + method: PUT + response: + body: "" + headers: + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Date: + - Wed, 05 Apr 2017 22:33:28 GMT + Etag: + - '"0x8D47C73C85680A2"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:29 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac527a-0001-00d8-725c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:0muB+K1PjTX/4HpluZhDnn6H+XwnGIYKVNJGkrZVZI0= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:29 GMT + X-Ms-Lease-Action: + - acquire + X-Ms-Lease-Duration: + - "30" + X-Ms-Proposed-Lease-Id: + - dfe6dde8-68d5-4910-9248-c97c61768fea + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-41leaseblobsuitetestreleasel/blob/41leaseblobsuitetestreleaseleasesuccessful?comp=lease + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:28 GMT + Etag: + - '"0x8D47C73C85680A2"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:29 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Lease-Id: + - dfe6dde8-68d5-4910-9248-c97c61768fea + X-Ms-Request-Id: + - 5eac5295-0001-00d8-0b5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:yqT+v/imq3TFp8EypvBT3z1DvoPsavw+PRCc/R+xgkk= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:29 GMT + X-Ms-Lease-Action: + - release + X-Ms-Lease-Id: + - dfe6dde8-68d5-4910-9248-c97c61768fea + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-41leaseblobsuitetestreleasel/blob/41leaseblobsuitetestreleaseleasesuccessful?comp=lease + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:28 GMT + Etag: + - '"0x8D47C73C85680A2"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:29 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac52a7-0001-00d8-1b5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:DmLfbOWK7KGU0RNqiiJhuvGuE85I45vaNCFYXiRSsm8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:29 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-41leaseblobsuitetestreleasel?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:28 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac52b1-0001-00d8-235c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/LeaseBlobSuite/TestRenewLeaseAgainstNoCurrentLease.yaml b/storage/recordings/LeaseBlobSuite/TestRenewLeaseAgainstNoCurrentLease.yaml new file mode 100644 index 000000000000..d249c811ca69 --- /dev/null +++ b/storage/recordings/LeaseBlobSuite/TestRenewLeaseAgainstNoCurrentLease.yaml @@ -0,0 +1,136 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:gAqN5ehsiNZpLP0c0glrTs+76tmMOc8em712F/vQ1/o= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:29 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-50leaseblobsuitetestrenewlea?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:28 GMT + Etag: + - '"0x8D47C73C88A0094"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:29 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac52c6-0001-00d8-335c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:JF2lHfXD/k9m4N+SxD85BzqmnCzYsanpR4AZHbBXMdU= + Content-Length: + - "6" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:29 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-50leaseblobsuitetestrenewlea/blob/50leaseblobsuitetestrenewleaseagainstnocurrentlease + method: PUT + response: + body: "" + headers: + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Date: + - Wed, 05 Apr 2017 22:33:28 GMT + Etag: + - '"0x8D47C73C87D2270"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:29 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac52cd-0001-00d8-395c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:aK3J4qL0BaJFOtzcZtibGUupe0tYlP1RC7Op0exeBXA= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:29 GMT + X-Ms-Lease-Action: + - renew + X-Ms-Lease-Id: + - Golang rocks on Azure + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-50leaseblobsuitetestrenewlea/blob/50leaseblobsuitetestrenewleaseagainstnocurrentlease?comp=lease + method: PUT + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x72\x72\x6F\x72\x3E\x3C\x43\x6F\x64\x65\x3E\x49\x6E\x76\x61\x6C\x69\x64\x48\x65\x61\x64\x65\x72\x56\x61\x6C\x75\x65\x3C\x2F\x43\x6F\x64\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x3E\x54\x68\x65\x20\x76\x61\x6C\x75\x65\x20\x66\x6F\x72\x20\x6F\x6E\x65\x20\x6F\x66\x20\x74\x68\x65\x20\x48\x54\x54\x50\x20\x68\x65\x61\x64\x65\x72\x73\x20\x69\x73\x20\x6E\x6F\x74\x20\x69\x6E\x20\x74\x68\x65\x20\x63\x6F\x72\x72\x65\x63\x74\x20\x66\x6F\x72\x6D\x61\x74\x2E\n\x52\x65\x71\x75\x65\x73\x74\x49\x64\x3A\x35\x65\x61\x63\x35\x32\x64\x62\x2D\x30\x30\x30\x31\x2D\x30\x30\x64\x38\x2D\x34\x35\x35\x63\x2D\x61\x65\x61\x35\x36\x38\x30\x30\x30\x30\x30\x30\n\x54\x69\x6D\x65\x3A\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x32\x39\x2E\x34\x36\x31\x33\x38\x30\x34\x5A\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x48\x65\x61\x64\x65\x72\x4E\x61\x6D\x65\x3E\x78\x2D\x6D\x73\x2D\x6C\x65\x61\x73\x65\x2D\x69\x64\x3C\x2F\x48\x65\x61\x64\x65\x72\x4E\x61\x6D\x65\x3E\x3C\x48\x65\x61\x64\x65\x72\x56\x61\x6C\x75\x65\x3E\x47\x6F\x6C\x61\x6E\x67\x20\x72\x6F\x63\x6B\x73\x20\x6F\x6E\x20\x41\x7A\x75\x72\x65\x3C\x2F\x48\x65\x61\x64\x65\x72\x56\x61\x6C\x75\x65\x3E\x3C\x2F\x45\x72\x72\x6F\x72\x3E" + headers: + Content-Length: + - "340" + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:28 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac52db-0001-00d8-455c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 400 The value for one of the HTTP headers is not in the correct format. + code: 400 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:SAjxkQzmsoOxkFdmhJiz/07Fzkr0AfEsfEPssBd1YDE= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:29 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-50leaseblobsuitetestrenewlea?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:29 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac52e7-0001-00d8-4f5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/LeaseBlobSuite/TestRenewLeaseSuccessful.yaml b/storage/recordings/LeaseBlobSuite/TestRenewLeaseSuccessful.yaml new file mode 100644 index 000000000000..15d9050c2583 --- /dev/null +++ b/storage/recordings/LeaseBlobSuite/TestRenewLeaseSuccessful.yaml @@ -0,0 +1,177 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:40OxckSKCF94CFPxlvV+ynZqMUAIlCt8G4cXjXCPWQ8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:29 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-39leaseblobsuitetestrenewlea?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:29 GMT + Etag: + - '"0x8D47C73C8A8FFB8"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:29 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac52fd-0001-00d8-625c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:wgYaMFgYTPYelRkDaO524UoKWKxXcJeDj9xz3Kw8OJk= + Content-Length: + - "6" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:29 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-39leaseblobsuitetestrenewlea/blob/39leaseblobsuitetestrenewleasesuccessful + method: PUT + response: + body: "" + headers: + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Date: + - Wed, 05 Apr 2017 22:33:29 GMT + Etag: + - '"0x8D47C73C8A2D9A8"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:29 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac5343-0001-00d8-205c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:jGkxsnyXZyZl3LrOgyqV0ABxJppSbVV18Rcwoz8EGtg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:29 GMT + X-Ms-Lease-Action: + - acquire + X-Ms-Lease-Duration: + - "30" + X-Ms-Proposed-Lease-Id: + - dfe6dde8-68d5-4910-9248-c97c61768fea + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-39leaseblobsuitetestrenewlea/blob/39leaseblobsuitetestrenewleasesuccessful?comp=lease + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:29 GMT + Etag: + - '"0x8D47C73C8A2D9A8"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:29 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Lease-Id: + - dfe6dde8-68d5-4910-9248-c97c61768fea + X-Ms-Request-Id: + - 5eac5355-0001-00d8-305c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:LanGqG1mwRkxkJGfLq4JloLFNmhVf4+xUWHLCUiIDZs= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:29 GMT + X-Ms-Lease-Action: + - renew + X-Ms-Lease-Id: + - dfe6dde8-68d5-4910-9248-c97c61768fea + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-39leaseblobsuitetestrenewlea/blob/39leaseblobsuitetestrenewleasesuccessful?comp=lease + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:29 GMT + Etag: + - '"0x8D47C73C8A2D9A8"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:29 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Lease-Id: + - dfe6dde8-68d5-4910-9248-c97c61768fea + X-Ms-Request-Id: + - 5eac5364-0001-00d8-3e5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:RBCRBwU5YA1NBxphFfhwngVwO8UUJnOHkB2ro/xYXL4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:29 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-39leaseblobsuitetestrenewlea?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:29 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac537d-0001-00d8-535c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/PageBlobSuite/TestGetPageRanges.yaml b/storage/recordings/PageBlobSuite/TestGetPageRanges.yaml new file mode 100644 index 000000000000..353287041969 --- /dev/null +++ b/storage/recordings/PageBlobSuite/TestGetPageRanges.yaml @@ -0,0 +1,443 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:tA5vyfPg2DBJt8jDzc9Ql3LJ9CQjpmieMknWUu2JOWI= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:29 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31pageblobsuitetestgetpagera?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:29 GMT + Etag: + - '"0x8D47C73C8D6322D"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:29 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac539c-0001-00d8-6c5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Y8AWottpdAUOoQmbkvnwd5Xm7D4W5vOsl0xVR4PDI94= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Content-Length: + - "10240" + X-Ms-Blob-Sequence-Number: + - "0" + X-Ms-Blob-Type: + - PageBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31pageblobsuitetestgetpagera/blob/131pageblobsuitetestgetpageranges + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:29 GMT + Etag: + - '"0x8D47C73C8C90624"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:29 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac53b2-0001-00d8-015c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:6Nj7UnreE8KhUPgQW1Z1gGi8dyQHZqMqHS3x1wDYP4U= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31pageblobsuitetestgetpagera/blob/131pageblobsuitetestgetpageranges?comp=pagelist + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x50\x61\x67\x65\x4C\x69\x73\x74\x20\x2F\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:29 GMT + Etag: + - '"0x8D47C73C8C90624"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:29 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Content-Length: + - "10240" + X-Ms-Request-Id: + - 5eac53d9-0001-00d8-265c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:dG0Wdb40Xc4UAxFyfUiANwNZVUtOxXdV13NcC1uSmlg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Content-Length: + - "10240" + X-Ms-Blob-Sequence-Number: + - "0" + X-Ms-Blob-Type: + - PageBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31pageblobsuitetestgetpagera/blob/231pageblobsuitetestgetpageranges + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:29 GMT + Etag: + - '"0x8D47C73C8D7128A"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:29 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac53fe-0001-00d8-475c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:JT07vD9vPNcpGvLxUofhx25V8qIbniLhj/1gbppUxk0= + Content-Length: + - "512" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - PageBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:30 GMT + X-Ms-Page-Write: + - update + X-Ms-Range: + - bytes=0-511 + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31pageblobsuitetestgetpagera/blob/231pageblobsuitetestgetpageranges?comp=page + method: PUT + response: + body: "" + headers: + Content-Md5: + - 2Xr7q2sERdQmQ41hZ7sPvQ== + Date: + - Wed, 05 Apr 2017 22:33:29 GMT + Etag: + - '"0x8D47C73C8E25F15"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:29 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Sequence-Number: + - "0" + X-Ms-Request-Id: + - 5eac5423-0001-00d8-685c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:2Mum5YrL+V0fn05X+aaedqV+U2YvvuF3vpgnt33aNaQ= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31pageblobsuitetestgetpagera/blob/231pageblobsuitetestgetpageranges?comp=pagelist + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x50\x61\x67\x65\x4C\x69\x73\x74\x3E\x3C\x50\x61\x67\x65\x52\x61\x6E\x67\x65\x3E\x3C\x53\x74\x61\x72\x74\x3E\x30\x3C\x2F\x53\x74\x61\x72\x74\x3E\x3C\x45\x6E\x64\x3E\x35\x31\x31\x3C\x2F\x45\x6E\x64\x3E\x3C\x2F\x50\x61\x67\x65\x52\x61\x6E\x67\x65\x3E\x3C\x2F\x50\x61\x67\x65\x4C\x69\x73\x74\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:29 GMT + Etag: + - '"0x8D47C73C8E25F15"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:29 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Content-Length: + - "10240" + X-Ms-Request-Id: + - 5eac5438-0001-00d8-795c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:IfdtQe4+v/YMjoQovGQr2Gcw6UT1/0y82yK3nETYjys= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Content-Length: + - "10240" + X-Ms-Blob-Sequence-Number: + - "0" + X-Ms-Blob-Type: + - PageBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31pageblobsuitetestgetpagera/blob/331pageblobsuitetestgetpageranges + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:29 GMT + Etag: + - '"0x8D47C73C8F0E0AB"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:30 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac5454-0001-00d8-0e5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:+ytDt7SMzzc+dy90aLYl57MZ52BgFxNYBKlAB0h4XYI= + Content-Length: + - "512" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - PageBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:30 GMT + X-Ms-Page-Write: + - update + X-Ms-Range: + - bytes=0-511 + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31pageblobsuitetestgetpagera/blob/331pageblobsuitetestgetpageranges?comp=page + method: PUT + response: + body: "" + headers: + Content-Md5: + - 2Xr7q2sERdQmQ41hZ7sPvQ== + Date: + - Wed, 05 Apr 2017 22:33:29 GMT + Etag: + - '"0x8D47C73C8FB69D9"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:30 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Sequence-Number: + - "0" + X-Ms-Request-Id: + - 5eac5470-0001-00d8-285c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit + volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:QbhpGf0uvkpkkvLeDd1R4wi1jL1yo7wzLWmwhz/zGFU= + Content-Length: + - "1024" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - PageBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:30 GMT + X-Ms-Page-Write: + - update + X-Ms-Range: + - bytes=1024-2047 + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31pageblobsuitetestgetpagera/blob/331pageblobsuitetestgetpageranges?comp=page + method: PUT + response: + body: "" + headers: + Content-Md5: + - 0rZVY1m4cHz874drfCSd/w== + Date: + - Wed, 05 Apr 2017 22:33:29 GMT + Etag: + - '"0x8D47C73C9029718"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:30 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Sequence-Number: + - "0" + X-Ms-Request-Id: + - 5eac548d-0001-00d8-425c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:sGTu5KacIddksQgZ9DsOLBmbAeKRD4un/qXMGwBIAtA= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31pageblobsuitetestgetpagera/blob/331pageblobsuitetestgetpageranges?comp=pagelist + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x50\x61\x67\x65\x4C\x69\x73\x74\x3E\x3C\x50\x61\x67\x65\x52\x61\x6E\x67\x65\x3E\x3C\x53\x74\x61\x72\x74\x3E\x30\x3C\x2F\x53\x74\x61\x72\x74\x3E\x3C\x45\x6E\x64\x3E\x35\x31\x31\x3C\x2F\x45\x6E\x64\x3E\x3C\x2F\x50\x61\x67\x65\x52\x61\x6E\x67\x65\x3E\x3C\x50\x61\x67\x65\x52\x61\x6E\x67\x65\x3E\x3C\x53\x74\x61\x72\x74\x3E\x31\x30\x32\x34\x3C\x2F\x53\x74\x61\x72\x74\x3E\x3C\x45\x6E\x64\x3E\x32\x30\x34\x37\x3C\x2F\x45\x6E\x64\x3E\x3C\x2F\x50\x61\x67\x65\x52\x61\x6E\x67\x65\x3E\x3C\x2F\x50\x61\x67\x65\x4C\x69\x73\x74\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:29 GMT + Etag: + - '"0x8D47C73C9029718"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:30 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Content-Length: + - "10240" + X-Ms-Request-Id: + - 5eac54a9-0001-00d8-5d5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Cn0pVaCuTB5uTvpMeoR8v716Vjad/xShYdRCEjpELEg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31pageblobsuitetestgetpagera?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:29 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac54c1-0001-00d8-755c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/PageBlobSuite/TestPutPageBlob.yaml b/storage/recordings/PageBlobSuite/TestPutPageBlob.yaml new file mode 100644 index 000000000000..a76a9af13202 --- /dev/null +++ b/storage/recordings/PageBlobSuite/TestPutPageBlob.yaml @@ -0,0 +1,148 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:tvYkEQ1GZ2zWRduetgbGIViQQ5cWqRMKyX4PFzhMkIQ= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-29pageblobsuitetestputpagebl?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:29 GMT + Etag: + - '"0x8D47C73C92EE91B"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:30 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac54e0-0001-00d8-115c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:XEb0XoGTlkh5AAsuwsd1qz4MhQGcWvPy17ZNmPqqgSc= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Content-Length: + - "10485760" + X-Ms-Blob-Sequence-Number: + - "0" + X-Ms-Blob-Type: + - PageBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-29pageblobsuitetestputpagebl/blob/29pageblobsuitetestputpageblob + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:30 GMT + Etag: + - '"0x8D47C73C921BD70"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:30 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac54fa-0001-00d8-265c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:VEEYywP1JUjalRyHovAQpRGGNb1z5oD+xKlR7sIJn7M= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-29pageblobsuitetestputpagebl/blob/29pageblobsuitetestputpageblob + method: HEAD + response: + body: "" + headers: + Accept-Ranges: + - bytes + Content-Length: + - "10485760" + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:30 GMT + Etag: + - '"0x8D47C73C921BD70"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:30 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Sequence-Number: + - "0" + X-Ms-Blob-Type: + - PageBlob + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac5511-0001-00d8-3b5c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:6MqV83TTy7DWuiNuIvHQsRokiV8pyVKu0BnxagQ9ePw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-29pageblobsuitetestputpagebl?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:30 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac5520-0001-00d8-495c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/PageBlobSuite/TestPutPagesClear.yaml b/storage/recordings/PageBlobSuite/TestPutPagesClear.yaml new file mode 100644 index 000000000000..ae0da389b9bf --- /dev/null +++ b/storage/recordings/PageBlobSuite/TestPutPagesClear.yaml @@ -0,0 +1,284 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:v6b9cZvdLNSrpjMUV4j19agcVTyjK5pWBQrGjY3YDdk= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31pageblobsuitetestputpagesc?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:30 GMT + Etag: + - '"0x8D47C73C94ED2CD"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:30 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac553b-0001-00d8-5f5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:G68RWsutirZihc1DgXPvSFNgbZ1t1WP4nj0Nv9s6vWE= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Content-Length: + - "10485760" + X-Ms-Blob-Sequence-Number: + - "0" + X-Ms-Blob-Type: + - PageBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31pageblobsuitetestputpagesc/blob/31pageblobsuitetestputpagesclear + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:30 GMT + Etag: + - '"0x8D47C73C941A745"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:30 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac554d-0001-00d8-6e5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit + volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricie + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:5c/iAbGP+JdP6QAX48Eb0We9xR1KHqHUAfl3k7hbJjg= + Content-Length: + - "2048" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - PageBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:30 GMT + X-Ms-Page-Write: + - update + X-Ms-Range: + - bytes=0-2047 + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31pageblobsuitetestputpagesc/blob/31pageblobsuitetestputpagesclear?comp=page + method: PUT + response: + body: "" + headers: + Content-Md5: + - 38PbAkkDLDPUjo6bIBbUzQ== + Date: + - Wed, 05 Apr 2017 22:33:30 GMT + Etag: + - '"0x8D47C73C94949C5"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:30 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Sequence-Number: + - "0" + X-Ms-Request-Id: + - 5eac5565-0001-00d8-015c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:57ni7xzY26eHlL8dkEzk5VltsLMqlnedJsYFu3uR4tM= + Content-Length: + - "0" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - PageBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:30 GMT + X-Ms-Page-Write: + - clear + X-Ms-Range: + - bytes=512-1023 + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31pageblobsuitetestputpagesc/blob/31pageblobsuitetestputpagesclear?comp=page + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:30 GMT + Etag: + - '"0x8D47C73C95076FC"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:30 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Sequence-Number: + - "0" + X-Ms-Request-Id: + - 5eac5580-0001-00d8-185c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:1icsn/ePcExLI6B40JdtbQ0U5XUL0jlt0C3+QpEpAcM= + Range: + - bytes=0-2047 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:30 GMT + X-Ms-Range-Get-Content-Md5: + - "false" + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31pageblobsuitetestputpagesc/blob/31pageblobsuitetestputpagesclear + method: GET + response: + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricie" + headers: + Accept-Ranges: + - bytes + Content-Length: + - "2048" + Content-Range: + - bytes 0-2047/10485760 + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:30 GMT + Etag: + - '"0x8D47C73C95076FC"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:30 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Sequence-Number: + - "0" + X-Ms-Blob-Type: + - PageBlob + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac5595-0001-00d8-295c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 206 Partial Content + code: 206 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:LMquHRjneFpwn2HH4pTupLVO8uKXVVfg6azk31Ayghg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:31 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31pageblobsuitetestputpagesc?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:30 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac55a4-0001-00d8-365c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/PageBlobSuite/TestPutPagesUpdate.yaml b/storage/recordings/PageBlobSuite/TestPutPagesUpdate.yaml new file mode 100644 index 000000000000..bb2d6d9f1414 --- /dev/null +++ b/storage/recordings/PageBlobSuite/TestPutPagesUpdate.yaml @@ -0,0 +1,404 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:fHZ/uBpYamtK91qPiNH6HBNV7hbz2Q4wQot0Lktfb0I= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:31 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-32pageblobsuitetestputpagesu?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:30 GMT + Etag: + - '"0x8D47C73C97D3DF5"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:30 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac55b5-0001-00d8-455c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:TovKus31KJdBj1yPNIgS5aL5Ijq9MEZHao0Ti3979kA= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Content-Length: + - "10485760" + X-Ms-Blob-Sequence-Number: + - "0" + X-Ms-Blob-Type: + - PageBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:31 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-32pageblobsuitetestputpagesu/blob/32pageblobsuitetestputpagesupdate + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:30 GMT + Etag: + - '"0x8D47C73C9720ECE"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:30 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac55c7-0001-00d8-565c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit + volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:r7cksT5ys4ZfBVzXPZFIj4tpQ6S9lDSjSzPOnjK2Nbo= + Content-Length: + - "1024" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - PageBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:31 GMT + X-Ms-Page-Write: + - update + X-Ms-Range: + - bytes=0-1023 + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-32pageblobsuitetestputpagesu/blob/32pageblobsuitetestputpagesupdate?comp=page + method: PUT + response: + body: "" + headers: + Content-Md5: + - 0rZVY1m4cHz874drfCSd/w== + Date: + - Wed, 05 Apr 2017 22:33:30 GMT + Etag: + - '"0x8D47C73C979631B"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:30 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Sequence-Number: + - "0" + X-Ms-Request-Id: + - 5eac55d5-0001-00d8-635c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Xa4dVHhFNLwzNAWZRdprMC6ZTllz/rNgEjmH8sEyUzg= + Content-Length: + - "512" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - PageBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:31 GMT + X-Ms-Page-Write: + - update + X-Ms-Range: + - bytes=1024-1535 + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-32pageblobsuitetestputpagesu/blob/32pageblobsuitetestputpagesupdate?comp=page + method: PUT + response: + body: "" + headers: + Content-Md5: + - 2Xr7q2sERdQmQ41hZ7sPvQ== + Date: + - Wed, 05 Apr 2017 22:33:30 GMT + Etag: + - '"0x8D47C73C980DE85"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:30 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Sequence-Number: + - "0" + X-Ms-Request-Id: + - 5eac55e1-0001-00d8-6d5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:2n7Z5/hqOuQTr/MlUy9QqraJmgImvRwL2iAw2HI6+1A= + Range: + - bytes=0-1535 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:31 GMT + X-Ms-Range-Get-Content-Md5: + - "false" + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-32pageblobsuitetestputpagesu/blob/32pageblobsuitetestputpagesupdate + method: GET + response: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit + volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio.Lorem ipsum + dolor sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac + headers: + Accept-Ranges: + - bytes + Content-Length: + - "1536" + Content-Range: + - bytes 0-1535/10485760 + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:30 GMT + Etag: + - '"0x8D47C73C980DE85"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:30 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Sequence-Number: + - "0" + X-Ms-Blob-Type: + - PageBlob + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac55f0-0001-00d8-7b5c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 206 Partial Content + code: 206 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:4N0WVOQNbRiTmItInO9TrH/fE1xsclv5JGN23rooYVA= + Content-Length: + - "512" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - PageBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:31 GMT + X-Ms-Page-Write: + - update + X-Ms-Range: + - bytes=0-511 + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-32pageblobsuitetestputpagesu/blob/32pageblobsuitetestputpagesupdate?comp=page + method: PUT + response: + body: "" + headers: + Content-Md5: + - 2Xr7q2sERdQmQ41hZ7sPvQ== + Date: + - Wed, 05 Apr 2017 22:33:30 GMT + Etag: + - '"0x8D47C73C98F601A"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:31 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Sequence-Number: + - "0" + X-Ms-Request-Id: + - 5eac55ff-0001-00d8-095c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:2n7Z5/hqOuQTr/MlUy9QqraJmgImvRwL2iAw2HI6+1A= + Range: + - bytes=0-1535 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:31 GMT + X-Ms-Range-Get-Content-Md5: + - "false" + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-32pageblobsuitetestputpagesu/blob/32pageblobsuitetestputpagesupdate + method: GET + response: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit + volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio.Lorem ipsum + dolor sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac + headers: + Accept-Ranges: + - bytes + Content-Length: + - "1536" + Content-Range: + - bytes 0-1535/10485760 + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:30 GMT + Etag: + - '"0x8D47C73C98F601A"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:31 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Sequence-Number: + - "0" + X-Ms-Blob-Type: + - PageBlob + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac560d-0001-00d8-165c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 206 Partial Content + code: 206 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:IJHLX0qSAj77ydGVxlZqM82F2YNHKx7pwC6LmQHeo3I= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:31 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-32pageblobsuitetestputpagesu?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:30 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac561e-0001-00d8-255c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageBlobSuite/TestBlobExists.yaml b/storage/recordings/StorageBlobSuite/TestBlobExists.yaml new file mode 100644 index 000000000000..99b70844d720 --- /dev/null +++ b/storage/recordings/StorageBlobSuite/TestBlobExists.yaml @@ -0,0 +1,206 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:NNfM0sOSRuZdFDM/PMmOF0jHDqoljosw5OWNqJRFaTE= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:03 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31storageblobsuitetestblobex?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:03 GMT + Etag: + - '"0x8D47C73B9418D6D"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:03 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac296a-0001-00d8-3f5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:yx3XIx06loqzIjzSkTaWbY96kiyIaNOvrRi8SDPOD4E= + Content-Length: + - "6" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:03 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31storageblobsuitetestblobex/blob/31storageblobsuitetestblobexists + method: PUT + response: + body: "" + headers: + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Date: + - Wed, 05 Apr 2017 22:33:03 GMT + Etag: + - '"0x8D47C73B93450D0"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:03 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2988-0001-00d8-565c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:xGXoX0ntPj2lXOgn1MUVYM9SPReP1NcQG/lFhutak2o= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:03 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31storageblobsuitetestblobex/blob/31storageblobsuitetestblobexists + method: HEAD + response: + body: "" + headers: + Accept-Ranges: + - bytes + Content-Length: + - "6" + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:03 GMT + Etag: + - '"0x8D47C73B93450D0"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:03 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac29ac-0001-00d8-745c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:jVwki/JVYnn4o8MgUy14dZ2k0yAHfUImZ+7bIHbuSV8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:03 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31storageblobsuitetestblobex/blob/31storageblobsuitetestblobexists.lol + method: HEAD + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:03 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac29bf-0001-00d8-075c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The specified blob does not exist. + code: 404 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:V9h+U2t20pn0Bv/5qCqQjhq9IQ8PW/OXyW8LKhpbUmY= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:04 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31storageblobsuitetestblobex/blob/31storageblobsuitetestblobexists.lol + method: DELETE + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x72\x72\x6F\x72\x3E\x3C\x43\x6F\x64\x65\x3E\x42\x6C\x6F\x62\x4E\x6F\x74\x46\x6F\x75\x6E\x64\x3C\x2F\x43\x6F\x64\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x3E\x54\x68\x65\x20\x73\x70\x65\x63\x69\x66\x69\x65\x64\x20\x62\x6C\x6F\x62\x20\x64\x6F\x65\x73\x20\x6E\x6F\x74\x20\x65\x78\x69\x73\x74\x2E\n\x52\x65\x71\x75\x65\x73\x74\x49\x64\x3A\x35\x65\x61\x63\x32\x39\x64\x37\x2D\x30\x30\x30\x31\x2D\x30\x30\x64\x38\x2D\x31\x64\x35\x63\x2D\x61\x65\x61\x35\x36\x38\x30\x30\x30\x30\x30\x30\n\x54\x69\x6D\x65\x3A\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x30\x33\x2E\x39\x31\x31\x38\x31\x32\x30\x5A\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x45\x72\x72\x6F\x72\x3E" + headers: + Content-Length: + - "215" + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:03 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac29d7-0001-00d8-1d5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The specified blob does not exist. + code: 404 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Ne2IefHqf2rD7fhQ/S5/isQrNZxxgUnu8YtrnleqQ0U= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:04 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-31storageblobsuitetestblobex?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:03 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac29e8-0001-00d8-2d5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageBlobSuite/TestDeleteBlobIfExists.yaml b/storage/recordings/StorageBlobSuite/TestDeleteBlobIfExists.yaml new file mode 100644 index 000000000000..e2dfa5e274c4 --- /dev/null +++ b/storage/recordings/StorageBlobSuite/TestDeleteBlobIfExists.yaml @@ -0,0 +1,124 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:my8+oQG+lcDLVGFTZ/IPYT2SjCtVmN01P1hbaf7VlH4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:04 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-39storageblobsuitetestdelete?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:03 GMT + Etag: + - '"0x8D47C73B9701FB3"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:04 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2a00-0001-00d8-405c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:8gL/zzInU+rUNJZIhWvPEwEZJyBS73UlXj9r3W0abvc= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:04 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-39storageblobsuitetestdelete/blob/39storageblobsuitetestdeleteblobifexists + method: DELETE + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x72\x72\x6F\x72\x3E\x3C\x43\x6F\x64\x65\x3E\x42\x6C\x6F\x62\x4E\x6F\x74\x46\x6F\x75\x6E\x64\x3C\x2F\x43\x6F\x64\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x3E\x54\x68\x65\x20\x73\x70\x65\x63\x69\x66\x69\x65\x64\x20\x62\x6C\x6F\x62\x20\x64\x6F\x65\x73\x20\x6E\x6F\x74\x20\x65\x78\x69\x73\x74\x2E\n\x52\x65\x71\x75\x65\x73\x74\x49\x64\x3A\x35\x65\x61\x63\x32\x61\x31\x36\x2D\x30\x30\x30\x31\x2D\x30\x30\x64\x38\x2D\x35\x34\x35\x63\x2D\x61\x65\x61\x35\x36\x38\x30\x30\x30\x30\x30\x30\n\x54\x69\x6D\x65\x3A\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x30\x34\x2E\x30\x37\x38\x39\x32\x36\x39\x5A\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x45\x72\x72\x6F\x72\x3E" + headers: + Content-Length: + - "215" + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:03 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2a16-0001-00d8-545c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The specified blob does not exist. + code: 404 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:8gL/zzInU+rUNJZIhWvPEwEZJyBS73UlXj9r3W0abvc= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:04 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-39storageblobsuitetestdelete/blob/39storageblobsuitetestdeleteblobifexists + method: DELETE + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x72\x72\x6F\x72\x3E\x3C\x43\x6F\x64\x65\x3E\x42\x6C\x6F\x62\x4E\x6F\x74\x46\x6F\x75\x6E\x64\x3C\x2F\x43\x6F\x64\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x3E\x54\x68\x65\x20\x73\x70\x65\x63\x69\x66\x69\x65\x64\x20\x62\x6C\x6F\x62\x20\x64\x6F\x65\x73\x20\x6E\x6F\x74\x20\x65\x78\x69\x73\x74\x2E\n\x52\x65\x71\x75\x65\x73\x74\x49\x64\x3A\x35\x65\x61\x63\x32\x61\x33\x30\x2D\x30\x30\x30\x31\x2D\x30\x30\x64\x38\x2D\x36\x38\x35\x63\x2D\x61\x65\x61\x35\x36\x38\x30\x30\x30\x30\x30\x30\n\x54\x69\x6D\x65\x3A\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x30\x34\x2E\x31\x32\x33\x39\x35\x37\x38\x5A\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x45\x72\x72\x6F\x72\x3E" + headers: + Content-Length: + - "215" + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:03 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2a30-0001-00d8-685c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The specified blob does not exist. + code: 404 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:dXk+vfcAhyD9OXeGwXkjdme/LL3PrlzgZIs3QR2yhKQ= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:04 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-39storageblobsuitetestdelete?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:03 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2a48-0001-00d8-7d5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageBlobSuite/TestDeleteBlobWithConditions.yaml b/storage/recordings/StorageBlobSuite/TestDeleteBlobWithConditions.yaml new file mode 100644 index 000000000000..48a18e3c93d7 --- /dev/null +++ b/storage/recordings/StorageBlobSuite/TestDeleteBlobWithConditions.yaml @@ -0,0 +1,257 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:fYSAc0tS4Aw+88JN5lA5O8ySQeEsCCDMwPzjX/rXDNY= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:04 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-45storageblobsuitetestdelete?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:03 GMT + Etag: + - '"0x8D47C73B991692F"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:04 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2a6a-0001-00d8-1c5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:AJSdzpWCVfcadfNnr5rIV5ozSjl5FcLn1mqk6pFdk+8= + Content-Length: + - "0" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:04 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-45storageblobsuitetestdelete/blob/45storageblobsuitetestdeleteblobwithconditions + method: PUT + response: + body: "" + headers: + Content-Md5: + - 1B2M2Y8AsgTpgAmY7PhCfg== + Date: + - Wed, 05 Apr 2017 22:33:03 GMT + Etag: + - '"0x8D47C73B984F05B"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:04 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2a80-0001-00d8-305c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:3pN9EaZKcClXFhJtcArllXrOwACgZ2FJVTW21NJO+78= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:04 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-45storageblobsuitetestdelete/blob/45storageblobsuitetestdeleteblobwithconditions + method: HEAD + response: + body: "" + headers: + Accept-Ranges: + - bytes + Content-Length: + - "0" + Content-Md5: + - 1B2M2Y8AsgTpgAmY7PhCfg== + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:03 GMT + Etag: + - '"0x8D47C73B984F05B"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:04 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac2a9d-0001-00d8-495c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:SzubFj7cnMkuthWg6xmMmGAQR4X9P/syDCRaCWEhgGI= + If-Match: + - GolangRocksOnAzure + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:04 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-45storageblobsuitetestdelete/blob/45storageblobsuitetestdeleteblobwithconditions + method: DELETE + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x72\x72\x6F\x72\x3E\x3C\x43\x6F\x64\x65\x3E\x43\x6F\x6E\x64\x69\x74\x69\x6F\x6E\x4E\x6F\x74\x4D\x65\x74\x3C\x2F\x43\x6F\x64\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x3E\x54\x68\x65\x20\x63\x6F\x6E\x64\x69\x74\x69\x6F\x6E\x20\x73\x70\x65\x63\x69\x66\x69\x65\x64\x20\x75\x73\x69\x6E\x67\x20\x48\x54\x54\x50\x20\x63\x6F\x6E\x64\x69\x74\x69\x6F\x6E\x61\x6C\x20\x68\x65\x61\x64\x65\x72\x28\x73\x29\x20\x69\x73\x20\x6E\x6F\x74\x20\x6D\x65\x74\x2E\n\x52\x65\x71\x75\x65\x73\x74\x49\x64\x3A\x35\x65\x61\x63\x32\x61\x64\x35\x2D\x30\x30\x30\x31\x2D\x30\x30\x64\x38\x2D\x37\x61\x35\x63\x2D\x61\x65\x61\x35\x36\x38\x30\x30\x30\x30\x30\x30\n\x54\x69\x6D\x65\x3A\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x30\x34\x2E\x33\x39\x33\x31\x34\x32\x39\x5A\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x45\x72\x72\x6F\x72\x3E" + headers: + Content-Length: + - "252" + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:03 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2ad5-0001-00d8-7a5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 412 The condition specified using HTTP conditional header(s) is not met. + code: 412 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:3pN9EaZKcClXFhJtcArllXrOwACgZ2FJVTW21NJO+78= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:04 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-45storageblobsuitetestdelete/blob/45storageblobsuitetestdeleteblobwithconditions + method: HEAD + response: + body: "" + headers: + Accept-Ranges: + - bytes + Content-Length: + - "0" + Content-Md5: + - 1B2M2Y8AsgTpgAmY7PhCfg== + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:03 GMT + Etag: + - '"0x8D47C73B984F05B"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:04 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac2b0c-0001-00d8-2d5c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:LHc/QODeJmXxUdbC8JqYmtg0L+IZa5i/IHgWQmtvFts= + If-Match: + - '"0x8D47C73B984F05B"' + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:04 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-45storageblobsuitetestdelete/blob/45storageblobsuitetestdeleteblobwithconditions + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:04 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2b36-0001-00d8-525c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:89I2qIERjAMfimojoaPc5PugxaLLDvRDl2LutunbZUo= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:04 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-45storageblobsuitetestdelete?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:04 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2b4a-0001-00d8-665c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageBlobSuite/TestGetAndSetBlobMetadata.yaml b/storage/recordings/StorageBlobSuite/TestGetAndSetBlobMetadata.yaml new file mode 100644 index 000000000000..2802dc4dfe7e --- /dev/null +++ b/storage/recordings/StorageBlobSuite/TestGetAndSetBlobMetadata.yaml @@ -0,0 +1,243 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:HliXHpQuIr+Batk2pVHUHstms+V273PG6omJKyD7W9Y= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:04 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-42storageblobsuitetestgetand?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:04 GMT + Etag: + - '"0x8D47C73B9C66537"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:04 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2b7c-0001-00d8-135c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:9lnfDr1zEIVirInwYXh/vM18wIjVPt4AQ6B//6a0rUo= + Content-Length: + - "6" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:04 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-42storageblobsuitetestgetand/blob/142storageblobsuitetestgetandsetblobmetadata + method: PUT + response: + body: "" + headers: + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Date: + - Wed, 05 Apr 2017 22:33:04 GMT + Etag: + - '"0x8D47C73B9B92924"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:04 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2bab-0001-00d8-3c5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:HQB42k73UtfFyuLjkhxDMECTPSZyATSRN7VemwkCAUI= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:04 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-42storageblobsuitetestgetand/blob/142storageblobsuitetestgetandsetblobmetadata?comp=metadata + method: GET + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:04 GMT + Etag: + - '"0x8D47C73B9B92924"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:04 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2bd5-0001-00d8-635c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: Hello! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:agWcquoUjXu7Cvah52a/JgMP54G4xH8y330Y7p9qr9g= + Content-Length: + - "6" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:04 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-42storageblobsuitetestgetand/blob/242storageblobsuitetestgetandsetblobmetadata + method: PUT + response: + body: "" + headers: + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Date: + - Wed, 05 Apr 2017 22:33:04 GMT + Etag: + - '"0x8D47C73B9C7AAB1"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:04 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2bef-0001-00d8-795c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:3BjrlBE9ZeqUIV4rQLpaKKp/7B2GfJRqtkuTrQWf0do= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:04 GMT + X-Ms-Meta-Lol: + - rofl + X-Ms-Meta-Rofl_baz: + - waz qux + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-42storageblobsuitetestgetand/blob/242storageblobsuitetestgetandsetblobmetadata?comp=metadata + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:04 GMT + Etag: + - '"0x8D47C73B9CED7F1"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:04 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2c1b-0001-00d8-205c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:izdVMONsLq69zWUKTOCOLLSb05YD1fj1uUCnjzBWpIE= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:04 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-42storageblobsuitetestgetand/blob/242storageblobsuitetestgetandsetblobmetadata?comp=metadata + method: GET + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:04 GMT + Etag: + - '"0x8D47C73B9CED7F1"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:04 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Meta-Lol: + - rofl + X-Ms-Meta-Rofl_baz: + - waz qux + X-Ms-Request-Id: + - 5eac2c33-0001-00d8-385c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:K7BWaORQ8RkFvvVHUyKEaRrg4djzfpJUxEwdelEiJ1w= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:04 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-42storageblobsuitetestgetand?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:04 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2c4b-0001-00d8-4e5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageBlobSuite/TestGetBlobProperties.yaml b/storage/recordings/StorageBlobSuite/TestGetBlobProperties.yaml new file mode 100644 index 000000000000..c779c917ad92 --- /dev/null +++ b/storage/recordings/StorageBlobSuite/TestGetBlobProperties.yaml @@ -0,0 +1,175 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:/aMWaS2dFJEZNJGcSuViOUfzPef2ZUpgeD3U92j/Hwg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:05 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-38storageblobsuitetestgetblo?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:04 GMT + Etag: + - '"0x8D47C73B9F9B36A"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:04 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2c6a-0001-00d8-685c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:W3NzjgVnrmyJjA8cPbqf/p5LR+TyFsGu32DjARXWP+Q= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:05 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-38storageblobsuitetestgetblo/blob/138storageblobsuitetestgetblobproperties + method: HEAD + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:04 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2c8d-0001-00d8-075c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The specified blob does not exist. + code: 404 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:CwrWIVB3Z7jsnM9uyPXSRb2IpKKajvJ4RicMK5UlBRI= + Content-Length: + - "64" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:05 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-38storageblobsuitetestgetblo/blob/238storageblobsuitetestgetblobproperties + method: PUT + response: + body: "" + headers: + Content-Md5: + - k5xcYcwrRU0Jp851wBBhJg== + Date: + - Wed, 05 Apr 2017 22:33:04 GMT + Etag: + - '"0x8D47C73B9F3A49E"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:04 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2cad-0001-00d8-235c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:FzWuTkmxE4vu7bYoCcJ1Lqz0ARR5HhGsfiY/AZJsIwE= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:05 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-38storageblobsuitetestgetblo/blob/238storageblobsuitetestgetblobproperties + method: HEAD + response: + body: "" + headers: + Accept-Ranges: + - bytes + Content-Length: + - "64" + Content-Md5: + - k5xcYcwrRU0Jp851wBBhJg== + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:04 GMT + Etag: + - '"0x8D47C73B9F3A49E"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:04 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac2cca-0001-00d8-3d5c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:xd4tWwfwPL5s9t3qRWG4jEOb7ftlL/J2J6XjCurknUk= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:05 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-38storageblobsuitetestgetblo?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:04 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2cda-0001-00d8-4c5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageBlobSuite/TestGetBlobRange.yaml b/storage/recordings/StorageBlobSuite/TestGetBlobRange.yaml new file mode 100644 index 000000000000..c61350bb1119 --- /dev/null +++ b/storage/recordings/StorageBlobSuite/TestGetBlobRange.yaml @@ -0,0 +1,287 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:9nu8qK4mFGC/UbUgj//IsZH4NainTKsjMiM8DO8A7Uk= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:05 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-33storageblobsuitetestgetblo?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:04 GMT + Etag: + - '"0x8D47C73BA218DA4"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:05 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2cf9-0001-00d8-665c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "0123456789" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:avRKkLQKSRGQRUT0nQoWpYyobsr5W+aJVLl8j122A70= + Content-Length: + - "10" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:05 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-33storageblobsuitetestgetblo/blob/33storageblobsuitetestgetblobrange + method: PUT + response: + body: "" + headers: + Content-Md5: + - eB5eJF1ptWaXm4bijSPyxw== + Date: + - Wed, 05 Apr 2017 22:33:04 GMT + Etag: + - '"0x8D47C73BA1451F6"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:05 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2d0c-0001-00d8-785c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:lFVzR4t40cNBijPob1rFkS/ZA9xlAaNDJurdN6+CHOk= + Range: + - bytes=0-10 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:05 GMT + X-Ms-Range-Get-Content-Md5: + - "false" + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-33storageblobsuitetestgetblo/blob/33storageblobsuitetestgetblobrange + method: GET + response: + body: "0123456789" + headers: + Accept-Ranges: + - bytes + Content-Length: + - "10" + Content-Range: + - bytes 0-9/10 + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:04 GMT + Etag: + - '"0x8D47C73BA1451F6"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:05 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Content-Md5: + - eB5eJF1ptWaXm4bijSPyxw== + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac2d1d-0001-00d8-065c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 206 Partial Content + code: 206 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:oEk8/ERI3igcGa9njGqs+roCTHkYuUaK2MiydYMO9a4= + Range: + - bytes=1-3 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:05 GMT + X-Ms-Range-Get-Content-Md5: + - "false" + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-33storageblobsuitetestgetblo/blob/33storageblobsuitetestgetblobrange + method: GET + response: + body: "123" + headers: + Accept-Ranges: + - bytes + Content-Length: + - "3" + Content-Range: + - bytes 1-3/10 + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:04 GMT + Etag: + - '"0x8D47C73BA1451F6"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:05 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Content-Md5: + - eB5eJF1ptWaXm4bijSPyxw== + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac2d3e-0001-00d8-225c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 206 Partial Content + code: 206 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:MbL6csYCAxYabbcUsptWzsxpx+l04t0e8xku6v0ULSQ= + Range: + - bytes=3-10 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:05 GMT + X-Ms-Range-Get-Content-Md5: + - "false" + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-33storageblobsuitetestgetblo/blob/33storageblobsuitetestgetblobrange + method: GET + response: + body: "3456789" + headers: + Accept-Ranges: + - bytes + Content-Length: + - "7" + Content-Range: + - bytes 3-9/10 + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:04 GMT + Etag: + - '"0x8D47C73BA1451F6"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:05 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Content-Md5: + - eB5eJF1ptWaXm4bijSPyxw== + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac2d4b-0001-00d8-2f5c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 206 Partial Content + code: 206 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:OGcfBLsvzDc8wWTIGpBzxsmOZGUDL8/T+HIgSUcHkWU= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:05 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-33storageblobsuitetestgetblo/blob/33storageblobsuitetestgetblobrange + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:05 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2d57-0001-00d8-3a5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:aP7h0bJk2tRp12fcdHneFnVlWRhaS45ir7+Tqv3Bs2I= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:05 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-33storageblobsuitetestgetblo?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:05 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2d6a-0001-00d8-4a5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageBlobSuite/TestMetadataCaseMunging.yaml b/storage/recordings/StorageBlobSuite/TestMetadataCaseMunging.yaml new file mode 100644 index 000000000000..b5e03c87b52b --- /dev/null +++ b/storage/recordings/StorageBlobSuite/TestMetadataCaseMunging.yaml @@ -0,0 +1,173 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:eynfs+QloEhoyfjXWPhjenVYqxOwVGaVaMtUV7n8LmI= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:05 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40storageblobsuitetestmetada?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:05 GMT + Etag: + - '"0x8D47C73BA58378E"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:05 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2d7c-0001-00d8-595c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:iKmxay9pGw/Qi1TDUapSfbmReOvJ6KnC4G7AYytjyFk= + Content-Length: + - "6" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:05 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40storageblobsuitetestmetada/blob/40storageblobsuitetestmetadatacasemunging + method: PUT + response: + body: "" + headers: + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Date: + - Wed, 05 Apr 2017 22:33:05 GMT + Etag: + - '"0x8D47C73BA4AFC1B"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:05 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2d90-0001-00d8-6b5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:fxkZ9YdeAw6WI7UJSYEPkS2PBZErF6meDnGPyDTo/sg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:05 GMT + X-Ms-Meta-Lol: + - different rofl + X-Ms-Meta-Rofl_baz: + - different waz qux + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40storageblobsuitetestmetada/blob/40storageblobsuitetestmetadatacasemunging?comp=metadata + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:05 GMT + Etag: + - '"0x8D47C73BA558551"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:05 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2dba-0001-00d8-0d5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:4KsPkofVcu8LLMk/WfruMS8zDV9yi7NaKHrM9eiOpAg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:05 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40storageblobsuitetestmetada/blob/40storageblobsuitetestmetadatacasemunging?comp=metadata + method: GET + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:05 GMT + Etag: + - '"0x8D47C73BA558551"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:05 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Meta-Lol: + - different rofl + X-Ms-Meta-Rofl_baz: + - different waz qux + X-Ms-Request-Id: + - 5eac2dd2-0001-00d8-215c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:PHr64tjU6Rufx3kOOECaW6z1pnNuLTLtOLtwR9TY4/k= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:05 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-40storageblobsuitetestmetada?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:05 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2de3-0001-00d8-325c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageBlobSuite/TestPutAppendBlobSpecialChars.yaml b/storage/recordings/StorageBlobSuite/TestPutAppendBlobSpecialChars.yaml new file mode 100644 index 000000000000..cbbfe3d2bfe5 --- /dev/null +++ b/storage/recordings/StorageBlobSuite/TestPutAppendBlobSpecialChars.yaml @@ -0,0 +1,385 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:2ao4Kve4KRx0SCBjExBTe18/5GdwK2aCW7pV6/JHBt8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:05 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-46storageblobsuitetestputapp?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:05 GMT + Etag: + - '"0x8D47C73BA7FC3DF"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:05 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2dfa-0001-00d8-445c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:fnCKYjgpmOIsHxaLF1f2j5PKwcrUfZwlNQPwxXsxA2o= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - AppendBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:05 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-46storageblobsuitetestputapp/blob/46storageblobsuitetestputappendblobspecialchars + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:05 GMT + Etag: + - '"0x8D47C73BA72AF7E"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:05 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2e0d-0001-00d8-555c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:2xH0SrxqtqUgBFlkqkBoAoko+QIiAhS7FH064J5NppI= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:06 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-46storageblobsuitetestputapp/blob/46storageblobsuitetestputappendblobspecialchars + method: HEAD + response: + body: "" + headers: + Accept-Ranges: + - bytes + Content-Length: + - "0" + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:05 GMT + Etag: + - '"0x8D47C73BA72AF7E"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:05 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Committed-Block-Count: + - "0" + X-Ms-Blob-Type: + - AppendBlob + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac2e1e-0001-00d8-605c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit + volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:dl0675kE/yEj148989t9RZqQMBaZ+qvM40tMkMl/PWY= + Content-Length: + - "1024" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - AppendBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:06 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-46storageblobsuitetestputapp/blob/46storageblobsuitetestputappendblobspecialchars?comp=appendblock + method: PUT + response: + body: "" + headers: + Content-Md5: + - 0rZVY1m4cHz874drfCSd/w== + Date: + - Wed, 05 Apr 2017 22:33:05 GMT + Etag: + - '"0x8D47C73BA8109F5"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:05 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Append-Offset: + - "0" + X-Ms-Blob-Committed-Block-Count: + - "1" + X-Ms-Request-Id: + - 5eac2e33-0001-00d8-745c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Fac2D1PXWkOoM9BXNMtd1q2XiPy/wxA4fGqQUX9U+7A= + Range: + - bytes=0-1023 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:06 GMT + X-Ms-Range-Get-Content-Md5: + - "false" + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-46storageblobsuitetestputapp/blob/46storageblobsuitetestputappendblobspecialchars + method: GET + response: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit + volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + headers: + Accept-Ranges: + - bytes + Content-Length: + - "1024" + Content-Range: + - bytes 0-1023/1024 + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:05 GMT + Etag: + - '"0x8D47C73BA8109F5"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:05 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Committed-Block-Count: + - "1" + X-Ms-Blob-Type: + - AppendBlob + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac2e48-0001-00d8-075c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 206 Partial Content + code: 206 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:NiMS1aNfg6mwJD8pFpPEBOnMbXncHiaa6sJPKEwovLw= + Content-Length: + - "512" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - AppendBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:06 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-46storageblobsuitetestputapp/blob/46storageblobsuitetestputappendblobspecialchars?comp=appendblock + method: PUT + response: + body: "" + headers: + Content-Md5: + - 2Xr7q2sERdQmQ41hZ7sPvQ== + Date: + - Wed, 05 Apr 2017 22:33:05 GMT + Etag: + - '"0x8D47C73BA8FD9B4"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:05 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Append-Offset: + - "1024" + X-Ms-Blob-Committed-Block-Count: + - "2" + X-Ms-Request-Id: + - 5eac2e5b-0001-00d8-185c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Pz4jDCxWQnc8y20sFQVxSd9tOOOFhLL7so/QOSXjhM0= + Range: + - bytes=0-1535 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:06 GMT + X-Ms-Range-Get-Content-Md5: + - "false" + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-46storageblobsuitetestputapp/blob/46storageblobsuitetestputappendblobspecialchars + method: GET + response: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit + volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio.Lorem ipsum + dolor sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac + headers: + Accept-Ranges: + - bytes + Content-Length: + - "1536" + Content-Range: + - bytes 0-1535/1536 + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:05 GMT + Etag: + - '"0x8D47C73BA8FD9B4"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:05 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Committed-Block-Count: + - "2" + X-Ms-Blob-Type: + - AppendBlob + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac2e78-0001-00d8-325c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 206 Partial Content + code: 206 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:65J7qO+A9I+XOCHLooRUlpvd/rZwCAZNfIO1MuL9sOg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:06 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-46storageblobsuitetestputapp?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:05 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2e8c-0001-00d8-455c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageBlobSuite/TestSetBlobProperties.yaml b/storage/recordings/StorageBlobSuite/TestSetBlobProperties.yaml new file mode 100644 index 000000000000..57a5548664bf --- /dev/null +++ b/storage/recordings/StorageBlobSuite/TestSetBlobProperties.yaml @@ -0,0 +1,195 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:3n/WNWbfJpcChNPRMIGkjYxwlhin9qmXXMraWmbfBhA= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:06 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-38storageblobsuitetestsetblo?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:05 GMT + Etag: + - '"0x8D47C73BAC64EFF"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:06 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2eb5-0001-00d8-6a5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:gf9hPJP/TiWtEblCDNb7gf2v6jg3E8y4iA+Kc2JX7VI= + Content-Length: + - "6" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:06 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-38storageblobsuitetestsetblo/blob/38storageblobsuitetestsetblobproperties + method: PUT + response: + body: "" + headers: + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Date: + - Wed, 05 Apr 2017 22:33:05 GMT + Etag: + - '"0x8D47C73BABAC1FA"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:06 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2ed3-0001-00d8-7d5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:1PHcKZFwoXLL5IF5n/e+1+D3+UCP/3pLPyP7zUzBT74= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Cache-Control: + - private, max-age=0, no-cache + X-Ms-Blob-Content-Encoding: + - gzip + X-Ms-Blob-Content-Language: + - de-DE + X-Ms-Blob-Content-Md5: + - oBATU+oaDduHWbVZLuzIJw== + X-Ms-Blob-Content-Type: + - application/json + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:06 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-38storageblobsuitetestsetblo/blob/38storageblobsuitetestsetblobproperties?comp=properties + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:05 GMT + Etag: + - '"0x8D47C73BAC34F09"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:06 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2eed-0001-00d8-125c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:xAjyeGUdRx9UTUDt7T4X+TDXEbE64uhGa/+wudQz0jc= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:06 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-38storageblobsuitetestsetblo/blob/38storageblobsuitetestsetblobproperties + method: HEAD + response: + body: "" + headers: + Accept-Ranges: + - bytes + Cache-Control: + - private, max-age=0, no-cache + Content-Encoding: + - gzip + Content-Language: + - de-DE + Content-Length: + - "6" + Content-Md5: + - oBATU+oaDduHWbVZLuzIJw== + Content-Type: + - application/json + Date: + - Wed, 05 Apr 2017 22:33:05 GMT + Etag: + - '"0x8D47C73BAC34F09"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:06 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac2efe-0001-00d8-1f5c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:TVol7vCEmCjaSySrTiCblrG82dO7YZDD8TiIgxEk1RI= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:06 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-38storageblobsuitetestsetblo?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:06 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2f05-0001-00d8-255c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageBlobSuite/TestSetMetadataWithExtraHeaders.yaml b/storage/recordings/StorageBlobSuite/TestSetMetadataWithExtraHeaders.yaml new file mode 100644 index 000000000000..15c26096ec46 --- /dev/null +++ b/storage/recordings/StorageBlobSuite/TestSetMetadataWithExtraHeaders.yaml @@ -0,0 +1,224 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:40BVGSszBHNZ8MOHKSMyc32iEgAxT0qC99YBpedNm88= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:06 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-48storageblobsuitetestsetmet?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:06 GMT + Etag: + - '"0x8D47C73BAF221D5"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:06 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2f1f-0001-00d8-395c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:cir0pEjgllnjmBnoUYB/xHyJph1kqkjnNBN5nFuLkJo= + Content-Length: + - "6" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:06 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-48storageblobsuitetestsetmet/blob/48storageblobsuitetestsetmetadatawithextraheaders + method: PUT + response: + body: "" + headers: + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Date: + - Wed, 05 Apr 2017 22:33:06 GMT + Etag: + - '"0x8D47C73BAE4E6D6"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:06 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2f37-0001-00d8-4f5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:9c/O1liGOdL434WUxTORCkZqYUcoQLMpmncb3375urI= + If-Match: + - incorrect-etag + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:06 GMT + X-Ms-Meta-Lol: + - rofl + X-Ms-Meta-Rofl_baz: + - waz qux + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-48storageblobsuitetestsetmet/blob/48storageblobsuitetestsetmetadatawithextraheaders?comp=metadata + method: PUT + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x72\x72\x6F\x72\x3E\x3C\x43\x6F\x64\x65\x3E\x43\x6F\x6E\x64\x69\x74\x69\x6F\x6E\x4E\x6F\x74\x4D\x65\x74\x3C\x2F\x43\x6F\x64\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x3E\x54\x68\x65\x20\x63\x6F\x6E\x64\x69\x74\x69\x6F\x6E\x20\x73\x70\x65\x63\x69\x66\x69\x65\x64\x20\x75\x73\x69\x6E\x67\x20\x48\x54\x54\x50\x20\x63\x6F\x6E\x64\x69\x74\x69\x6F\x6E\x61\x6C\x20\x68\x65\x61\x64\x65\x72\x28\x73\x29\x20\x69\x73\x20\x6E\x6F\x74\x20\x6D\x65\x74\x2E\n\x52\x65\x71\x75\x65\x73\x74\x49\x64\x3A\x35\x65\x61\x63\x32\x66\x34\x35\x2D\x30\x30\x30\x31\x2D\x30\x30\x64\x38\x2D\x35\x63\x35\x63\x2D\x61\x65\x61\x35\x36\x38\x30\x30\x30\x30\x30\x30\n\x54\x69\x6D\x65\x3A\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x30\x36\x2E\x36\x35\x32\x36\x39\x36\x36\x5A\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x45\x72\x72\x6F\x72\x3E" + headers: + Content-Length: + - "252" + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:06 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2f45-0001-00d8-5c5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 412 The condition specified using HTTP conditional header(s) is not met. + code: 412 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:QM1FScZh7DHN82PNXMUuOEUqrlP9r8zBMlWwuazZphM= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:06 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-48storageblobsuitetestsetmet/blob/48storageblobsuitetestsetmetadatawithextraheaders + method: HEAD + response: + body: "" + headers: + Accept-Ranges: + - bytes + Content-Length: + - "6" + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:06 GMT + Etag: + - '"0x8D47C73BAE4E6D6"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:06 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Lease-State: + - available + X-Ms-Lease-Status: + - unlocked + X-Ms-Request-Id: + - 5eac2f58-0001-00d8-6b5c-aea568000000 + X-Ms-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:mff0xqcyXafnzJfxkSHj5m3/CMNeVfZ6Ho+50YyHhzw= + If-Match: + - '"0x8D47C73BAE4E6D6"' + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:06 GMT + X-Ms-Meta-Lol: + - rofl + X-Ms-Meta-Rofl_baz: + - waz qux + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-48storageblobsuitetestsetmet/blob/48storageblobsuitetestsetmetadatawithextraheaders?comp=metadata + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:06 GMT + Etag: + - '"0x8D47C73BAF983FD"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:06 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2f69-0001-00d8-785c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:/N2DamQNENQELKCKHdWFOvykDtGsagB9iACvL+D61Ds= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:06 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-48storageblobsuitetestsetmet?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:06 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2f79-0001-00d8-065c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageBlobSuite/TestSnapshotBlob.yaml b/storage/recordings/StorageBlobSuite/TestSnapshotBlob.yaml new file mode 100644 index 000000000000..23c1d782cba9 --- /dev/null +++ b/storage/recordings/StorageBlobSuite/TestSnapshotBlob.yaml @@ -0,0 +1,134 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:t/6lGvVsTn3KMnvombcBYcC3RDsOiFLPLX/6FkX2Ln0= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:06 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-33storageblobsuitetestsnapsh?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:06 GMT + Etag: + - '"0x8D47C73BB1F7B32"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:06 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2f91-0001-00d8-1a5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:nBRLgh4UtfVzqhnCUvaxW6/Ls8rTKtNRht+RnT9dZSs= + Content-Length: + - "6" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:07 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-33storageblobsuitetestsnapsh/blob/33storageblobsuitetestsnapshotblob + method: PUT + response: + body: "" + headers: + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Date: + - Wed, 05 Apr 2017 22:33:06 GMT + Etag: + - '"0x8D47C73BB1240AC"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:06 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2fa1-0001-00d8-285c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:a54mDfK452/6GRV8ZSWnnCosonI4JsVjUeVjHfChu7U= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:07 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-33storageblobsuitetestsnapsh/blob/33storageblobsuitetestsnapshotblob?comp=snapshot + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:06 GMT + Etag: + - '"0x8D47C73BB1240AC"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:06 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2fae-0001-00d8-345c-aea568000000 + X-Ms-Snapshot: + - 2017-04-05T22:33:06.8171721Z + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:r33Sno/uEd+E2lclVrZoxJ+w5xrqt09vou+rsiGGzm8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:07 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-33storageblobsuitetestsnapsh?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:06 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2fb6-0001-00d8-3b5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageBlobSuite/TestSnapshotBlobWithInvalidLease.yaml b/storage/recordings/StorageBlobSuite/TestSnapshotBlobWithInvalidLease.yaml new file mode 100644 index 000000000000..823354f0a7bb --- /dev/null +++ b/storage/recordings/StorageBlobSuite/TestSnapshotBlobWithInvalidLease.yaml @@ -0,0 +1,171 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:VRwnbdOX1jTByBKMqlEuh6U7JKAWMVQFwP0Gaa/+HTc= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:07 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-49storageblobsuitetestsnapsh?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:06 GMT + Etag: + - '"0x8D47C73BB3EEF9F"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:07 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2fbe-0001-00d8-435c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:yweof7P7pv6iaVFAk/4wsIYKcvI11ET/p8lxA2s5jhY= + Content-Length: + - "6" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:07 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-49storageblobsuitetestsnapsh/blob/49storageblobsuitetestsnapshotblobwithinvalidlease + method: PUT + response: + body: "" + headers: + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Date: + - Wed, 05 Apr 2017 22:33:06 GMT + Etag: + - '"0x8D47C73BB31B519"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:06 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2fcc-0001-00d8-4f5c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:ZaV6Pp+VdB+caRCZtbmYYYTagicl7NwTGDcDfOag/Vs= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:07 GMT + X-Ms-Lease-Action: + - acquire + X-Ms-Lease-Duration: + - "30" + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-49storageblobsuitetestsnapsh/blob/49storageblobsuitetestsnapshotblobwithinvalidlease?comp=lease + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:06 GMT + Etag: + - '"0x8D47C73BB31B519"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:06 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Lease-Id: + - b1e514c2-44ab-4851-82a6-69d01591013b + X-Ms-Request-Id: + - 5eac2fe6-0001-00d8-685c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:nT/qzeEWTPPzHM1uwBgu5wWC3/DPzafdWYw+oOg9Rps= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:07 GMT + X-Ms-Lease-Id: + - GolangRocksOnAzure + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-49storageblobsuitetestsnapsh/blob/49storageblobsuitetestsnapshotblobwithinvalidlease?comp=snapshot + method: PUT + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x72\x72\x6F\x72\x3E\x3C\x43\x6F\x64\x65\x3E\x49\x6E\x76\x61\x6C\x69\x64\x48\x65\x61\x64\x65\x72\x56\x61\x6C\x75\x65\x3C\x2F\x43\x6F\x64\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x3E\x54\x68\x65\x20\x76\x61\x6C\x75\x65\x20\x66\x6F\x72\x20\x6F\x6E\x65\x20\x6F\x66\x20\x74\x68\x65\x20\x48\x54\x54\x50\x20\x68\x65\x61\x64\x65\x72\x73\x20\x69\x73\x20\x6E\x6F\x74\x20\x69\x6E\x20\x74\x68\x65\x20\x63\x6F\x72\x72\x65\x63\x74\x20\x66\x6F\x72\x6D\x61\x74\x2E\n\x52\x65\x71\x75\x65\x73\x74\x49\x64\x3A\x35\x65\x61\x63\x32\x66\x65\x62\x2D\x30\x30\x30\x31\x2D\x30\x30\x64\x38\x2D\x36\x64\x35\x63\x2D\x61\x65\x61\x35\x36\x38\x30\x30\x30\x30\x30\x30\n\x54\x69\x6D\x65\x3A\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x30\x37\x2E\x36\x32\x31\x33\x36\x32\x37\x5A\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x48\x65\x61\x64\x65\x72\x4E\x61\x6D\x65\x3E\x78\x2D\x6D\x73\x2D\x6C\x65\x61\x73\x65\x2D\x69\x64\x3C\x2F\x48\x65\x61\x64\x65\x72\x4E\x61\x6D\x65\x3E\x3C\x48\x65\x61\x64\x65\x72\x56\x61\x6C\x75\x65\x3E\x47\x6F\x6C\x61\x6E\x67\x52\x6F\x63\x6B\x73\x4F\x6E\x41\x7A\x75\x72\x65\x3C\x2F\x48\x65\x61\x64\x65\x72\x56\x61\x6C\x75\x65\x3E\x3C\x2F\x45\x72\x72\x6F\x72\x3E" + headers: + Content-Length: + - "337" + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:07 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac2feb-0001-00d8-6d5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 400 The value for one of the HTTP headers is not in the correct format. + code: 400 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:bBmN7Q8P9kdcW60ksS90JCVN1JfaR/6iQtBR0/8cVy8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:07 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-49storageblobsuitetestsnapsh?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:07 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac304f-0001-00d8-405c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageBlobSuite/TestSnapshotBlobWithTimeout.yaml b/storage/recordings/StorageBlobSuite/TestSnapshotBlobWithTimeout.yaml new file mode 100644 index 000000000000..738bfa099f1b --- /dev/null +++ b/storage/recordings/StorageBlobSuite/TestSnapshotBlobWithTimeout.yaml @@ -0,0 +1,134 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:/36xrr7lid7Gn1zxyrX0yKAtmx/aEqC6sPdFum2uZ34= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:07 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-44storageblobsuitetestsnapsh?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:07 GMT + Etag: + - '"0x8D47C73BBA47A0B"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:07 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac305e-0001-00d8-4b5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:gXUc4ZmfDlm5v3EvYbWkJTNrnrDGOGOOPf5zxRYXrQc= + Content-Length: + - "6" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:07 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-44storageblobsuitetestsnapsh/blob/44storageblobsuitetestsnapshotblobwithtimeout + method: PUT + response: + body: "" + headers: + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Date: + - Wed, 05 Apr 2017 22:33:07 GMT + Etag: + - '"0x8D47C73BB9718E2"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:07 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac306b-0001-00d8-565c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:LmJi8C9LIZ3BJ5gzso4ygJEWg9vDqKmYbU8A7mFRWP0= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:07 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-44storageblobsuitetestsnapsh/blob/44storageblobsuitetestsnapshotblobwithtimeout?comp=snapshot + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:07 GMT + Etag: + - '"0x8D47C73BB9718E2"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:07 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3077-0001-00d8-5e5c-aea568000000 + X-Ms-Snapshot: + - 2017-04-05T22:33:07.6897863Z + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:9WvC2wMB2jvf9HDD7U56WnQrkYoNv/zR2Ue0Tiarfbc= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:07 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-44storageblobsuitetestsnapsh?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:07 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3080-0001-00d8-665c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageBlobSuite/TestSnapshotBlobWithValidLease.yaml b/storage/recordings/StorageBlobSuite/TestSnapshotBlobWithValidLease.yaml new file mode 100644 index 000000000000..985048a2017a --- /dev/null +++ b/storage/recordings/StorageBlobSuite/TestSnapshotBlobWithValidLease.yaml @@ -0,0 +1,173 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:rOa5aUpPbxkhd0REVDTeurhK5Hzkdh2G6twgB7PSZCw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:08 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-47storageblobsuitetestsnapsh?restype=container + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:07 GMT + Etag: + - '"0x8D47C73BBC3EE79"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:07 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3097-0001-00d8-785c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Hello! + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:7hrzUlCnXjsDu2RPxmi1h5uv5Fgtw0kxCKS0I6RiexM= + Content-Length: + - "6" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Blob-Type: + - BlockBlob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:08 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-47storageblobsuitetestsnapsh/blob/47storageblobsuitetestsnapshotblobwithvalidlease + method: PUT + response: + body: "" + headers: + Content-Md5: + - lS0sVtBIWVgzZ0e83ZhZDQ== + Date: + - Wed, 05 Apr 2017 22:33:07 GMT + Etag: + - '"0x8D47C73BBB6B480"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:07 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac30a0-0001-00d8-805c-aea568000000 + X-Ms-Request-Server-Encrypted: + - "false" + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:nTiqzpUIkpVAh7O+FoQ0aPAG+y52d9PPfMCQo1I01o4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:08 GMT + X-Ms-Lease-Action: + - acquire + X-Ms-Lease-Duration: + - "30" + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-47storageblobsuitetestsnapsh/blob/47storageblobsuitetestsnapshotblobwithvalidlease?comp=lease + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:07 GMT + Etag: + - '"0x8D47C73BBB6B480"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:07 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Lease-Id: + - 121cfe12-766a-49e1-b7a3-bed76b3cbd3d + X-Ms-Request-Id: + - 5eac30af-0001-00d8-0c5c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:kDx+bys2954/Y4BcKbL9ZflnG0TMo014TWmXANbbYM4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:08 GMT + X-Ms-Lease-Id: + - 121cfe12-766a-49e1-b7a3-bed76b3cbd3d + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-47storageblobsuitetestsnapsh/blob/47storageblobsuitetestsnapshotblobwithvalidlease?comp=snapshot + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:07 GMT + Etag: + - '"0x8D47C73BBB6B480"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:07 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac30bb-0001-00d8-175c-aea568000000 + X-Ms-Snapshot: + - 2017-04-05T22:33:07.9479684Z + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:NiQYc55mbRai38UlfoQiG45eurheNzxuCvkDtnTTkP4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:08 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-47storageblobsuitetestsnapsh?restype=container + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:07 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac30ca-0001-00d8-235c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageClientSuite/TestReturnsStorageServiceError.yaml b/storage/recordings/StorageClientSuite/TestReturnsStorageServiceError.yaml new file mode 100644 index 000000000000..7ded39a83d6d --- /dev/null +++ b/storage/recordings/StorageClientSuite/TestReturnsStorageServiceError.yaml @@ -0,0 +1,35 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:i5PsVDNHkZelQiUqDDtTy5YvX5gbppXW8zly6qs6umE= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:09 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/cnt-49storageclientsuitetestretu?restype=container + method: DELETE + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x72\x72\x6F\x72\x3E\x3C\x43\x6F\x64\x65\x3E\x43\x6F\x6E\x74\x61\x69\x6E\x65\x72\x4E\x6F\x74\x46\x6F\x75\x6E\x64\x3C\x2F\x43\x6F\x64\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x3E\x54\x68\x65\x20\x73\x70\x65\x63\x69\x66\x69\x65\x64\x20\x63\x6F\x6E\x74\x61\x69\x6E\x65\x72\x20\x64\x6F\x65\x73\x20\x6E\x6F\x74\x20\x65\x78\x69\x73\x74\x2E\n\x52\x65\x71\x75\x65\x73\x74\x49\x64\x3A\x35\x65\x61\x63\x33\x33\x36\x32\x2D\x30\x30\x30\x31\x2D\x30\x30\x64\x38\x2D\x36\x38\x35\x63\x2D\x61\x65\x61\x35\x36\x38\x30\x30\x30\x30\x30\x30\n\x54\x69\x6D\x65\x3A\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x30\x39\x2E\x37\x31\x31\x38\x30\x30\x31\x5A\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x45\x72\x72\x6F\x72\x3E" + headers: + Content-Length: + - "225" + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:09 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3362-0001-00d8-685c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The specified container does not exist. + code: 404 diff --git a/storage/recordings/StorageClientSuite/TestReturnsStorageServiceError_withoutResponseBody.yaml b/storage/recordings/StorageClientSuite/TestReturnsStorageServiceError_withoutResponseBody.yaml new file mode 100644 index 000000000000..29933e92b3e3 --- /dev/null +++ b/storage/recordings/StorageClientSuite/TestReturnsStorageServiceError_withoutResponseBody.yaml @@ -0,0 +1,31 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:jhE7vl6hTbiqyG2bNxYWdLFVIm3pUg3HLAQaznj7hLs= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 blob + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:09 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.blob.core.windows.net/non-existing-container/non-existing-blob + method: HEAD + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:09 GMT + Server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5eac3370-0001-00d8-735c-aea568000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The specified container does not exist. + code: 404 diff --git a/storage/recordings/StorageClientSuite/Test_doRetry.yaml b/storage/recordings/StorageClientSuite/Test_doRetry.yaml new file mode 100644 index 000000000000..914090c5eebe --- /dev/null +++ b/storage/recordings/StorageClientSuite/Test_doRetry.yaml @@ -0,0 +1,94 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Prefer: + - return-no-content + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/%28retry%29?timeout=30 + method: DELETE + response: + body: '{"odata.error":{"code":"ResourceNotFound","message":{"lang":"en-US","value":"The + specified resource does not exist.\nRequestId:26d67dd8-0002-0096-0fff-ba608d000000\nTime:2017-04-22T00:30:49.2979671Z"}}}' + headers: + Content-Length: + - "202" + Content-Type: + - application/json + Date: + - Sat, 22 Apr 2017 00:30:49 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 26d67dd8-0002-0096-0fff-ba608d000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The specified resource does not exist. + code: 404 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Prefer: + - return-no-content + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/%28retry%29?timeout=30 + method: DELETE + response: + body: '{"odata.error":{"code":"ResourceNotFound","message":{"lang":"en-US","value":"The + specified resource does not exist.\nRequestId:26d67f51-0002-0096-6fff-ba608d000000\nTime:2017-04-22T00:30:50.3507139Z"}}}' + headers: + Content-Length: + - "202" + Content-Type: + - application/json + Date: + - Sat, 22 Apr 2017 00:30:50 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 26d67f51-0002-0096-6fff-ba608d000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The specified resource does not exist. + code: 404 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Prefer: + - return-no-content + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/%28retry%29?timeout=30 + method: DELETE + response: + body: '{"odata.error":{"code":"ResourceNotFound","message":{"lang":"en-US","value":"The + specified resource does not exist.\nRequestId:26d68106-0002-0096-19ff-ba608d000000\nTime:2017-04-22T00:30:52.4141773Z"}}}' + headers: + Content-Length: + - "202" + Content-Type: + - application/json + Date: + - Sat, 22 Apr 2017 00:30:52 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 26d68106-0002-0096-19ff-ba608d000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The specified resource does not exist. + code: 404 diff --git a/storage/recordings/StorageDirSuite/TestCreateDirectory.yaml b/storage/recordings/StorageDirSuite/TestCreateDirectory.yaml new file mode 100644 index 000000000000..885340674310 --- /dev/null +++ b/storage/recordings/StorageDirSuite/TestCreateDirectory.yaml @@ -0,0 +1,147 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:GulbdY+hpNZFChI+5JxYluaQQNotmt8Xj2CwTezlwWE= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:15 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-35storagedirsuitetestcreatedirectory?restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:15 GMT + Etag: + - '"0x8D47C73C04EF93F"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:15 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271c2-001a-00eb-3a5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:5fKvC67bWTZ+GJcdWXaAmX0HH+okYWgFKUAO7593m3A= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:15 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-35storagedirsuitetestcreatedirectory/dir?restype=directory + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:15 GMT + Etag: + - '"0x8D47C73C03EE83B"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:15 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271c6-001a-00eb-3b5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:nd2gmiCfN39oXhxOI92zh8EwtFoOxR9x8nmsQDRqqIs= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:16 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-35storagedirsuitetestcreatedirectory/dir?restype=directory + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:15 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271c7-001a-00eb-3c5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:txfgRb6jfOCu4dTb+DViWej+Qg33QmEKIsTzlEWSKfM= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:16 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-35storagedirsuitetestcreatedirectory/dir?restype=directory + method: HEAD + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:15 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271c8-001a-00eb-3d5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The specified resource does not exist. + code: 404 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:ZMbnzTQYOxbPyGxWvOPZCvNXaCPKHg0ZTdyct6SKtn8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:16 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-35storagedirsuitetestcreatedirectory?restype=share + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:15 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271c9-001a-00eb-3e5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageDirSuite/TestCreateDirectoryIfExists.yaml b/storage/recordings/StorageDirSuite/TestCreateDirectoryIfExists.yaml new file mode 100644 index 000000000000..1daac683a734 --- /dev/null +++ b/storage/recordings/StorageDirSuite/TestCreateDirectoryIfExists.yaml @@ -0,0 +1,93 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:+DHC4mQ3p1YEQToiPQcpqgJHVmQT7AlqjLCBlRmDgXU= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:16 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-43storagedirsuitetestcreatedirectoryifexists/dir?restype=directory + method: PUT + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x72\x72\x6F\x72\x3E\x3C\x43\x6F\x64\x65\x3E\x52\x65\x73\x6F\x75\x72\x63\x65\x41\x6C\x72\x65\x61\x64\x79\x45\x78\x69\x73\x74\x73\x3C\x2F\x43\x6F\x64\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x3E\x54\x68\x65\x20\x73\x70\x65\x63\x69\x66\x69\x65\x64\x20\x72\x65\x73\x6F\x75\x72\x63\x65\x20\x61\x6C\x72\x65\x61\x64\x79\x20\x65\x78\x69\x73\x74\x73\x2E\n\x52\x65\x71\x75\x65\x73\x74\x49\x64\x3A\x35\x61\x30\x32\x37\x31\x63\x64\x2D\x30\x30\x31\x61\x2D\x30\x30\x65\x62\x2D\x34\x31\x35\x63\x2D\x61\x65\x66\x63\x34\x35\x30\x30\x30\x30\x30\x30\n\x54\x69\x6D\x65\x3A\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x31\x36\x2E\x30\x34\x34\x30\x34\x30\x36\x5A\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x45\x72\x72\x6F\x72\x3E" + headers: + Content-Length: + - "228" + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:15 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271cd-001a-00eb-415c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 409 The specified resource already exists. + code: 409 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:rdgEL7QEXj/tE05FaJl+wQhA1bAgnyrof7iUkSdIPPE= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:16 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-43storagedirsuitetestcreatedirectoryifexists/dir?restype=directory + method: HEAD + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:15 GMT + Etag: + - '"0x8D47C73C06897BD"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:15 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271ce-001a-00eb-425c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:2uJUfMlpGLvqNZW80dcp4EV4zRJdA08gMknZo5NxpiE= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:16 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-43storagedirsuitetestcreatedirectoryifexists/dir?restype=directory + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:15 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271cf-001a-00eb-435c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageDirSuite/TestCreateDirectoryIfNotExists.yaml b/storage/recordings/StorageDirSuite/TestCreateDirectoryIfNotExists.yaml new file mode 100644 index 000000000000..e8c138950f2c --- /dev/null +++ b/storage/recordings/StorageDirSuite/TestCreateDirectoryIfNotExists.yaml @@ -0,0 +1,147 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:tYBoYwo3k7dAKh/B7W96IZ+d+xB5g+iVh3xdPRBWlmk= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:16 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-46storagedirsuitetestcreatedirectoryifnotexists?restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:16 GMT + Etag: + - '"0x8D47C73C0BAEE4B"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:16 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271d2-001a-00eb-455c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:yqBUdHpb4BpuM1sQeSNALKx/HcpzHLwCobsibr7G718= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:16 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-46storagedirsuitetestcreatedirectoryifnotexists/dir?restype=directory + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:16 GMT + Etag: + - '"0x8D47C73C0A07A9E"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:16 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271d4-001a-00eb-465c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Xi6pByko4gk5Mu7z8ccJZUNn3X3OC2dgf84LmeR49mk= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:16 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-46storagedirsuitetestcreatedirectoryifnotexists/dir?restype=directory + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:16 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271d5-001a-00eb-475c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:IDpcjwC+vpa2cSlJpQ+BqnVwJBFz+SOYxApJ8FgZhfs= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:16 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-46storagedirsuitetestcreatedirectoryifnotexists/dir?restype=directory + method: HEAD + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:16 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271d6-001a-00eb-485c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The specified resource does not exist. + code: 404 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:BnMuOTlnT6oFVN4Ybr0gmnUos+1QghtRcgGsUsFH1NU= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:16 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-46storagedirsuitetestcreatedirectoryifnotexists?restype=share + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:16 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271d7-001a-00eb-495c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageDirSuite/TestDirectoryMetadata.yaml b/storage/recordings/StorageDirSuite/TestDirectoryMetadata.yaml new file mode 100644 index 000000000000..aaa421d16a45 --- /dev/null +++ b/storage/recordings/StorageDirSuite/TestDirectoryMetadata.yaml @@ -0,0 +1,163 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:BrJbysAiS1Y3Y2r4XrnJptRRsWJ02L42cNtIHjfiKu8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:16 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-37storagedirsuitetestdirectorymetadata?restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:16 GMT + Etag: + - '"0x8D47C73C0E9F630"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:16 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271d8-001a-00eb-4a5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:L3J+hND1frw7PXZz2ifODNvOCEVqkuR6h3I81o6VKfI= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:16 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-37storagedirsuitetestdirectorymetadata/testdir?restype=directory + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:16 GMT + Etag: + - '"0x8D47C73C0CAC6B3"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:16 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271da-001a-00eb-4b5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:VXZuu+PHRaP7f+C4LNa8nXHL6xi3SFCN1H2BsjyhudA= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:16 GMT + X-Ms-Meta-Another: + - anothervalue + X-Ms-Meta-Something: + - somethingvalue + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-37storagedirsuitetestdirectorymetadata/testdir?comp=metadata&restype=directory + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:16 GMT + Etag: + - '"0x8D47C73C0D21AD0"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:16 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271db-001a-00eb-4c5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:GOZmcikGAEV7dl0mkf1+MDS+2c5R8U/CGTzcQhfmLM8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:16 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-37storagedirsuitetestdirectorymetadata/testdir?restype=directory + method: HEAD + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:16 GMT + Etag: + - '"0x8D47C73C0D21AD0"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:16 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Meta-Another: + - anothervalue + X-Ms-Meta-Something: + - somethingvalue + X-Ms-Request-Id: + - 5a0271dc-001a-00eb-4d5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:rlO59A34pNIgDBova2ILjc2uZo+fNP5UkYViZX9wYCo= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:17 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-37storagedirsuitetestdirectorymetadata?restype=share + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:16 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271dd-001a-00eb-4e5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageDirSuite/TestListDirsAndFiles.yaml b/storage/recordings/StorageDirSuite/TestListDirsAndFiles.yaml new file mode 100644 index 000000000000..58e3ca37f220 --- /dev/null +++ b/storage/recordings/StorageDirSuite/TestListDirsAndFiles.yaml @@ -0,0 +1,211 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:UsA0tzil/ple4ocjDcEGBnTKf8QFPGF2+6rGTusTSpA= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:17 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-36storagedirsuitetestlistdirsandfiles?restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:16 GMT + Etag: + - '"0x8D47C73C1149074"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:16 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271de-001a-00eb-4f5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:2MqkziX1OPi9+m/tB8sjKYdM6zXcroO05YKa1MF/tp0= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:17 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-36storagedirsuitetestlistdirsandfiles/SomeDirectory?restype=directory + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:16 GMT + Etag: + - '"0x8D47C73C0F4C43C"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:16 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271e0-001a-00eb-505c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:bcKBoBGTKBUqthEFBjwSArM9h00cELTXNegIcvgATIk= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Content-Length: + - "512" + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:17 GMT + X-Ms-Type: + - file + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-36storagedirsuitetestlistdirsandfiles/lol.file + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:16 GMT + Etag: + - '"0x8D47C73C0FD5140"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:16 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271e1-001a-00eb-515c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:eOmPk0HGKbXg1c+85Z8ioz+V9RajVFAZbTV9dyNOIR4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:17 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-36storagedirsuitetestlistdirsandfiles?comp=list&restype=directory + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x20\x53\x65\x72\x76\x69\x63\x65\x45\x6E\x64\x70\x6F\x69\x6E\x74\x3D\"\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x6F\x6C\x61\x6E\x67\x72\x6F\x63\x6B\x73\x6F\x6E\x61\x7A\x75\x72\x65\x2E\x66\x69\x6C\x65\x2E\x63\x6F\x72\x65\x2E\x77\x69\x6E\x64\x6F\x77\x73\x2E\x6E\x65\x74\x2F\"\x20\x53\x68\x61\x72\x65\x4E\x61\x6D\x65\x3D\"\x73\x68\x61\x72\x65\x2D\x33\x36\x73\x74\x6F\x72\x61\x67\x65\x64\x69\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x64\x69\x72\x73\x61\x6E\x64\x66\x69\x6C\x65\x73\"\x20\x44\x69\x72\x65\x63\x74\x6F\x72\x79\x50\x61\x74\x68\x3D\"\"\x3E\x3C\x45\x6E\x74\x72\x69\x65\x73\x3E\x3C\x46\x69\x6C\x65\x3E\x3C\x4E\x61\x6D\x65\x3E\x6C\x6F\x6C\x2E\x66\x69\x6C\x65\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x35\x31\x32\x3C\x2F\x43\x6F\x6E\x74\x65\x6E\x74\x2D\x4C\x65\x6E\x67\x74\x68\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x2F\x46\x69\x6C\x65\x3E\x3C\x44\x69\x72\x65\x63\x74\x6F\x72\x79\x3E\x3C\x4E\x61\x6D\x65\x3E\x53\x6F\x6D\x65\x44\x69\x72\x65\x63\x74\x6F\x72\x79\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x20\x2F\x3E\x3C\x2F\x44\x69\x72\x65\x63\x74\x6F\x72\x79\x3E\x3C\x2F\x45\x6E\x74\x72\x69\x65\x73\x3E\x3C\x4E\x65\x78\x74\x4D\x61\x72\x6B\x65\x72\x20\x2F\x3E\x3C\x2F\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:16 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271e2-001a-00eb-525c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:LCFilQhLUV52r5Pa4vFBZewKe0GZlSFOMxhsQOuLsLQ= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:17 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-36storagedirsuitetestlistdirsandfiles/lol.file + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:16 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271e3-001a-00eb-535c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:mBXNzcMj42D+Vqkvw8ftsnsxr0bW8QDVcXWt2BcmxcA= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:17 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-36storagedirsuitetestlistdirsandfiles/lol.file + method: HEAD + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:16 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271e4-001a-00eb-545c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The specified resource does not exist. + code: 404 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:19/BCSDRuJzPJjXk5r7NnZJH71NHsX8cib3WFtdGD88= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:17 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-36storagedirsuitetestlistdirsandfiles?restype=share + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:16 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271e5-001a-00eb-555c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageDirSuite/TestListZeroDirsAndFiles.yaml b/storage/recordings/StorageDirSuite/TestListZeroDirsAndFiles.yaml new file mode 100644 index 000000000000..a750cc67b3e7 --- /dev/null +++ b/storage/recordings/StorageDirSuite/TestListZeroDirsAndFiles.yaml @@ -0,0 +1,91 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:J7EQc6v6ghrWiYlcB4ZRwRwKR/N2XNwZRKZPiC4xLmQ= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:17 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-40storagedirsuitetestlistzerodirsandfiles?restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:17 GMT + Etag: + - '"0x8D47C73C154B275"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:17 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271e6-001a-00eb-565c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:xtv289Fz9PdX300mQvbchETBLSytltqePWFJyFlN1CM= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:17 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-40storagedirsuitetestlistzerodirsandfiles?comp=list&restype=directory + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x20\x53\x65\x72\x76\x69\x63\x65\x45\x6E\x64\x70\x6F\x69\x6E\x74\x3D\"\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x6F\x6C\x61\x6E\x67\x72\x6F\x63\x6B\x73\x6F\x6E\x61\x7A\x75\x72\x65\x2E\x66\x69\x6C\x65\x2E\x63\x6F\x72\x65\x2E\x77\x69\x6E\x64\x6F\x77\x73\x2E\x6E\x65\x74\x2F\"\x20\x53\x68\x61\x72\x65\x4E\x61\x6D\x65\x3D\"\x73\x68\x61\x72\x65\x2D\x34\x30\x73\x74\x6F\x72\x61\x67\x65\x64\x69\x72\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x7A\x65\x72\x6F\x64\x69\x72\x73\x61\x6E\x64\x66\x69\x6C\x65\x73\"\x20\x44\x69\x72\x65\x63\x74\x6F\x72\x79\x50\x61\x74\x68\x3D\"\"\x3E\x3C\x45\x6E\x74\x72\x69\x65\x73\x20\x2F\x3E\x3C\x4E\x65\x78\x74\x4D\x61\x72\x6B\x65\x72\x20\x2F\x3E\x3C\x2F\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:17 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271e8-001a-00eb-575c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:FCpO/4dpP0h0X6qP7x21s8kL/Q5AdeqauPw9ZwZ6c6I= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:17 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-40storagedirsuitetestlistzerodirsandfiles?restype=share + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:17 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271e9-001a-00eb-585c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageEntitySuite/TestDelete.yaml b/storage/recordings/StorageEntitySuite/TestDelete.yaml new file mode 100644 index 000000000000..547a3f83b0ef --- /dev/null +++ b/storage/recordings/StorageEntitySuite/TestDelete.yaml @@ -0,0 +1,308 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: | + {"TableName":"table29storageentitysuitetestdel"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:TIhEod8E8k9KRsCo/MH+I2wy3r17uZ+MLDvUMto9/Y4= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:17 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table29storageentitysuitetestdel') + Date: + - Wed, 05 Apr 2017 22:33:17 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table29storageentitysuitetestdel') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b51a-0002-0064-705c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: '{"PartitionKey":"pkey1","RowKey":"rowkey1"}' + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:bGwrhQWrDakoX9OemzzPI4S5a6umnPcnIjvs4nVMQHM= + Content-Length: + - "43" + Content-Type: + - application/json + Prefer: + - return-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:17 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table29storageentitysuitetestdel + method: POST + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table29storageentitysuitetestdel/@Element","odata.type":"golangrocksonazure.table29storageentitysuitetestdel","odata.id":"https://golangrocksonazure.table.core.windows.net/table29storageentitysuitetestdel(PartitionKey=''pkey1'',RowKey=''rowkey1'')","odata.etag":"W/\"datetime''2017-04-05T22%3A33%3A17.7938773Z''\"","odata.editLink":"table29storageentitysuitetestdel(PartitionKey=''pkey1'',RowKey=''rowkey1'')","PartitionKey":"pkey1","RowKey":"rowkey1","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-05T22:33:17.7938773Z"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:17 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A17.7938773Z'" + Location: + - https://golangrocksonazure.table.core.windows.net/table29storageentitysuitetestdel(PartitionKey='pkey1',RowKey='rowkey1') + Preference-Applied: + - return-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b52c-0002-0064-7f5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:x+4ONgglyIS5RSax94v2q8fsbQTedePs7wWVZWISATk= + If-Match: + - W/"datetime'2017-04-05T22%3A33%3A17.7938773Z'" + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:17 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table29storageentitysuitetestdel%28PartitionKey=%27pkey1%27,%20RowKey=%27rowkey1%27%29 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:17 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b54f-0002-0064-1e5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: '{"PartitionKey":"pkey2","RowKey":"rowkey2"}' + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:bGwrhQWrDakoX9OemzzPI4S5a6umnPcnIjvs4nVMQHM= + Content-Length: + - "43" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:17 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table29storageentitysuitetestdel + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/table29storageentitysuitetestdel(PartitionKey='pkey2',RowKey='rowkey2') + Date: + - Wed, 05 Apr 2017 22:33:17 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A18.0160373Z'" + Location: + - https://golangrocksonazure.table.core.windows.net/table29storageentitysuitetestdel(PartitionKey='pkey2',RowKey='rowkey2') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b567-0002-0064-345c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:daT23oPoAmFDAKMb+I/blIAiR7Vm8MiUa8qiSOXp7Os= + If-Match: + - GolangRocksOnAzure + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:18 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table29storageentitysuitetestdel%28PartitionKey=%27pkey2%27,%20RowKey=%27rowkey2%27%29 + method: DELETE + response: + body: '{"odata.error":{"code":"InvalidInput","message":{"lang":"en-US","value":"The + etag value ''GolangRocksOnAzure'' specified in one of the request headers is + not valid. Please make sure only one etag value is specified and is valid.\nRequestId:ab33b580-0002-0064-4d5c-aeb219000000\nTime:2017-04-05T22:33:18.0930922Z"}}}' + headers: + Content-Type: + - application/json;odata=nometadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:17 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b580-0002-0064-4d5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 400 Bad Request + code: 400 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:daT23oPoAmFDAKMb+I/blIAiR7Vm8MiUa8qiSOXp7Os= + If-Match: + - '*' + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:18 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table29storageentitysuitetestdel%28PartitionKey=%27pkey2%27,%20RowKey=%27rowkey2%27%29 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:17 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b595-0002-0064-625c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:BsZecuKMss+n2Nh/d+jY7x+ZBaqT5h0ncuEKVU3Dk7U= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:18 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table29storageentitysuitetestdel%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:18 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b5a5-0002-0064-725c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageEntitySuite/TestExecuteQueryNextResults.yaml b/storage/recordings/StorageEntitySuite/TestExecuteQueryNextResults.yaml new file mode 100644 index 000000000000..9ef87a9058ed --- /dev/null +++ b/storage/recordings/StorageEntitySuite/TestExecuteQueryNextResults.yaml @@ -0,0 +1,449 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: | + {"TableName":"table46storageentitysuitetestexe"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:CbzLvQ0Zo3EfZLidzftTwfpAW89mhR3CUAsyG1eKQgo= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:18 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table46storageentitysuitetestexe') + Date: + - Wed, 05 Apr 2017 22:33:18 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table46storageentitysuitetestexe') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b5b3-0002-0064-805c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: '{"PartitionKey":"pkey","RowKey":"r0"}' + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:C9gMBXO0Hj1IHssTT9YrYmQZqM9l5jxXL3TEeSleXRk= + Content-Length: + - "37" + Content-Type: + - application/json + Prefer: + - return-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:18 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table46storageentitysuitetestexe + method: POST + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table46storageentitysuitetestexe/@Element","odata.type":"golangrocksonazure.table46storageentitysuitetestexe","odata.id":"https://golangrocksonazure.table.core.windows.net/table46storageentitysuitetestexe(PartitionKey=''pkey'',RowKey=''r0'')","odata.etag":"W/\"datetime''2017-04-05T22%3A33%3A18.3012418Z''\"","odata.editLink":"table46storageentitysuitetestexe(PartitionKey=''pkey'',RowKey=''r0'')","PartitionKey":"pkey","RowKey":"r0","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-05T22:33:18.3012418Z"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:18 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A18.3012418Z'" + Location: + - https://golangrocksonazure.table.core.windows.net/table46storageentitysuitetestexe(PartitionKey='pkey',RowKey='r0') + Preference-Applied: + - return-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b5c3-0002-0064-0f5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: '{"PartitionKey":"pkey","RowKey":"r1"}' + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:C9gMBXO0Hj1IHssTT9YrYmQZqM9l5jxXL3TEeSleXRk= + Content-Length: + - "37" + Content-Type: + - application/json + Prefer: + - return-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:18 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table46storageentitysuitetestexe + method: POST + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table46storageentitysuitetestexe/@Element","odata.type":"golangrocksonazure.table46storageentitysuitetestexe","odata.id":"https://golangrocksonazure.table.core.windows.net/table46storageentitysuitetestexe(PartitionKey=''pkey'',RowKey=''r1'')","odata.etag":"W/\"datetime''2017-04-05T22%3A33%3A18.3702918Z''\"","odata.editLink":"table46storageentitysuitetestexe(PartitionKey=''pkey'',RowKey=''r1'')","PartitionKey":"pkey","RowKey":"r1","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-05T22:33:18.3702918Z"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:18 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A18.3702918Z'" + Location: + - https://golangrocksonazure.table.core.windows.net/table46storageentitysuitetestexe(PartitionKey='pkey',RowKey='r1') + Preference-Applied: + - return-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b5ca-0002-0064-165c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: '{"PartitionKey":"pkey","RowKey":"r2"}' + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:C9gMBXO0Hj1IHssTT9YrYmQZqM9l5jxXL3TEeSleXRk= + Content-Length: + - "37" + Content-Type: + - application/json + Prefer: + - return-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:18 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table46storageentitysuitetestexe + method: POST + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table46storageentitysuitetestexe/@Element","odata.type":"golangrocksonazure.table46storageentitysuitetestexe","odata.id":"https://golangrocksonazure.table.core.windows.net/table46storageentitysuitetestexe(PartitionKey=''pkey'',RowKey=''r2'')","odata.etag":"W/\"datetime''2017-04-05T22%3A33%3A18.43734Z''\"","odata.editLink":"table46storageentitysuitetestexe(PartitionKey=''pkey'',RowKey=''r2'')","PartitionKey":"pkey","RowKey":"r2","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-05T22:33:18.43734Z"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:18 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A18.43734Z'" + Location: + - https://golangrocksonazure.table.core.windows.net/table46storageentitysuitetestexe(PartitionKey='pkey',RowKey='r2') + Preference-Applied: + - return-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b5db-0002-0064-275c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: '{"PartitionKey":"pkey","RowKey":"r3"}' + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:C9gMBXO0Hj1IHssTT9YrYmQZqM9l5jxXL3TEeSleXRk= + Content-Length: + - "37" + Content-Type: + - application/json + Prefer: + - return-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:18 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table46storageentitysuitetestexe + method: POST + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table46storageentitysuitetestexe/@Element","odata.type":"golangrocksonazure.table46storageentitysuitetestexe","odata.id":"https://golangrocksonazure.table.core.windows.net/table46storageentitysuitetestexe(PartitionKey=''pkey'',RowKey=''r3'')","odata.etag":"W/\"datetime''2017-04-05T22%3A33%3A18.4873759Z''\"","odata.editLink":"table46storageentitysuitetestexe(PartitionKey=''pkey'',RowKey=''r3'')","PartitionKey":"pkey","RowKey":"r3","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-05T22:33:18.4873759Z"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:18 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A18.4873759Z'" + Location: + - https://golangrocksonazure.table.core.windows.net/table46storageentitysuitetestexe(PartitionKey='pkey',RowKey='r3') + Preference-Applied: + - return-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b5e7-0002-0064-335c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: '{"PartitionKey":"pkey","RowKey":"r4"}' + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:C9gMBXO0Hj1IHssTT9YrYmQZqM9l5jxXL3TEeSleXRk= + Content-Length: + - "37" + Content-Type: + - application/json + Prefer: + - return-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:18 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table46storageentitysuitetestexe + method: POST + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table46storageentitysuitetestexe/@Element","odata.type":"golangrocksonazure.table46storageentitysuitetestexe","odata.id":"https://golangrocksonazure.table.core.windows.net/table46storageentitysuitetestexe(PartitionKey=''pkey'',RowKey=''r4'')","odata.etag":"W/\"datetime''2017-04-05T22%3A33%3A18.5364111Z''\"","odata.editLink":"table46storageentitysuitetestexe(PartitionKey=''pkey'',RowKey=''r4'')","PartitionKey":"pkey","RowKey":"r4","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-05T22:33:18.5364111Z"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:18 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A18.5364111Z'" + Location: + - https://golangrocksonazure.table.core.windows.net/table46storageentitysuitetestexe(PartitionKey='pkey',RowKey='r4') + Preference-Applied: + - return-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b5f2-0002-0064-3e5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Authorization: + - SharedKey golangrocksonazure:NIr5u1aJ08WoVtptkmKnk8ZgpqxzT07IXMxBr3unxIY= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:18 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table46storageentitysuitetestexe?%24top=2&timeout=30 + method: GET + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table46storageentitysuitetestexe","value":[{"odata.type":"golangrocksonazure.table46storageentitysuitetestexe","odata.id":"https://golangrocksonazure.table.core.windows.net/table46storageentitysuitetestexe(PartitionKey=''pkey'',RowKey=''r0'')","odata.etag":"W/\"datetime''2017-04-05T22%3A33%3A18.3012418Z''\"","odata.editLink":"table46storageentitysuitetestexe(PartitionKey=''pkey'',RowKey=''r0'')","PartitionKey":"pkey","RowKey":"r0","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-05T22:33:18.3012418Z"},{"odata.type":"golangrocksonazure.table46storageentitysuitetestexe","odata.id":"https://golangrocksonazure.table.core.windows.net/table46storageentitysuitetestexe(PartitionKey=''pkey'',RowKey=''r1'')","odata.etag":"W/\"datetime''2017-04-05T22%3A33%3A18.3702918Z''\"","odata.editLink":"table46storageentitysuitetestexe(PartitionKey=''pkey'',RowKey=''r1'')","PartitionKey":"pkey","RowKey":"r1","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-05T22:33:18.3702918Z"}]}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:18 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Continuation-Nextpartitionkey: + - 1!8!cGtleQ-- + X-Ms-Continuation-Nextrowkey: + - 1!4!cjI- + X-Ms-Request-Id: + - ab33b5f9-0002-0064-455c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Authorization: + - SharedKey golangrocksonazure:NIr5u1aJ08WoVtptkmKnk8ZgpqxzT07IXMxBr3unxIY= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:18 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table46storageentitysuitetestexe?%24top=2&NextPartitionKey=1%218%21cGtleQ--&NextRowKey=1%214%21cjI-&timeout=30 + method: GET + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table46storageentitysuitetestexe","value":[{"odata.type":"golangrocksonazure.table46storageentitysuitetestexe","odata.id":"https://golangrocksonazure.table.core.windows.net/table46storageentitysuitetestexe(PartitionKey=''pkey'',RowKey=''r2'')","odata.etag":"W/\"datetime''2017-04-05T22%3A33%3A18.43734Z''\"","odata.editLink":"table46storageentitysuitetestexe(PartitionKey=''pkey'',RowKey=''r2'')","PartitionKey":"pkey","RowKey":"r2","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-05T22:33:18.43734Z"},{"odata.type":"golangrocksonazure.table46storageentitysuitetestexe","odata.id":"https://golangrocksonazure.table.core.windows.net/table46storageentitysuitetestexe(PartitionKey=''pkey'',RowKey=''r3'')","odata.etag":"W/\"datetime''2017-04-05T22%3A33%3A18.4873759Z''\"","odata.editLink":"table46storageentitysuitetestexe(PartitionKey=''pkey'',RowKey=''r3'')","PartitionKey":"pkey","RowKey":"r3","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-05T22:33:18.4873759Z"}]}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:18 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Continuation-Nextpartitionkey: + - 1!8!cGtleQ-- + X-Ms-Continuation-Nextrowkey: + - 1!4!cjQ- + X-Ms-Request-Id: + - ab33b60c-0002-0064-575c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Authorization: + - SharedKey golangrocksonazure:NIr5u1aJ08WoVtptkmKnk8ZgpqxzT07IXMxBr3unxIY= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:18 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table46storageentitysuitetestexe?%24top=2&NextPartitionKey=1%218%21cGtleQ--&NextRowKey=1%214%21cjQ-&timeout=30 + method: GET + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table46storageentitysuitetestexe","value":[{"odata.type":"golangrocksonazure.table46storageentitysuitetestexe","odata.id":"https://golangrocksonazure.table.core.windows.net/table46storageentitysuitetestexe(PartitionKey=''pkey'',RowKey=''r4'')","odata.etag":"W/\"datetime''2017-04-05T22%3A33%3A18.5364111Z''\"","odata.editLink":"table46storageentitysuitetestexe(PartitionKey=''pkey'',RowKey=''r4'')","PartitionKey":"pkey","RowKey":"r4","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-05T22:33:18.5364111Z"}]}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:18 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b61f-0002-0064-6a5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:H5VmkvkkuCMaqu4gU3PPY9s5lHdfOw9QOV/n/yVj0gI= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:18 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table46storageentitysuitetestexe%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:18 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b629-0002-0064-745c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageEntitySuite/TestGet.yaml b/storage/recordings/StorageEntitySuite/TestGet.yaml new file mode 100644 index 000000000000..a20ab5b67b13 --- /dev/null +++ b/storage/recordings/StorageEntitySuite/TestGet.yaml @@ -0,0 +1,253 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: | + {"TableName":"table26storageentitysuitetestget"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:WSKjrlxzsHVqJxVBAM3GHKdqJuaffs6+cjliU1X7+rc= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Fri, 21 Apr 2017 19:01:28 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table26storageentitysuitetestget') + Date: + - Fri, 21 Apr 2017 19:01:29 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table26storageentitysuitetestget') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 01dca395-0002-0077-53d1-ba87f8000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: '{"AmountDue":200.23,"CustomerCode":"c9da6455-213d-42c9-9a79-3e9149a57833","CustomerCode@odata.type":"Edm.Guid","CustomerSince":"1992-12-20T21:55:00Z","CustomerSince@odata.type":"Edm.DateTime","IsActive":true,"NumberOfOrders":"255","NumberOfOrders@odata.type":"Edm.Int64","PartitionKey":"mypartitionkey","RowKey":"myrowkey"}' + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:wcHFp+gr7ZpvZFiASYHDhBYHrlGYf6fYfsMJ3s4tNI0= + Content-Length: + - "323" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Fri, 21 Apr 2017 19:01:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table26storageentitysuitetestget + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/table26storageentitysuitetestget(PartitionKey='mypartitionkey',RowKey='myrowkey') + Date: + - Fri, 21 Apr 2017 19:01:29 GMT + Etag: + - W/"datetime'2017-04-21T19%3A01%3A30.1231644Z'" + Location: + - https://golangrocksonazure.table.core.windows.net/table26storageentitysuitetestget(PartitionKey='mypartitionkey',RowKey='myrowkey') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 01dca3bc-0002-0077-74d1-ba87f8000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Authorization: + - SharedKey golangrocksonazure:TXUHWsilHY7Ef/c17zf5K7yTAYVBJauUBGKNBcSGjHU= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Fri, 21 Apr 2017 19:01:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table26storageentitysuitetestget%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29?%24select=IsActive&timeout=30 + method: GET + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table26storageentitysuitetestget/@Element&$select=IsActive","odata.type":"golangrocksonazure.table26storageentitysuitetestget","odata.id":"https://golangrocksonazure.table.core.windows.net/table26storageentitysuitetestget(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')","odata.etag":"W/\"datetime''2017-04-21T19%3A01%3A30.1231644Z''\"","odata.editLink":"table26storageentitysuitetestget(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')","IsActive":true}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Fri, 21 Apr 2017 19:01:29 GMT + Etag: + - W/"datetime'2017-04-21T19%3A01%3A30.1231644Z'" + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 01dca3c5-0002-0077-7bd1-ba87f8000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Authorization: + - SharedKey golangrocksonazure:TXUHWsilHY7Ef/c17zf5K7yTAYVBJauUBGKNBcSGjHU= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Fri, 21 Apr 2017 19:01:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table26storageentitysuitetestget%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29?%24select=AmountDue%2CCustomerCode%2CCustomerSince%2CIsActive%2CNumberOfOrders&timeout=30 + method: GET + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table26storageentitysuitetestget/@Element&$select=AmountDue,CustomerCode,CustomerSince,IsActive,NumberOfOrders","odata.type":"golangrocksonazure.table26storageentitysuitetestget","odata.id":"https://golangrocksonazure.table.core.windows.net/table26storageentitysuitetestget(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')","odata.etag":"W/\"datetime''2017-04-21T19%3A01%3A30.1231644Z''\"","odata.editLink":"table26storageentitysuitetestget(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')","AmountDue":200.23,"CustomerCode@odata.type":"Edm.Guid","CustomerCode":"c9da6455-213d-42c9-9a79-3e9149a57833","CustomerSince@odata.type":"Edm.DateTime","CustomerSince":"1992-12-20T21:55:00Z","IsActive":true,"NumberOfOrders@odata.type":"Edm.Int64","NumberOfOrders":"255"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Fri, 21 Apr 2017 19:01:29 GMT + Etag: + - W/"datetime'2017-04-21T19%3A01%3A30.1231644Z'" + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 01dca3dc-0002-0077-0ed1-ba87f8000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Authorization: + - SharedKey golangrocksonazure:TXUHWsilHY7Ef/c17zf5K7yTAYVBJauUBGKNBcSGjHU= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Fri, 21 Apr 2017 19:01:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table26storageentitysuitetestget%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29?timeout=30 + method: GET + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table26storageentitysuitetestget/@Element","odata.type":"golangrocksonazure.table26storageentitysuitetestget","odata.id":"https://golangrocksonazure.table.core.windows.net/table26storageentitysuitetestget(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')","odata.etag":"W/\"datetime''2017-04-21T19%3A01%3A30.1231644Z''\"","odata.editLink":"table26storageentitysuitetestget(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')","PartitionKey":"mypartitionkey","RowKey":"myrowkey","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-21T19:01:30.1231644Z","AmountDue":200.23,"CustomerCode@odata.type":"Edm.Guid","CustomerCode":"c9da6455-213d-42c9-9a79-3e9149a57833","CustomerSince@odata.type":"Edm.DateTime","CustomerSince":"1992-12-20T21:55:00Z","IsActive":true,"NumberOfOrders@odata.type":"Edm.Int64","NumberOfOrders":"255"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Fri, 21 Apr 2017 19:01:29 GMT + Etag: + - W/"datetime'2017-04-21T19%3A01%3A30.1231644Z'" + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 01dca3e3-0002-0077-15d1-ba87f8000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:voKWr7ShBYDaJfiGJ6tEcHNivtP4arHfBkOIVbL250w= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Fri, 21 Apr 2017 19:01:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table26storageentitysuitetestget%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Fri, 21 Apr 2017 19:01:29 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 01dca3f2-0002-0077-24d1-ba87f8000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageEntitySuite/TestInsert.yaml b/storage/recordings/StorageEntitySuite/TestInsert.yaml new file mode 100644 index 000000000000..d03a18a9e7d7 --- /dev/null +++ b/storage/recordings/StorageEntitySuite/TestInsert.yaml @@ -0,0 +1,191 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: | + {"TableName":"table29storageentitysuitetestins"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:CbzLvQ0Zo3EfZLidzftTwfpAW89mhR3CUAsyG1eKQgo= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:18 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table29storageentitysuitetestins') + Date: + - Wed, 05 Apr 2017 22:33:18 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table29storageentitysuitetestins') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b63b-0002-0064-065c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: '{"AmountDue":200.23,"CustomerCode":"c9da6455-213d-42c9-9a79-3e9149a57833","CustomerCode@odata.type":"Edm.Guid","CustomerSince":"1992-12-20T21:55:00Z","CustomerSince@odata.type":"Edm.DateTime","IsActive":true,"NumberOfOrders":"255","NumberOfOrders@odata.type":"Edm.Int64","PartitionKey":"mypartitionkey","RowKey":"myrowkey"}' + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:/Dn0LgUZt9W1pbmoI+/0QJAfgOZfhnWzpQVpPvlPP9o= + Content-Length: + - "323" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:18 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table29storageentitysuitetestins + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/table29storageentitysuitetestins(PartitionKey='mypartitionkey',RowKey='myrowkey') + Date: + - Wed, 05 Apr 2017 22:33:18 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A18.8786566Z'" + Location: + - https://golangrocksonazure.table.core.windows.net/table29storageentitysuitetestins(PartitionKey='mypartitionkey',RowKey='myrowkey') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b64b-0002-0064-145c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: '{"AmountDue":200.23,"CustomerCode":"c9da6455-213d-42c9-9a79-3e9149a57833","CustomerCode@odata.type":"Edm.Guid","CustomerSince":"1992-12-20T21:55:00Z","CustomerSince@odata.type":"Edm.DateTime","IsActive":true,"NumberOfOrders":"255","NumberOfOrders@odata.type":"Edm.Int64","PartitionKey":"mypartitionkey2","RowKey":"myrowkey2"}' + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:/Dn0LgUZt9W1pbmoI+/0QJAfgOZfhnWzpQVpPvlPP9o= + Content-Length: + - "325" + Content-Type: + - application/json + Prefer: + - return-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:18 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table29storageentitysuitetestins + method: POST + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table29storageentitysuitetestins/@Element","odata.type":"golangrocksonazure.table29storageentitysuitetestins","odata.id":"https://golangrocksonazure.table.core.windows.net/table29storageentitysuitetestins(PartitionKey=''mypartitionkey2'',RowKey=''myrowkey2'')","odata.etag":"W/\"datetime''2017-04-05T22%3A33%3A18.9246901Z''\"","odata.editLink":"table29storageentitysuitetestins(PartitionKey=''mypartitionkey2'',RowKey=''myrowkey2'')","PartitionKey":"mypartitionkey2","RowKey":"myrowkey2","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-05T22:33:18.9246901Z","AmountDue":200.23,"CustomerCode@odata.type":"Edm.Guid","CustomerCode":"c9da6455-213d-42c9-9a79-3e9149a57833","CustomerSince@odata.type":"Edm.DateTime","CustomerSince":"1992-12-20T21:55:00Z","IsActive":true,"NumberOfOrders@odata.type":"Edm.Int64","NumberOfOrders":"255"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:18 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A18.9246901Z'" + Location: + - https://golangrocksonazure.table.core.windows.net/table29storageentitysuitetestins(PartitionKey='mypartitionkey2',RowKey='myrowkey2') + Preference-Applied: + - return-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b656-0002-0064-1f5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:Nc9bEHZ5fnbetPsoAhMDW2q/vnPPGOb8SJC01T3gZrc= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:18 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table29storageentitysuitetestins%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:18 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b667-0002-0064-305c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageEntitySuite/TestInsertOrMerge.yaml b/storage/recordings/StorageEntitySuite/TestInsertOrMerge.yaml new file mode 100644 index 000000000000..a07d6c16635c --- /dev/null +++ b/storage/recordings/StorageEntitySuite/TestInsertOrMerge.yaml @@ -0,0 +1,185 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: | + {"TableName":"table36storageentitysuitetestins"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:CbzLvQ0Zo3EfZLidzftTwfpAW89mhR3CUAsyG1eKQgo= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:18 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table36storageentitysuitetestins') + Date: + - Wed, 05 Apr 2017 22:33:18 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table36storageentitysuitetestins') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b675-0002-0064-3e5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: '{"FamilyName":"Skywalker","Name":"Luke","PartitionKey":"mypartitionkey","RowKey":"myrowkey"}' + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:6UkRcHL+noxsQ33uo6MPHx6utOF2ppkprQ9iQF18NUk= + Content-Length: + - "92" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:19 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table36storageentitysuitetestins%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29 + method: MERGE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:18 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A18.8099292Z'" + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b682-0002-0064-4a5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: '{"Father":"Anakin","Mentor":"Yoda","PartitionKey":"mypartitionkey","RowKey":"myrowkey"}' + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:6UkRcHL+noxsQ33uo6MPHx6utOF2ppkprQ9iQF18NUk= + Content-Length: + - "87" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:19 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table36storageentitysuitetestins%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29 + method: MERGE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:18 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A18.8579615Z'" + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b691-0002-0064-595c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:l8d2SSaA5ME/otMGZ0k3XfZb3+gNKdEwWWm8+seOKsY= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:19 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table36storageentitysuitetestins%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:19 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b69c-0002-0064-635c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageEntitySuite/TestInsertOrReplace.yaml b/storage/recordings/StorageEntitySuite/TestInsertOrReplace.yaml new file mode 100644 index 000000000000..959b746fea6d --- /dev/null +++ b/storage/recordings/StorageEntitySuite/TestInsertOrReplace.yaml @@ -0,0 +1,185 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: | + {"TableName":"table38storageentitysuitetestins"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:UApC6hOOGveWssOXfwZxX0XEiTH43zQgc7hFaxaEnHI= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:19 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table38storageentitysuitetestins') + Date: + - Wed, 05 Apr 2017 22:33:19 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table38storageentitysuitetestins') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b6a7-0002-0064-6e5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: '{"FamilyName":"Skywalker","HasEpicTheme":true,"Name":"Anakin","PartitionKey":"mypartitionkey","RowKey":"myrowkey"}' + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:SdmKhX1o5pDblpgZUJf+NkW2kma6tavc7HIRCnNqdKk= + Content-Length: + - "114" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:19 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table38storageentitysuitetestins%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29 + method: PUT + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:19 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A19.0270829Z'" + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b6ba-0002-0064-7e5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: '{"FamilyName":"Organa","HasAwesomeDress":true,"Name":"Leia","PartitionKey":"mypartitionkey","RowKey":"myrowkey"}' + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:SdmKhX1o5pDblpgZUJf+NkW2kma6tavc7HIRCnNqdKk= + Content-Length: + - "112" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:19 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table38storageentitysuitetestins%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29 + method: PUT + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:19 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A19.0751178Z'" + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b6ca-0002-0064-0d5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:zwBN93vR49I5/vLgEaNd6U0Dk7QzUMMxxQJuPwrftQo= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:19 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table38storageentitysuitetestins%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:19 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b6d2-0002-0064-155c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageEntitySuite/TestMerge.yaml b/storage/recordings/StorageEntitySuite/TestMerge.yaml new file mode 100644 index 000000000000..46b016106ded --- /dev/null +++ b/storage/recordings/StorageEntitySuite/TestMerge.yaml @@ -0,0 +1,282 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: | + {"TableName":"table28storageentitysuitetestmer"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:UApC6hOOGveWssOXfwZxX0XEiTH43zQgc7hFaxaEnHI= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:19 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table28storageentitysuitetestmer') + Date: + - Wed, 05 Apr 2017 22:33:19 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table28storageentitysuitetestmer') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b6ed-0002-0064-2f5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: '{"Country":"Mexico","MalePoet":"Nezahualcoyotl","PartitionKey":"mypartitionkey","RowKey":"myrowkey"}' + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:waQ65Pa/FzCzNF8xq6tCL3Hwbyfkmnr7Sz+9cc7b7bU= + Content-Length: + - "100" + Content-Type: + - application/json + Prefer: + - return-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:19 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table28storageentitysuitetestmer + method: POST + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table28storageentitysuitetestmer/@Element","odata.type":"golangrocksonazure.table28storageentitysuitetestmer","odata.id":"https://golangrocksonazure.table.core.windows.net/table28storageentitysuitetestmer(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')","odata.etag":"W/\"datetime''2017-04-05T22%3A33%3A19.5431339Z''\"","odata.editLink":"table28storageentitysuitetestmer(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')","PartitionKey":"mypartitionkey","RowKey":"myrowkey","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-05T22:33:19.5431339Z","Country":"Mexico","MalePoet":"Nezahualcoyotl"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:19 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A19.5431339Z'" + Location: + - https://golangrocksonazure.table.core.windows.net/table28storageentitysuitetestmer(PartitionKey='mypartitionkey',RowKey='myrowkey') + Preference-Applied: + - return-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b6fd-0002-0064-3e5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: '{"FemalePoet":"Sor Juana Ines de la Cruz","PartitionKey":"mypartitionkey","RowKey":"myrowkey"}' + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:QKcxsU9OKUPDLmjVXAtOlcB+D5aaOfwXc70VX2nKBV8= + Content-Length: + - "94" + Content-Type: + - application/json + If-Match: + - W/"datetime'2017-04-05T22%3A33%3A19.5431339Z'" + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:19 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table28storageentitysuitetestmer%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29 + method: MERGE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:19 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A19.5441339Z'" + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b708-0002-0064-495c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: '{"FemalePoet":"Sor Juana Ines de la Cruz","PartitionKey":"mypartitionkey","RowKey":"myrowkey"}' + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:QKcxsU9OKUPDLmjVXAtOlcB+D5aaOfwXc70VX2nKBV8= + Content-Length: + - "94" + Content-Type: + - application/json + If-Match: + - W/"datetime''2017-04-01T01%3A07%3A23.8881885Z''" + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:19 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table28storageentitysuitetestmer%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29 + method: MERGE + response: + body: '{"odata.error":{"code":"ConditionNotMet","message":{"lang":"en-US","value":"The + condition specified using HTTP conditional header(s) is not met.\nRequestId:ab33b717-0002-0064-585c-aeb219000000\nTime:2017-04-05T22:33:19.7592892Z"}}}' + headers: + Content-Type: + - application/json;odata=nometadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:19 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b717-0002-0064-585c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 412 Precondition Failed + code: 412 +- request: + body: '{"FemalePainter":"Frida Kahlo","MalePainter":"Diego Rivera","PartitionKey":"mypartitionkey","RowKey":"myrowkey"}' + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:QKcxsU9OKUPDLmjVXAtOlcB+D5aaOfwXc70VX2nKBV8= + Content-Length: + - "112" + Content-Type: + - application/json + If-Match: + - '*' + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:19 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table28storageentitysuitetestmer%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29 + method: MERGE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:19 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A19.5451339Z'" + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b735-0002-0064-765c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:uNlLRSlYVGkKM6TOWgzB6ORWehbUnExnfVVr/QwGH08= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:19 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table28storageentitysuitetestmer%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:19 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b740-0002-0064-805c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageEntitySuite/TestUpdate.yaml b/storage/recordings/StorageEntitySuite/TestUpdate.yaml new file mode 100644 index 000000000000..1cc8a048fc36 --- /dev/null +++ b/storage/recordings/StorageEntitySuite/TestUpdate.yaml @@ -0,0 +1,282 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: | + {"TableName":"table29storageentitysuitetestupd"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:UApC6hOOGveWssOXfwZxX0XEiTH43zQgc7hFaxaEnHI= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:19 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table29storageentitysuitetestupd') + Date: + - Wed, 05 Apr 2017 22:33:21 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table29storageentitysuitetestupd') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b751-0002-0064-105c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: '{"AmountDue":200.23,"CustomerCode":"c9da6455-213d-42c9-9a79-3e9149a57833","CustomerCode@odata.type":"Edm.Guid","CustomerSince":"1992-12-20T21:55:00Z","CustomerSince@odata.type":"Edm.DateTime","IsActive":true,"NumberOfOrders":"255","NumberOfOrders@odata.type":"Edm.Int64","PartitionKey":"mypartitionkey","RowKey":"myrowkey"}' + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:8H5S+sLigqgd6u+Zz1ZaF4NGOeDqXGqpHNuLttJFvYY= + Content-Length: + - "323" + Content-Type: + - application/json + Prefer: + - return-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:21 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table29storageentitysuitetestupd + method: POST + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table29storageentitysuitetestupd/@Element","odata.type":"golangrocksonazure.table29storageentitysuitetestupd","odata.id":"https://golangrocksonazure.table.core.windows.net/table29storageentitysuitetestupd(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')","odata.etag":"W/\"datetime''2017-04-05T22%3A33%3A21.3944643Z''\"","odata.editLink":"table29storageentitysuitetestupd(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')","PartitionKey":"mypartitionkey","RowKey":"myrowkey","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-05T22:33:21.3944643Z","AmountDue":200.23,"CustomerCode@odata.type":"Edm.Guid","CustomerCode":"c9da6455-213d-42c9-9a79-3e9149a57833","CustomerSince@odata.type":"Edm.DateTime","CustomerSince":"1992-12-20T21:55:00Z","IsActive":true,"NumberOfOrders@odata.type":"Edm.Int64","NumberOfOrders":"255"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:21 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A21.3944643Z'" + Location: + - https://golangrocksonazure.table.core.windows.net/table29storageentitysuitetestupd(PartitionKey='mypartitionkey',RowKey='myrowkey') + Preference-Applied: + - return-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b8be-0002-0064-5f5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: '{"FamilyName":"Skywalker","HasEpicTheme":true,"Name":"Anakin","PartitionKey":"mypartitionkey","RowKey":"myrowkey"}' + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:rZSIXhKEtGwbh/9/jOdab4Im+bjetbRJj7Q8lZcgTXQ= + Content-Length: + - "114" + Content-Type: + - application/json + If-Match: + - W/"datetime'2017-04-05T22%3A33%3A21.3944643Z'" + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:21 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table29storageentitysuitetestupd%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29 + method: PUT + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:21 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A21.3954643Z'" + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b8cc-0002-0064-6d5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: '{"FamilyName":"Skywalker","HasEpicTheme":true,"Name":"Anakin","PartitionKey":"mypartitionkey","RowKey":"myrowkey"}' + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:rZSIXhKEtGwbh/9/jOdab4Im+bjetbRJj7Q8lZcgTXQ= + Content-Length: + - "114" + Content-Type: + - application/json + If-Match: + - W/"datetime''2017-04-01T01%3A07%3A23.8881885Z''" + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:21 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table29storageentitysuitetestupd%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29 + method: PUT + response: + body: '{"odata.error":{"code":"ConditionNotMet","message":{"lang":"en-US","value":"The + condition specified using HTTP conditional header(s) is not met.\nRequestId:ab33b8d9-0002-0064-795c-aeb219000000\nTime:2017-04-05T22:33:21.5435710Z"}}}' + headers: + Content-Type: + - application/json;odata=nometadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:21 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b8d9-0002-0064-795c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 412 Precondition Failed + code: 412 +- request: + body: '{"FamilyName":"Organa","HasAwesomeDress":true,"Name":"Leia","PartitionKey":"mypartitionkey","RowKey":"myrowkey"}' + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:rZSIXhKEtGwbh/9/jOdab4Im+bjetbRJj7Q8lZcgTXQ= + Content-Length: + - "112" + Content-Type: + - application/json + If-Match: + - '*' + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:21 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table29storageentitysuitetestupd%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29 + method: PUT + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:21 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A21.3964643Z'" + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b8ec-0002-0064-095c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:Fx0hjj/Vg9jCf7Cl6kLMeouq4OULBHhxYWBdz6fPfrI= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:21 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table29storageentitysuitetestupd%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:21 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b8f8-0002-0064-155c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageEntitySuite/Test_InsertAndDeleteEntities.yaml b/storage/recordings/StorageEntitySuite/Test_InsertAndDeleteEntities.yaml new file mode 100644 index 000000000000..0d17f3b5bf93 --- /dev/null +++ b/storage/recordings/StorageEntitySuite/Test_InsertAndDeleteEntities.yaml @@ -0,0 +1,300 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: | + {"TableName":"table47storageentitysuitetestins"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:cy02jfl8ITfr9jAyIek/qzm4CCuo4Y7GXvF74wIrkgY= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:21 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table47storageentitysuitetestins') + Date: + - Wed, 05 Apr 2017 22:33:21 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table47storageentitysuitetestins') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b90b-0002-0064-285c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: '{"FamilyName":"Skywalker","Name":"Luke","Number":3,"PartitionKey":"mypartitionkey","RowKey":"100"}' + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:WiA7NftMB4cIorqRb3tMswathla1nQK3IRs1XXtW2UQ= + Content-Length: + - "98" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:21 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table47storageentitysuitetestins + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/table47storageentitysuitetestins(PartitionKey='mypartitionkey',RowKey='100') + Date: + - Wed, 05 Apr 2017 22:33:21 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A21.7507202Z'" + Location: + - https://golangrocksonazure.table.core.windows.net/table47storageentitysuitetestins(PartitionKey='mypartitionkey',RowKey='100') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b913-0002-0064-2f5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: '{"FamilyName":"Skywalker","Name":"Luke","Number":1,"PartitionKey":"mypartitionkey","RowKey":"200"}' + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:WiA7NftMB4cIorqRb3tMswathla1nQK3IRs1XXtW2UQ= + Content-Length: + - "98" + Content-Type: + - application/json + Prefer: + - return-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:21 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table47storageentitysuitetestins + method: POST + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table47storageentitysuitetestins/@Element","odata.type":"golangrocksonazure.table47storageentitysuitetestins","odata.id":"https://golangrocksonazure.table.core.windows.net/table47storageentitysuitetestins(PartitionKey=''mypartitionkey'',RowKey=''200'')","odata.etag":"W/\"datetime''2017-04-05T22%3A33%3A21.799755Z''\"","odata.editLink":"table47storageentitysuitetestins(PartitionKey=''mypartitionkey'',RowKey=''200'')","PartitionKey":"mypartitionkey","RowKey":"200","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-05T22:33:21.799755Z","FamilyName":"Skywalker","Name":"Luke","Number":1}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:21 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A21.799755Z'" + Location: + - https://golangrocksonazure.table.core.windows.net/table47storageentitysuitetestins(PartitionKey='mypartitionkey',RowKey='200') + Preference-Applied: + - return-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b921-0002-0064-3a5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Authorization: + - SharedKey golangrocksonazure:z+UsJMxVy3yvwAsQXzVKWvUioZwxIb4LQgfyfde4jgs= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:21 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table47storageentitysuitetestins?%24filter=Number+eq+1&timeout=30 + method: GET + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table47storageentitysuitetestins","value":[{"odata.type":"golangrocksonazure.table47storageentitysuitetestins","odata.id":"https://golangrocksonazure.table.core.windows.net/table47storageentitysuitetestins(PartitionKey=''mypartitionkey'',RowKey=''200'')","odata.etag":"W/\"datetime''2017-04-05T22%3A33%3A21.799755Z''\"","odata.editLink":"table47storageentitysuitetestins(PartitionKey=''mypartitionkey'',RowKey=''200'')","PartitionKey":"mypartitionkey","RowKey":"200","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-05T22:33:21.799755Z","FamilyName":"Skywalker","Name":"Luke","Number":1}]}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:21 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b92e-0002-0064-455c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:ijytKSa75FkwJenQs0dxgKTuIK0kqkDdtIh48XzY9KU= + If-Match: + - '*' + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:21 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table47storageentitysuitetestins%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27200%27%29 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:21 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b936-0002-0064-4d5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Authorization: + - SharedKey golangrocksonazure:z+UsJMxVy3yvwAsQXzVKWvUioZwxIb4LQgfyfde4jgs= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:21 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table47storageentitysuitetestins?timeout=30 + method: GET + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table47storageentitysuitetestins","value":[{"odata.type":"golangrocksonazure.table47storageentitysuitetestins","odata.id":"https://golangrocksonazure.table.core.windows.net/table47storageentitysuitetestins(PartitionKey=''mypartitionkey'',RowKey=''100'')","odata.etag":"W/\"datetime''2017-04-05T22%3A33%3A21.7507202Z''\"","odata.editLink":"table47storageentitysuitetestins(PartitionKey=''mypartitionkey'',RowKey=''100'')","PartitionKey":"mypartitionkey","RowKey":"100","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-05T22:33:21.7507202Z","FamilyName":"Skywalker","Name":"Luke","Number":3}]}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:21 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b93c-0002-0064-535c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:OPS7H/nzJDtEovunhxSj7rACRIBMZsQE9nspHvyPiWM= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:21 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table47storageentitysuitetestins%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:21 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b957-0002-0064-6b5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageEntitySuite/Test_InsertAndExecuteQuery.yaml b/storage/recordings/StorageEntitySuite/Test_InsertAndExecuteQuery.yaml new file mode 100644 index 000000000000..c4c63995ea95 --- /dev/null +++ b/storage/recordings/StorageEntitySuite/Test_InsertAndExecuteQuery.yaml @@ -0,0 +1,228 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: | + {"TableName":"table45storageentitysuitetestins"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:F55tia1wUmKgJZ/m9yR01k56Vd9CHyyIid1PjT/AGg0= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:22 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table45storageentitysuitetestins') + Date: + - Wed, 05 Apr 2017 22:33:21 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table45storageentitysuitetestins') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b96f-0002-0064-805c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: '{"FamilyName":"Skywalker","HasCoolWeapon":true,"Name":"Luke","PartitionKey":"mypartitionkey","RowKey":"100"}' + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:wRiJwXWaYw48eSZV6VK8+0kdJIvRBuFT+QXxSzztHqo= + Content-Length: + - "108" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:22 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table45storageentitysuitetestins + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/table45storageentitysuitetestins(PartitionKey='mypartitionkey',RowKey='100') + Date: + - Wed, 05 Apr 2017 22:33:21 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A22.1349963Z'" + Location: + - https://golangrocksonazure.table.core.windows.net/table45storageentitysuitetestins(PartitionKey='mypartitionkey',RowKey='100') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b97a-0002-0064-0a5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: '{"FamilyName":"Skywalker","HasCoolWeapon":true,"Name":"Luke","PartitionKey":"mypartitionkey","RowKey":"200"}' + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:wRiJwXWaYw48eSZV6VK8+0kdJIvRBuFT+QXxSzztHqo= + Content-Length: + - "108" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:22 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table45storageentitysuitetestins + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/table45storageentitysuitetestins(PartitionKey='mypartitionkey',RowKey='200') + Date: + - Wed, 05 Apr 2017 22:33:22 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A22.1810293Z'" + Location: + - https://golangrocksonazure.table.core.windows.net/table45storageentitysuitetestins(PartitionKey='mypartitionkey',RowKey='200') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b982-0002-0064-125c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Authorization: + - SharedKey golangrocksonazure:TVOcnY9mrY9dn83/ZVes+i9ZTgwSyF7LxgsEWImQ5RQ= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:22 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table45storageentitysuitetestins?%24filter=RowKey+eq+%27200%27&timeout=30 + method: GET + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table45storageentitysuitetestins","value":[{"odata.type":"golangrocksonazure.table45storageentitysuitetestins","odata.id":"https://golangrocksonazure.table.core.windows.net/table45storageentitysuitetestins(PartitionKey=''mypartitionkey'',RowKey=''200'')","odata.etag":"W/\"datetime''2017-04-05T22%3A33%3A22.1810293Z''\"","odata.editLink":"table45storageentitysuitetestins(PartitionKey=''mypartitionkey'',RowKey=''200'')","PartitionKey":"mypartitionkey","RowKey":"200","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-05T22:33:22.1810293Z","FamilyName":"Skywalker","HasCoolWeapon":true,"Name":"Luke"}]}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:22 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b996-0002-0064-255c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:5LK5XDdD/WDzgpVS8zXAgmcSSntbdlbFzxiYo7u8EAc= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:22 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table45storageentitysuitetestins%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:22 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b9a5-0002-0064-325c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageEntitySuite/Test_InsertAndGetEntities.yaml b/storage/recordings/StorageEntitySuite/Test_InsertAndGetEntities.yaml new file mode 100644 index 000000000000..7e6c1a0f9664 --- /dev/null +++ b/storage/recordings/StorageEntitySuite/Test_InsertAndGetEntities.yaml @@ -0,0 +1,226 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: | + {"TableName":"table44storageentitysuitetestins"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:F55tia1wUmKgJZ/m9yR01k56Vd9CHyyIid1PjT/AGg0= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:22 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table44storageentitysuitetestins') + Date: + - Wed, 05 Apr 2017 22:33:22 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table44storageentitysuitetestins') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b9b7-0002-0064-405c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: '{"FamilyName":"Skywalker","HasCoolWeapon":true,"Name":"Luke","PartitionKey":"mypartitionkey","RowKey":"100"}' + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:HzZKkxWm+N5N4RC1FJtQhHlbKKECAd3V+mg76b6UgRI= + Content-Length: + - "108" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:22 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table44storageentitysuitetestins + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/table44storageentitysuitetestins(PartitionKey='mypartitionkey',RowKey='100') + Date: + - Wed, 05 Apr 2017 22:33:22 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A22.3861763Z'" + Location: + - https://golangrocksonazure.table.core.windows.net/table44storageentitysuitetestins(PartitionKey='mypartitionkey',RowKey='100') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b9bd-0002-0064-455c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: '{"FamilyName":"Skywalker","HasCoolWeapon":true,"Name":"Luke","PartitionKey":"mypartitionkey","RowKey":"200"}' + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:HzZKkxWm+N5N4RC1FJtQhHlbKKECAd3V+mg76b6UgRI= + Content-Length: + - "108" + Content-Type: + - application/json + Prefer: + - return-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:22 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table44storageentitysuitetestins + method: POST + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table44storageentitysuitetestins/@Element","odata.type":"golangrocksonazure.table44storageentitysuitetestins","odata.id":"https://golangrocksonazure.table.core.windows.net/table44storageentitysuitetestins(PartitionKey=''mypartitionkey'',RowKey=''200'')","odata.etag":"W/\"datetime''2017-04-05T22%3A33%3A22.4352119Z''\"","odata.editLink":"table44storageentitysuitetestins(PartitionKey=''mypartitionkey'',RowKey=''200'')","PartitionKey":"mypartitionkey","RowKey":"200","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-05T22:33:22.4352119Z","FamilyName":"Skywalker","HasCoolWeapon":true,"Name":"Luke"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:22 GMT + Etag: + - W/"datetime'2017-04-05T22%3A33%3A22.4352119Z'" + Location: + - https://golangrocksonazure.table.core.windows.net/table44storageentitysuitetestins(PartitionKey='mypartitionkey',RowKey='200') + Preference-Applied: + - return-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b9cd-0002-0064-555c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Authorization: + - SharedKey golangrocksonazure:CghiB6J3n1hZpBl70J5agSQMLorAQjubezthK/UEVZ8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:22 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table44storageentitysuitetestins?timeout=30 + method: GET + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table44storageentitysuitetestins","value":[{"odata.type":"golangrocksonazure.table44storageentitysuitetestins","odata.id":"https://golangrocksonazure.table.core.windows.net/table44storageentitysuitetestins(PartitionKey=''mypartitionkey'',RowKey=''100'')","odata.etag":"W/\"datetime''2017-04-05T22%3A33%3A22.3861763Z''\"","odata.editLink":"table44storageentitysuitetestins(PartitionKey=''mypartitionkey'',RowKey=''100'')","PartitionKey":"mypartitionkey","RowKey":"100","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-05T22:33:22.3861763Z","FamilyName":"Skywalker","HasCoolWeapon":true,"Name":"Luke"},{"odata.type":"golangrocksonazure.table44storageentitysuitetestins","odata.id":"https://golangrocksonazure.table.core.windows.net/table44storageentitysuitetestins(PartitionKey=''mypartitionkey'',RowKey=''200'')","odata.etag":"W/\"datetime''2017-04-05T22%3A33%3A22.4352119Z''\"","odata.editLink":"table44storageentitysuitetestins(PartitionKey=''mypartitionkey'',RowKey=''200'')","PartitionKey":"mypartitionkey","RowKey":"200","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-05T22:33:22.4352119Z","FamilyName":"Skywalker","HasCoolWeapon":true,"Name":"Luke"}]}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:22 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b9d6-0002-0064-5e5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:ne+0wCZ5Z8VUJtgbIRkqR0v4rF2BqpMKvtl1bJZ216A= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:22 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table44storageentitysuitetestins%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:22 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33b9e8-0002-0064-705c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageFileSuite/TestCopyFileMissingFile.yaml b/storage/recordings/StorageFileSuite/TestCopyFileMissingFile.yaml new file mode 100644 index 000000000000..858d994ef9d5 --- /dev/null +++ b/storage/recordings/StorageFileSuite/TestCopyFileMissingFile.yaml @@ -0,0 +1,128 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:S+EpqQqFM1g2Gs0deNksf1DYTg6h0EtsZueKSGi29WA= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:22 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-40storagefilesuitetestcopyfilemissingfile?restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:22 GMT + Etag: + - '"0x8D47C73C453642F"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:22 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271f0-001a-00eb-5a5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:0FWm/JBcLHsfuVOIWaLMcZ646JZWgpJGRMADPxZ4pHY= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:22 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-40storagefilesuitetestcopyfilemissingfile/one?restype=directory + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:22 GMT + Etag: + - '"0x8D47C73C4325B3F"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:22 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271f2-001a-00eb-5b5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:36kI+byDQVZjmIHbfqq3ZmjH3YgwDJj865RGGy7cZ7s= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Copy-Source: + - "" + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:22 GMT + X-Ms-Type: + - file + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-40storagefilesuitetestcopyfilemissingfile/one/someother.file + method: PUT + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x72\x72\x6F\x72\x3E\x3C\x43\x6F\x64\x65\x3E\x4D\x69\x73\x73\x69\x6E\x67\x52\x65\x71\x75\x69\x72\x65\x64\x48\x65\x61\x64\x65\x72\x3C\x2F\x43\x6F\x64\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x3E\x41\x6E\x20\x48\x54\x54\x50\x20\x68\x65\x61\x64\x65\x72\x20\x74\x68\x61\x74\x27\x73\x20\x6D\x61\x6E\x64\x61\x74\x6F\x72\x79\x20\x66\x6F\x72\x20\x74\x68\x69\x73\x20\x72\x65\x71\x75\x65\x73\x74\x20\x69\x73\x20\x6E\x6F\x74\x20\x73\x70\x65\x63\x69\x66\x69\x65\x64\x2E\n\x52\x65\x71\x75\x65\x73\x74\x49\x64\x3A\x35\x61\x30\x32\x37\x31\x66\x33\x2D\x30\x30\x31\x61\x2D\x30\x30\x65\x62\x2D\x35\x63\x35\x63\x2D\x61\x65\x66\x63\x34\x35\x30\x30\x30\x30\x30\x30\n\x54\x69\x6D\x65\x3A\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x32\x32\x2E\x33\x39\x34\x36\x30\x30\x30\x5A\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x48\x65\x61\x64\x65\x72\x4E\x61\x6D\x65\x3E\x78\x2D\x6D\x73\x2D\x63\x6F\x6E\x74\x65\x6E\x74\x2D\x6C\x65\x6E\x67\x74\x68\x3C\x2F\x48\x65\x61\x64\x65\x72\x4E\x61\x6D\x65\x3E\x3C\x2F\x45\x72\x72\x6F\x72\x3E" + headers: + Content-Length: + - "300" + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:22 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271f3-001a-00eb-5c5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 400 An HTTP header that's mandatory for this request is not specified. + code: 400 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:E4PK6XOwNMGXpBT49OtEBHqOfHPdHCw7JdJUJKHvecs= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:22 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-40storagefilesuitetestcopyfilemissingfile?restype=share + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:22 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271f4-001a-00eb-5d5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageFileSuite/TestCopyFileSameAccountNoMetaData.yaml b/storage/recordings/StorageFileSuite/TestCopyFileSameAccountNoMetaData.yaml new file mode 100644 index 000000000000..c9b66493fb3c --- /dev/null +++ b/storage/recordings/StorageFileSuite/TestCopyFileSameAccountNoMetaData.yaml @@ -0,0 +1,289 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:MpXcRE8AcpFRx6UGqBsnu81pD8kXXp0KmEqwnGLwNas= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:22 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-50storagefilesuitetestcopyfilesameaccountnometadata?restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:22 GMT + Etag: + - '"0x8D47C73C471C735"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:22 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271f5-001a-00eb-5e5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:r/vbpZmLgpuVrphnZGp7JNOwPo16kAgvQtz0Hw+/39w= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:22 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-50storagefilesuitetestcopyfilesameaccountnometadata/one?restype=directory + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:22 GMT + Etag: + - '"0x8D47C73C4510C4D"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:22 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271f7-001a-00eb-5f5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:fVAGhJTYMTaf32EAuEZcZIZRhGwjid4NR6rEJ5I70eg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:22 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-50storagefilesuitetestcopyfilesameaccountnometadata/one/two?restype=directory + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:22 GMT + Etag: + - '"0x8D47C73C45E551E"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:22 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271f8-001a-00eb-605c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:/GrRmNJMGmvjI59B+DXQUZOauBWipzS+4QtY1vJA6ug= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Content-Length: + - "1024" + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:22 GMT + X-Ms-Type: + - file + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-50storagefilesuitetestcopyfilesameaccountnometadata/one/two/some.file + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:22 GMT + Etag: + - '"0x8D47C73C469C8DF"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:22 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271f9-001a-00eb-615c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:dMfWg7/08PTtlDJzbQQUajsPjtjSjpW2tL+Rc6regFA= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:23 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-50storagefilesuitetestcopyfilesameaccountnometadata/one/two/some.file + method: HEAD + response: + body: "" + headers: + Content-Length: + - "1024" + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:22 GMT + Etag: + - '"0x8D47C73C469C8DF"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:22 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271fa-001a-00eb-625c-aefc45000000 + X-Ms-Type: + - File + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:SBAwcDCKwRKlcjSoLAg+sAyoiaR4tqQ2m+n1Ew49LMI= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Copy-Source: + - https://golangrocksonazure.file.core.windows.net/share-50storagefilesuitetestcopyfilesameaccountnometadata/one/two/some.file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:23 GMT + X-Ms-Type: + - file + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-50storagefilesuitetestcopyfilesameaccountnometadata/one/two/someother.file + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:22 GMT + Etag: + - '"0x8D47C73C48FF554"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:22 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Copy-Id: + - c0a7ceda-c893-4efc-82e4-6bf63b1b7b13 + X-Ms-Copy-Status: + - success + X-Ms-Request-Id: + - 5a0271fb-001a-00eb-635c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:jQKnIPOy9kUBbMTLXhFSxAxoROW4nBjXXvRxCy0u61g= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:23 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-50storagefilesuitetestcopyfilesameaccountnometadata/one/two/some.file + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:22 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271fc-001a-00eb-645c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:JJNkKo40JTjM7D6cQTHriQ+j9hh4giWsg5VltV6yhOc= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:23 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-50storagefilesuitetestcopyfilesameaccountnometadata/one/two/someother.file + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:22 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271fd-001a-00eb-655c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:95AIos3qH/NY0eJgzKonNkl7B3pbksKhiPL76WJuAV0= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:23 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-50storagefilesuitetestcopyfilesameaccountnometadata?restype=share + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:22 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271fe-001a-00eb-665c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageFileSuite/TestCopyFileSameAccountTimeout.yaml b/storage/recordings/StorageFileSuite/TestCopyFileSameAccountTimeout.yaml new file mode 100644 index 000000000000..bc8c4b261254 --- /dev/null +++ b/storage/recordings/StorageFileSuite/TestCopyFileSameAccountTimeout.yaml @@ -0,0 +1,252 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:udbzIbMGhVi2tr0UM3xYe15NXZZazWt0LjpM2vOmsu4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:23 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-47storagefilesuitetestcopyfilesameaccounttimeout?restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:22 GMT + Etag: + - '"0x8D47C73C4DE7FB1"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:23 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a0271ff-001a-00eb-675c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:taMcePzD9wI/ovuSi6aFs63ixESIsCj0wMjNM+yKJSo= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:23 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-47storagefilesuitetestcopyfilesameaccounttimeout/one?restype=directory + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:23 GMT + Etag: + - '"0x8D47C73C4BF4B29"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:23 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027201-001a-00eb-685c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:YNlmzJEJ7sLl9IPYl72Mr2OxM1jntul6kWKFPH36270= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:23 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-47storagefilesuitetestcopyfilesameaccounttimeout/one/two?restype=directory + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:23 GMT + Etag: + - '"0x8D47C73C4C67873"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:23 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027202-001a-00eb-695c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:jro2AAKY68Ojud4PS6d1lf0s3cY+1rJiw8PGMN3h56k= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Content-Length: + - "1024" + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:23 GMT + X-Ms-Type: + - file + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-47storagefilesuitetestcopyfilesameaccounttimeout/one/two/some.file + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:23 GMT + Etag: + - '"0x8D47C73C4E10A07"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:23 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027203-001a-00eb-6a5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Ux6DJZBmhlEdy7hj2YPYA6W+yxU0RIwYScTPQsE7Uvw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Copy-Source: + - https://golangrocksonazure.file.core.windows.net/share-47storagefilesuitetestcopyfilesameaccounttimeout/one/two/some.file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:23 GMT + X-Ms-Type: + - file + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-47storagefilesuitetestcopyfilesameaccounttimeout/one/two/someother.file?timeout=60 + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:23 GMT + Etag: + - '"0x8D47C73C4EE52CF"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:23 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Copy-Id: + - 726ba2bf-9402-4d46-be1a-f2fb34259063 + X-Ms-Copy-Status: + - success + X-Ms-Request-Id: + - 5a027204-001a-00eb-6b5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:RJHkCdxWNiaQT0PAYfZgUY1uDlHw3db/cupoQ/oRCPs= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:23 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-47storagefilesuitetestcopyfilesameaccounttimeout/one/two/some.file + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:23 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027205-001a-00eb-6c5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:TZF2tA4D5ilv/70W7BrnPBEmaNQ4s95vibFTuCTpWfo= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:23 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-47storagefilesuitetestcopyfilesameaccounttimeout/one/two/someother.file + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:23 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027206-001a-00eb-6d5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:mTMrVQxecnfqWIaD//ZPdqOIANe2fnBrcXgobxBC/ks= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:23 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-47storagefilesuitetestcopyfilesameaccounttimeout?restype=share + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:23 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027207-001a-00eb-6e5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageFileSuite/TestCreateFile.yaml b/storage/recordings/StorageFileSuite/TestCreateFile.yaml new file mode 100644 index 000000000000..0bc546143211 --- /dev/null +++ b/storage/recordings/StorageFileSuite/TestCreateFile.yaml @@ -0,0 +1,240 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:2AhHYE7Is2hJ5ffLFRRx9HS4/d/+DXBcmGFQHWBuQDo= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:24 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestcreatefile?restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:23 GMT + Etag: + - '"0x8D47C73C5420EBD"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:23 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02720a-001a-00eb-705c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:YnflvuFlNvKqr2pMY7LV7kw4JqMn8MBXuDHUX+sHECw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:24 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestcreatefile/one?restype=directory + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:23 GMT + Etag: + - '"0x8D47C73C52104A6"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:23 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02720c-001a-00eb-715c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:5O/hOKh72G8ZYpE7TU6u0O6VLPnmkoTJ8Odvv5hBXxw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:24 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestcreatefile/one/two?restype=directory + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:23 GMT + Etag: + - '"0x8D47C73C528A728"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:23 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02720d-001a-00eb-725c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:HqWvnjX27W9jv9Ap4apHDeJHX6tpTAYmOAANYUsZOR4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:24 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestcreatefile/one/two/some.file + method: HEAD + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:23 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02720e-001a-00eb-735c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The specified resource does not exist. + code: 404 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:ADQao/We+Ye7YzmolaahiHZ7ZMBYBnfDvkM+xqBEUuw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Content-Length: + - "1024" + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:24 GMT + X-Ms-Type: + - file + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestcreatefile/one/two/some.file + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:23 GMT + Etag: + - '"0x8D47C73C5477F49"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:23 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02720f-001a-00eb-745c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:NHiqWuo1e3lzEKehnQXa1ZhxHznph4+MOiSFINyIoeU= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:24 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestcreatefile/one/two/some.file + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:24 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027210-001a-00eb-755c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:HqWvnjX27W9jv9Ap4apHDeJHX6tpTAYmOAANYUsZOR4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:24 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestcreatefile/one/two/some.file + method: HEAD + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:24 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027211-001a-00eb-765c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The specified resource does not exist. + code: 404 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Bj2Bin+xGxxrdtK8deCXb9hQBK/zBe9jqty6/7uFZRo= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:24 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestcreatefile?restype=share + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:24 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027212-001a-00eb-775c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageFileSuite/TestFileMD5.yaml b/storage/recordings/StorageFileSuite/TestFileMD5.yaml new file mode 100644 index 000000000000..d998a5cfa09c --- /dev/null +++ b/storage/recordings/StorageFileSuite/TestFileMD5.yaml @@ -0,0 +1,225 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:GDcErV0MKKWj9vyAo8Sd9hofqgLzAFUICQyAlRfzTQU= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:24 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-28storagefilesuitetestfilemd5?restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:24 GMT + Etag: + - '"0x8D47C73C59E979F"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:24 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027213-001a-00eb-785c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:L2CXYDagD0SCSQYa5R5zyW5EyVZ/P6LW61vFY8A8NjA= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Content-Length: + - "1024" + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:24 GMT + X-Ms-Type: + - file + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-28storagefilesuitetestfilemd5/test.dat + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:24 GMT + Etag: + - '"0x8D47C73C57DB429"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:24 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027215-001a-00eb-795c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: !!binary | + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ///////////////////////////////////w== + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:ktNHnVNY8+4nY1jrfSsYegujNYDUGhp9ck+UqpVGHBY= + Content-Length: + - "1024" + Content-Md5: + - mokYsRh42lBvdhvBycTOFw== + Range: + - bytes=0-1023 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:24 GMT + X-Ms-Version: + - 2016-05-31 + X-Ms-Write: + - update + url: https://golangrocksonazure.file.core.windows.net/share-28storagefilesuitetestfilemd5/test.dat?comp=range + method: PUT + response: + body: "" + headers: + Content-Md5: + - mokYsRh42lBvdhvBycTOFw== + Date: + - Wed, 05 Apr 2017 22:33:24 GMT + Etag: + - '"0x8D47C73C586684C"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:24 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027216-001a-00eb-7a5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:DsfquVvrO5fR+xc3bvnvW6/T0izTqopb+YEvqItyAkc= + Range: + - bytes=0-1023 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:24 GMT + X-Ms-Range-Get-Content-Md5: + - "true" + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-28storagefilesuitetestfilemd5/test.dat + method: GET + response: + body: !!binary | + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ///////////////////////////////////w== + headers: + Accept-Ranges: + - bytes + Content-Length: + - "1024" + Content-Md5: + - mokYsRh42lBvdhvBycTOFw== + Content-Range: + - bytes 0-1023/1024 + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:24 GMT + Etag: + - '"0x8D47C73C586684C"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:24 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027217-001a-00eb-7b5c-aefc45000000 + X-Ms-Type: + - File + X-Ms-Version: + - 2016-05-31 + status: 206 Partial Content + code: 206 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:zpYhbNL94X54QfRPxArAPuGGa6uV2FuXfy57A+ORQBg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:24 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-28storagefilesuitetestfilemd5?restype=share + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:24 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027218-001a-00eb-7c5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageFileSuite/TestFileMetadata.yaml b/storage/recordings/StorageFileSuite/TestFileMetadata.yaml new file mode 100644 index 000000000000..7e5476574fa1 --- /dev/null +++ b/storage/recordings/StorageFileSuite/TestFileMetadata.yaml @@ -0,0 +1,173 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:cp98c9s4axvdKfWe0oaM+dTLU9tr6eV1WCeBo3Dq6AQ= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:25 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-33storagefilesuitetestfilemetadata?restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:24 GMT + Etag: + - '"0x8D47C73C5C958FB"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:24 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027219-001a-00eb-7d5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:/jSwP/zdV5+8aq8f0p6K7J9zWCT1CVQRGJtCBfd+210= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Content-Length: + - "512" + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:25 GMT + X-Ms-Type: + - file + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-33storagefilesuitetestfilemetadata/test.dat + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:24 GMT + Etag: + - '"0x8D47C73C5AABFAD"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:24 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02721b-001a-00eb-7e5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:FQmNZz5lbp/tSmomNAS8cuJrZYGlUUiwnB+hOIPrNOk= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:25 GMT + X-Ms-Meta-Another: + - anothervalue + X-Ms-Meta-Something: + - somethingvalue + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-33storagefilesuitetestfilemetadata/test.dat?comp=metadata + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:24 GMT + Etag: + - '"0x8D47C73C5B3259E"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:24 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02721c-001a-00eb-7f5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:h/y5MQViGWwunnHhxfsA4ssD8hH4HR0VeyYAM9JgMLs= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:25 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-33storagefilesuitetestfilemetadata/test.dat + method: HEAD + response: + body: "" + headers: + Content-Length: + - "512" + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:24 GMT + Etag: + - '"0x8D47C73C5B3259E"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:24 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Meta-Another: + - anothervalue + X-Ms-Meta-Something: + - somethingvalue + X-Ms-Request-Id: + - 5a02721d-001a-00eb-805c-aefc45000000 + X-Ms-Type: + - File + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Sr9cjx5UdXEPhncMILPi9Tac0gC4NlCibph+YsC5heE= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:25 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-33storagefilesuitetestfilemetadata?restype=share + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:24 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02721f-001a-00eb-015c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageFileSuite/TestFileProperties.yaml b/storage/recordings/StorageFileSuite/TestFileProperties.yaml new file mode 100644 index 000000000000..2864fdfd0369 --- /dev/null +++ b/storage/recordings/StorageFileSuite/TestFileProperties.yaml @@ -0,0 +1,185 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:3gfImYdosqvrxRgvVla5TdbSnMMyDpDOotk7cE0oLbE= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:25 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-35storagefilesuitetestfileproperties?restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:24 GMT + Etag: + - '"0x8D47C73C5F48F9C"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:25 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027220-001a-00eb-025c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:QUcZcmHhF9uj85TOgJVzshkwYWq+6WwG7Fh9LdayK/o= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Content-Length: + - "512" + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:25 GMT + X-Ms-Type: + - file + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-35storagefilesuitetestfileproperties/test.dat + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:24 GMT + Etag: + - '"0x8D47C73C5D3ABC4"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:24 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027222-001a-00eb-035c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:+PLaoHZYQZiStKQ+FuhTCccvJsszoRQTQ+d9mhXRJ9Q= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Cache-Control: + - cachecontrol + X-Ms-Content-Disposition: + - friendly + X-Ms-Content-Encoding: + - noencoding + X-Ms-Content-Language: + - neutral + X-Ms-Content-Length: + - "512" + X-Ms-Content-Type: + - mytype + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:25 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-35storagefilesuitetestfileproperties/test.dat?comp=properties + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:24 GMT + Etag: + - '"0x8D47C73C5DBEA9A"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:24 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027223-001a-00eb-045c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:t6KQ/eA5uuM1MEPSG1eiThbrxbDSNR8V/pOffmqrqCQ= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:25 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-35storagefilesuitetestfileproperties/test.dat + method: HEAD + response: + body: "" + headers: + Cache-Control: + - cachecontrol + Content-Disposition: + - friendly + Content-Encoding: + - noencoding + Content-Language: + - neutral + Content-Length: + - "512" + Content-Type: + - mytype + Date: + - Wed, 05 Apr 2017 22:33:24 GMT + Etag: + - '"0x8D47C73C5DBEA9A"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:24 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027224-001a-00eb-055c-aefc45000000 + X-Ms-Type: + - File + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:oVbaWAjk4oZnmwToeFb09LmFdFkF1j5F8V8YrvLmv8w= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:25 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-35storagefilesuitetestfileproperties?restype=share + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:24 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027225-001a-00eb-065c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageFileSuite/TestFileRanges.yaml b/storage/recordings/StorageFileSuite/TestFileRanges.yaml new file mode 100644 index 000000000000..1d4b2ff2972e --- /dev/null +++ b/storage/recordings/StorageFileSuite/TestFileRanges.yaml @@ -0,0 +1,1010 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:R8UCr5bKHYuhdTvZerXTrWvE2fbUyBCSrmXa6q16I0U= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:25 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestfileranges?restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:25 GMT + Etag: + - '"0x8D47C73C61CDF85"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:25 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027226-001a-00eb-075c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:gp3Oc/Uk7U7r0ZmfuLVmcgZKXB/dt2Ujizj92s/ZfY8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Content-Length: + - "4096" + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:25 GMT + X-Ms-Type: + - file + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestfileranges/file1.txt + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:25 GMT + Etag: + - '"0x8D47C73C5FBAD4D"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:25 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027228-001a-00eb-085c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:lnvMKlnqJ74u31F1RpBoy7AAboj57EPDSMZDvADBkVc= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:25 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestfileranges/file1.txt?comp=rangelist + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x52\x61\x6E\x67\x65\x73\x20\x2F\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:25 GMT + Etag: + - '"0x8D47C73C5FBAD4D"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:25 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Content-Length: + - "4096" + X-Ms-Request-Id: + - 5a027229-001a-00eb-095c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure://8iZCTapTBflUcqii//dDJkNROH/ivxL0S6hfTj8yU= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Content-Length: + - "4096" + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:25 GMT + X-Ms-Type: + - file + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestfileranges/file2.txt + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:25 GMT + Etag: + - '"0x8D47C73C60B195C"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:25 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02722a-001a-00eb-0a5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit + volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:XNtcoZ+qTIS8KSda6WBvAuSW6nlHVYVtuLGsjsTvdqo= + Content-Length: + - "4096" + Range: + - bytes=0-4095 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:25 GMT + X-Ms-Version: + - 2016-05-31 + X-Ms-Write: + - update + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestfileranges/file2.txt?comp=range + method: PUT + response: + body: "" + headers: + Content-Md5: + - jsb3Ma13LxsCTUxwb89yFw== + Date: + - Wed, 05 Apr 2017 22:33:25 GMT + Etag: + - '"0x8D47C73C6199AE4"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:25 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02722b-001a-00eb-0b5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:CeEhs4ThZzmg1KI9B7+t/KdGRsuyxTJUNptx7ciIkog= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:25 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestfileranges/file2.txt?comp=rangelist + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x52\x61\x6E\x67\x65\x73\x3E\x3C\x52\x61\x6E\x67\x65\x3E\x3C\x53\x74\x61\x72\x74\x3E\x30\x3C\x2F\x53\x74\x61\x72\x74\x3E\x3C\x45\x6E\x64\x3E\x34\x30\x39\x35\x3C\x2F\x45\x6E\x64\x3E\x3C\x2F\x52\x61\x6E\x67\x65\x3E\x3C\x2F\x52\x61\x6E\x67\x65\x73\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:25 GMT + Etag: + - '"0x8D47C73C6199AE4"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:25 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Content-Length: + - "4096" + X-Ms-Request-Id: + - 5a02722c-001a-00eb-0c5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:/JIHcrxParjsX9e45Ow1/GSP/N0xeXRspgiQ6XkjXXU= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Content-Length: + - "4096" + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:25 GMT + X-Ms-Type: + - file + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestfileranges/file3.txt + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:25 GMT + Etag: + - '"0x8D47C73C6286A9F"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:25 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02722d-001a-00eb-0d5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit + volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:7Y1ICY2i50Qccv8DS7zmc1YWmFj6F9cRErdHxlUjRMY= + Content-Length: + - "4096" + Range: + - bytes=0-4095 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:25 GMT + X-Ms-Version: + - 2016-05-31 + X-Ms-Write: + - update + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestfileranges/file3.txt?comp=range + method: PUT + response: + body: "" + headers: + Content-Md5: + - jsb3Ma13LxsCTUxwb89yFw== + Date: + - Wed, 05 Apr 2017 22:33:25 GMT + Etag: + - '"0x8D47C73C6300D14"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:25 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02722e-001a-00eb-0e5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:xiaE22UDyIaqhqszU7Aac6ue1gbLMY8zu4jAe8edizI= + Content-Length: + - "0" + Range: + - bytes=0-4095 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:25 GMT + X-Ms-Version: + - 2016-05-31 + X-Ms-Write: + - clear + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestfileranges/file3.txt?comp=range + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:25 GMT + Etag: + - '"0x8D47C73C6378880"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:25 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02722f-001a-00eb-0f5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:QdlQR23vZQ9JqVpfNijfe02aQ+sj0RGkXJp8YytVe4Q= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:26 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestfileranges/file3.txt?comp=rangelist + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x52\x61\x6E\x67\x65\x73\x20\x2F\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:25 GMT + Etag: + - '"0x8D47C73C6378880"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:25 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Content-Length: + - "4096" + X-Ms-Request-Id: + - 5a027230-001a-00eb-105c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:y1Vjs4w7KRYYwvHXPLgd0A+0ydXzvNONYMGYosQCias= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Content-Length: + - "4096" + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:26 GMT + X-Ms-Type: + - file + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestfileranges/file4.txt + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:25 GMT + Etag: + - '"0x8D47C73C64594C8"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:25 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027231-001a-00eb-115c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Q1one+UsUJ4GNRviiARELm5+MS3Cr3puPWKS02lt05I= + Content-Length: + - "512" + Range: + - bytes=0-511 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:26 GMT + X-Ms-Version: + - 2016-05-31 + X-Ms-Write: + - update + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestfileranges/file4.txt?comp=range + method: PUT + response: + body: "" + headers: + Content-Md5: + - 2Xr7q2sERdQmQ41hZ7sPvQ== + Date: + - Wed, 05 Apr 2017 22:33:25 GMT + Etag: + - '"0x8D47C73C64D102A"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:25 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027232-001a-00eb-125c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:FVxHa6IXwEHmYRyiQS58rJKi0t7z6RprQDaQwyJFoUc= + Content-Length: + - "512" + Range: + - bytes=1024-1535 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:26 GMT + X-Ms-Version: + - 2016-05-31 + X-Ms-Write: + - update + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestfileranges/file4.txt?comp=range + method: PUT + response: + body: "" + headers: + Content-Md5: + - 2Xr7q2sERdQmQ41hZ7sPvQ== + Date: + - Wed, 05 Apr 2017 22:33:25 GMT + Etag: + - '"0x8D47C73C654B2AC"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:25 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027233-001a-00eb-135c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:QAu471nRbmar0197vPIDFpFc96KtpVkoRuNG3RFUjE0= + Content-Length: + - "512" + Range: + - bytes=2048-2559 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:26 GMT + X-Ms-Version: + - 2016-05-31 + X-Ms-Write: + - update + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestfileranges/file4.txt?comp=range + method: PUT + response: + body: "" + headers: + Content-Md5: + - 2Xr7q2sERdQmQ41hZ7sPvQ== + Date: + - Wed, 05 Apr 2017 22:33:25 GMT + Etag: + - '"0x8D47C73C6661AE5"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:25 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027234-001a-00eb-145c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:al5gIxfQF01kp4pdVQHyW0r4IUP8wn3ifivYACNWq30= + Content-Length: + - "512" + Range: + - bytes=3072-3583 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:26 GMT + X-Ms-Version: + - 2016-05-31 + X-Ms-Write: + - update + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestfileranges/file4.txt?comp=range + method: PUT + response: + body: "" + headers: + Content-Md5: + - 2Xr7q2sERdQmQ41hZ7sPvQ== + Date: + - Wed, 05 Apr 2017 22:33:25 GMT + Etag: + - '"0x8D47C73C66D6F35"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:25 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027235-001a-00eb-155c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:t0n7KNhUMmFLUpRpRAXJdj1IKWthmn6WdOfYsofuK40= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:26 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestfileranges/file4.txt?comp=rangelist + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x52\x61\x6E\x67\x65\x73\x3E\x3C\x52\x61\x6E\x67\x65\x3E\x3C\x53\x74\x61\x72\x74\x3E\x30\x3C\x2F\x53\x74\x61\x72\x74\x3E\x3C\x45\x6E\x64\x3E\x35\x31\x31\x3C\x2F\x45\x6E\x64\x3E\x3C\x2F\x52\x61\x6E\x67\x65\x3E\x3C\x52\x61\x6E\x67\x65\x3E\x3C\x53\x74\x61\x72\x74\x3E\x31\x30\x32\x34\x3C\x2F\x53\x74\x61\x72\x74\x3E\x3C\x45\x6E\x64\x3E\x31\x35\x33\x35\x3C\x2F\x45\x6E\x64\x3E\x3C\x2F\x52\x61\x6E\x67\x65\x3E\x3C\x52\x61\x6E\x67\x65\x3E\x3C\x53\x74\x61\x72\x74\x3E\x32\x30\x34\x38\x3C\x2F\x53\x74\x61\x72\x74\x3E\x3C\x45\x6E\x64\x3E\x32\x35\x35\x39\x3C\x2F\x45\x6E\x64\x3E\x3C\x2F\x52\x61\x6E\x67\x65\x3E\x3C\x52\x61\x6E\x67\x65\x3E\x3C\x53\x74\x61\x72\x74\x3E\x33\x30\x37\x32\x3C\x2F\x53\x74\x61\x72\x74\x3E\x3C\x45\x6E\x64\x3E\x33\x35\x38\x33\x3C\x2F\x45\x6E\x64\x3E\x3C\x2F\x52\x61\x6E\x67\x65\x3E\x3C\x2F\x52\x61\x6E\x67\x65\x73\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:25 GMT + Etag: + - '"0x8D47C73C66D6F35"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:25 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Content-Length: + - "4096" + X-Ms-Request-Id: + - 5a027236-001a-00eb-165c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:iKY/eEZXTz0X3uRR06N5zHpuyolzZKySjiDBNZ6yEJ0= + Range: + - bytes=1000-3000 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:26 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestfileranges/file4.txt?comp=rangelist + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x52\x61\x6E\x67\x65\x73\x3E\x3C\x52\x61\x6E\x67\x65\x3E\x3C\x53\x74\x61\x72\x74\x3E\x31\x30\x32\x34\x3C\x2F\x53\x74\x61\x72\x74\x3E\x3C\x45\x6E\x64\x3E\x31\x35\x33\x35\x3C\x2F\x45\x6E\x64\x3E\x3C\x2F\x52\x61\x6E\x67\x65\x3E\x3C\x52\x61\x6E\x67\x65\x3E\x3C\x53\x74\x61\x72\x74\x3E\x32\x30\x34\x38\x3C\x2F\x53\x74\x61\x72\x74\x3E\x3C\x45\x6E\x64\x3E\x32\x35\x35\x39\x3C\x2F\x45\x6E\x64\x3E\x3C\x2F\x52\x61\x6E\x67\x65\x3E\x3C\x2F\x52\x61\x6E\x67\x65\x73\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:26 GMT + Etag: + - '"0x8D47C73C66D6F35"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:25 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Content-Length: + - "4096" + X-Ms-Request-Id: + - 5a027238-001a-00eb-175c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:aAJUH9hdxXdjXhMD/h3UJP3VD54JvJg7Fl/3tByBgcE= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Content-Length: + - "4096" + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:26 GMT + X-Ms-Type: + - file + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestfileranges/file5.txt + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:26 GMT + Etag: + - '"0x8D47C73C6963431"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:26 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027239-001a-00eb-185c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer feugiat + eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et finibus + massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque id justo + interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. + Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. Donec + ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida + dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit + volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:pxTDbT1N1tzDsvN6vp3WjCnT7r2neYkHLH4cqJJu6IY= + Content-Length: + - "4096" + Range: + - bytes=0-4095 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:26 GMT + X-Ms-Version: + - 2016-05-31 + X-Ms-Write: + - update + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestfileranges/file5.txt?comp=range + method: PUT + response: + body: "" + headers: + Content-Md5: + - jsb3Ma13LxsCTUxwb89yFw== + Date: + - Wed, 05 Apr 2017 22:33:26 GMT + Etag: + - '"0x8D47C73C6B225A6"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:26 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02723a-001a-00eb-195c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:tPpzg7V0upNpe63MqTv1TihLSsq52uj3eNKKljPSYP0= + Content-Length: + - "0" + Range: + - bytes=0-511 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:26 GMT + X-Ms-Version: + - 2016-05-31 + X-Ms-Write: + - clear + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestfileranges/file5.txt?comp=range + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:26 GMT + Etag: + - '"0x8D47C73C6B9A108"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:26 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02723b-001a-00eb-1a5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:esNaZmaV5gsCKjugqgoAvD1MH/zhw8B4FSK7m1VYiSM= + Content-Length: + - "0" + Range: + - bytes=2048-2559 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:26 GMT + X-Ms-Version: + - 2016-05-31 + X-Ms-Write: + - clear + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestfileranges/file5.txt?comp=range + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:26 GMT + Etag: + - '"0x8D47C73C6C0F558"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:26 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02723c-001a-00eb-1b5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:HsfhiM/q4W2tJ4FNPQSB3as2uMpdag5dwHMFReSFLfU= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:26 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestfileranges/file5.txt?comp=rangelist + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x52\x61\x6E\x67\x65\x73\x3E\x3C\x52\x61\x6E\x67\x65\x3E\x3C\x53\x74\x61\x72\x74\x3E\x35\x31\x32\x3C\x2F\x53\x74\x61\x72\x74\x3E\x3C\x45\x6E\x64\x3E\x32\x30\x34\x37\x3C\x2F\x45\x6E\x64\x3E\x3C\x2F\x52\x61\x6E\x67\x65\x3E\x3C\x52\x61\x6E\x67\x65\x3E\x3C\x53\x74\x61\x72\x74\x3E\x32\x35\x36\x30\x3C\x2F\x53\x74\x61\x72\x74\x3E\x3C\x45\x6E\x64\x3E\x34\x30\x39\x35\x3C\x2F\x45\x6E\x64\x3E\x3C\x2F\x52\x61\x6E\x67\x65\x3E\x3C\x2F\x52\x61\x6E\x67\x65\x73\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:26 GMT + Etag: + - '"0x8D47C73C6C0F558"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:26 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Content-Length: + - "4096" + X-Ms-Request-Id: + - 5a02723d-001a-00eb-1c5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Zvu5JIwAAJusgoPk7ReVzyEsu7c6TvYzT1SH9dpUOrk= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:26 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-31storagefilesuitetestfileranges?restype=share + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:26 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02723e-001a-00eb-1d5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageFileSuite/TestGetFile.yaml b/storage/recordings/StorageFileSuite/TestGetFile.yaml new file mode 100644 index 000000000000..17c1540aff24 --- /dev/null +++ b/storage/recordings/StorageFileSuite/TestGetFile.yaml @@ -0,0 +1,315 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:9kLR92BuyF5lIzw8zheBCz7oBG7DFMgjO5naq0+KM8U= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:27 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-28storagefilesuitetestgetfile?restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:26 GMT + Etag: + - '"0x8D47C73C703995D"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:26 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02723f-001a-00eb-1e5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:yhcuHp2qA/h0cp3Kz4SxP3nYnA202aVeY0FHnKtzim4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Content-Length: + - "1024" + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:27 GMT + X-Ms-Type: + - file + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-28storagefilesuitetestgetfile/some.file + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:26 GMT + Etag: + - '"0x8D47C73C6E2DB49"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:26 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027241-001a-00eb-1f5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: !!binary | + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ///////////////////////////////////w== + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:pFNRo5uEefHQp6iBSfukEKmsWsAnwdrYvXgalmqCVT8= + Content-Length: + - "1024" + Range: + - bytes=0-1023 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:27 GMT + X-Ms-Version: + - 2016-05-31 + X-Ms-Write: + - update + url: https://golangrocksonazure.file.core.windows.net/share-28storagefilesuitetestgetfile/some.file?comp=range + method: PUT + response: + body: "" + headers: + Content-Md5: + - mokYsRh42lBvdhvBycTOFw== + Date: + - Wed, 05 Apr 2017 22:33:26 GMT + Etag: + - '"0x8D47C73C6EAF30C"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:26 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027242-001a-00eb-205c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:BGWZeSVp8JMKSQf8WES3wPYVr67bF6bJwFPxsQn7Iow= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:27 GMT + X-Ms-Meta-Another: + - anothervalue + X-Ms-Meta-Something: + - somethingvalue + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-28storagefilesuitetestgetfile/some.file?comp=metadata + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:26 GMT + Etag: + - '"0x8D47C73C6F2475C"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:26 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027243-001a-00eb-215c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Y8hknOSjeE5QxB4LIbz1OocJ9mbHLa2S52Psm2LT+lg= + Range: + - bytes=0-1023 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:27 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-28storagefilesuitetestgetfile/some.file + method: GET + response: + body: !!binary | + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ///////////////////////////////////w== + headers: + Accept-Ranges: + - bytes + Content-Length: + - "1024" + Content-Range: + - bytes 0-1023/1024 + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:26 GMT + Etag: + - '"0x8D47C73C6F2475C"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:26 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Meta-Another: + - anothervalue + X-Ms-Meta-Something: + - somethingvalue + X-Ms-Request-Id: + - 5a027244-001a-00eb-225c-aefc45000000 + X-Ms-Type: + - File + X-Ms-Version: + - 2016-05-31 + status: 206 Partial Content + code: 206 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:2CRI15qsJg6UODR5aiqEFi9R/AU3f+N249JkW7E4goA= + Range: + - bytes=512-1023 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:27 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-28storagefilesuitetestgetfile/some.file + method: GET + response: + body: !!binary | + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////8= + headers: + Accept-Ranges: + - bytes + Content-Length: + - "512" + Content-Range: + - bytes 512-1023/1024 + Content-Type: + - application/octet-stream + Date: + - Wed, 05 Apr 2017 22:33:26 GMT + Etag: + - '"0x8D47C73C6F2475C"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:26 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Meta-Another: + - anothervalue + X-Ms-Meta-Something: + - somethingvalue + X-Ms-Request-Id: + - 5a027245-001a-00eb-235c-aefc45000000 + X-Ms-Type: + - File + X-Ms-Version: + - 2016-05-31 + status: 206 Partial Content + code: 206 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:wnzAnAKDNFWSecVFKqh4wxsKBvdl2M2RdJrU6dYTRTo= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:27 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-28storagefilesuitetestgetfile?restype=share + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:26 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027246-001a-00eb-245c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageMessageSuite/TestDeleteMessages.yaml b/storage/recordings/StorageMessageSuite/TestDeleteMessages.yaml new file mode 100644 index 000000000000..4c6cc810ff24 --- /dev/null +++ b/storage/recordings/StorageMessageSuite/TestDeleteMessages.yaml @@ -0,0 +1,151 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:7J32x93osnJ/Lzpyy4dxVPSe1uioAzQeUBeshptVTaY= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 23:44:26 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-38storagemessagesuitetestdeletemessages + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 23:44:25 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 3890b5e3-0003-0012-1d66-ae36a5000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: message + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:HOujcGIBZYS0yO0HMHhfIiqWgK7mxHbRCte7mZCnl54= + Content-Length: + - "63" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 23:44:26 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-38storagemessagesuitetestdeletemessages/messages + method: POST + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x61\x63\x39\x64\x35\x30\x35\x30\x2D\x36\x39\x31\x66\x2D\x34\x35\x62\x32\x2D\x39\x30\x30\x31\x2D\x30\x63\x63\x62\x64\x36\x32\x35\x66\x32\x63\x39\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x3C\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x33\x3A\x34\x34\x3A\x32\x36\x20\x47\x4D\x54\x3C\x2F\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x31\x32\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x33\x3A\x34\x34\x3A\x32\x36\x20\x47\x4D\x54\x3C\x2F\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x41\x67\x41\x41\x41\x41\x4D\x41\x41\x41\x41\x41\x41\x41\x41\x41\x43\x61\x39\x57\x6A\x32\x61\x75\x30\x67\x45\x3D\x3C\x2F\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x3C\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x33\x3A\x34\x34\x3A\x32\x36\x20\x47\x4D\x54\x3C\x2F\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 23:44:25 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 3890b5f8-0003-0012-2f66-ae36a5000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:71lN4zn1znDzKRajaH5cm7QsU8N35yWvUZZueoTDK4g= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 23:44:26 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-38storagemessagesuitetestdeletemessages/messages?visibilitytimeout=1 + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x61\x63\x39\x64\x35\x30\x35\x30\x2D\x36\x39\x31\x66\x2D\x34\x35\x62\x32\x2D\x39\x30\x30\x31\x2D\x30\x63\x63\x62\x64\x36\x32\x35\x66\x32\x63\x39\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x3C\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x33\x3A\x34\x34\x3A\x32\x36\x20\x47\x4D\x54\x3C\x2F\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x31\x32\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x33\x3A\x34\x34\x3A\x32\x36\x20\x47\x4D\x54\x3C\x2F\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x41\x67\x41\x41\x41\x41\x4D\x41\x41\x41\x41\x41\x41\x41\x41\x41\x71\x30\x76\x32\x6A\x32\x61\x75\x30\x67\x45\x3D\x3C\x2F\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x3C\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x33\x3A\x34\x34\x3A\x32\x37\x20\x47\x4D\x54\x3C\x2F\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x3C\x44\x65\x71\x75\x65\x75\x65\x43\x6F\x75\x6E\x74\x3E\x31\x3C\x2F\x44\x65\x71\x75\x65\x75\x65\x43\x6F\x75\x6E\x74\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x54\x65\x78\x74\x3E\x6D\x65\x73\x73\x61\x67\x65\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x54\x65\x78\x74\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E" + headers: + Cache-Control: + - no-cache + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 23:44:25 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 3890b601-0003-0012-3866-ae36a5000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:QWIYUOYycw+eJZ++471/ll5cWEau472PzrTShbXFGoU= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 23:44:26 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-38storagemessagesuitetestdeletemessages/messages/ac9d5050-691f-45b2-9001-0ccbd625f2c9?popreceipt=AgAAAAMAAAAAAAAAq0v2j2au0gE%3D + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 23:44:25 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 3890b60d-0003-0012-4466-ae36a5000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:KXYBwEee7+QtH0SFyxvQLPCcqRU2t4+mlRHebVLakgQ= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 23:44:26 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-38storagemessagesuitetestdeletemessages + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 23:44:25 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 3890b614-0003-0012-4b66-ae36a5000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageMessageSuite/TestPutMessage_Peek.yaml b/storage/recordings/StorageMessageSuite/TestPutMessage_Peek.yaml new file mode 100644 index 000000000000..955f51f00f72 --- /dev/null +++ b/storage/recordings/StorageMessageSuite/TestPutMessage_Peek.yaml @@ -0,0 +1,947 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:1Kd6d39bbodTKHuy/NKyglgQPc2r3tmKiKQBIS19BAg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 23:44:26 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-39storagemessagesuitetestputmessagepeek + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 23:44:25 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 3890b61a-0003-0012-5166-ae36a5000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultr + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:l29QUzUtfC/WC0NbYdUifn0ST5iQb1InTeg9gPLblB0= + Content-Length: + - "65592" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 23:44:26 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-39storagemessagesuitetestputmessagepeek/messages + method: POST + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x36\x65\x64\x63\x61\x33\x39\x63\x2D\x62\x31\x30\x37\x2D\x34\x30\x39\x66\x2D\x61\x38\x32\x30\x2D\x34\x62\x66\x65\x34\x31\x61\x38\x66\x32\x64\x30\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x3C\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x33\x3A\x34\x34\x3A\x32\x36\x20\x47\x4D\x54\x3C\x2F\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x31\x32\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x33\x3A\x34\x34\x3A\x32\x36\x20\x47\x4D\x54\x3C\x2F\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x41\x67\x41\x41\x41\x41\x4D\x41\x41\x41\x41\x41\x41\x41\x41\x41\x6E\x38\x71\x50\x6A\x32\x61\x75\x30\x67\x45\x3D\x3C\x2F\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x3C\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x33\x3A\x34\x34\x3A\x32\x36\x20\x47\x4D\x54\x3C\x2F\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 23:44:25 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 3890b627-0003-0012-5866-ae36a5000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:8+2Bayii4hEvj3068DdWs7QNr4PkQqCWevf8fYF64Bw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 23:44:26 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-39storagemessagesuitetestputmessagepeek/messages?peekonly=true + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x36\x65\x64\x63\x61\x33\x39\x63\x2D\x62\x31\x30\x37\x2D\x34\x30\x39\x66\x2D\x61\x38\x32\x30\x2D\x34\x62\x66\x65\x34\x31\x61\x38\x66\x32\x64\x30\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x3C\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x33\x3A\x34\x34\x3A\x32\x36\x20\x47\x4D\x54\x3C\x2F\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x31\x32\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x33\x3A\x34\x34\x3A\x32\x36\x20\x47\x4D\x54\x3C\x2F\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x44\x65\x71\x75\x65\x75\x65\x43\x6F\x75\x6E\x74\x3E\x30\x3C\x2F\x44\x65\x71\x75\x65\x75\x65\x43\x6F\x75\x6E\x74\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x54\x65\x78\x74\x3E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x54\x65\x78\x74\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E" + headers: + Cache-Control: + - no-cache + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 23:44:25 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 3890b632-0003-0012-6266-ae36a5000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:a8Kzf7Yx59aF03yxb1P2fiQszqP0D0ItqsxWGq78krQ= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 23:44:27 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-39storagemessagesuitetestputmessagepeek + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 23:44:26 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 3890b64d-0003-0012-7a66-ae36a5000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageMessageSuite/TestPutMessage_Peek_Update_Delete.yaml b/storage/recordings/StorageMessageSuite/TestPutMessage_Peek_Update_Delete.yaml new file mode 100644 index 000000000000..c6ea876218b0 --- /dev/null +++ b/storage/recordings/StorageMessageSuite/TestPutMessage_Peek_Update_Delete.yaml @@ -0,0 +1,1042 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:dP5GMXFtFR/WCgInFmZZdDnk+n35d975vdoq28yO9Us= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 23:44:27 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-53storagemessagesuitetestputmessagepeekupdatedelete + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 23:44:26 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 3890b656-0003-0012-0366-ae36a5000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc + suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. + Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque + hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque + id felis nec lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus + varius. In hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis + eget magna pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut + ut cursus odio. Quisque id justo interdum, maximus ex a, dapibus leo. Nullam + mattis arcu nec justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, + vitae scelerisque ex posuere. Donec ut ante porttitor, ultricies ante ac, pulvinar + metus. Nunc suscipit elit gravida dolor facilisis sollicitudin. Fusce ac ultrices + libero. Donec erat lectus, hendrerit volutpat nisl quis, porta accumsan nibh. + Pellentesque hendrerit nisi id mi porttitor maximus. Phasellus vitae venenatis + velit. Quisque id felis nec lacus iaculis porttitor. Maecenas egestas tortor + et nulla dapibus varius. In hac habitasse platea dictumst.Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Integer feugiat eleifend scelerisque. + Phasellus tempor turpis eget magna pretium, et finibus massa convallis. Donec + eget lacinia nibh. Ut ut cursus odio. Quisque id justo interdum, maximus ex + a, dapibus leo. Nullam mattis arcu nec justo vehicula pretium. Curabitur fermentum + quam ac dolor venenatis, vitae scelerisque ex posuere. Donec ut ante porttitor, + ultricies ante ac, pulvinar metus. Nunc suscipit elit gravida dolor facilisis + sollicitudin. Fusce ac ultrices libero. Donec erat lectus, hendrerit volutpat + nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi id mi porttitor + maximus. Phasellus vitae venenatis velit. Quisque id felis nec lacus iaculis + porttitor. Maecenas egestas tortor et nulla dapibus varius. In hac habitasse + platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer + feugiat eleifend scelerisque. Phasellus tempor turpis eget magna pretium, et + finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. Quisque + id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec justo vehicula + pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque ex posuere. + Donec ut ante porttitor, ultricies ante ac, pulvinar metus. Nunc suscipit elit + gravida dolor facilisis sollicitudin. Fusce ac ultrices libero. Donec erat lectus, + hendrerit volutpat nisl quis, porta accumsan nibh. Pellentesque hendrerit nisi + id mi porttitor maximus. Phasellus vitae venenatis velit. Quisque id felis nec + lacus iaculis porttitor. Maecenas egestas tortor et nulla dapibus varius. In + hac habitasse platea dictumst.Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer feugiat eleifend scelerisque. Phasellus tempor turpis eget magna + pretium, et finibus massa convallis. Donec eget lacinia nibh. Ut ut cursus odio. + Quisque id justo interdum, maximus ex a, dapibus leo. Nullam mattis arcu nec + justo vehicula pretium. Curabitur fermentum quam ac dolor venenatis, vitae scelerisque + ex posuere. Donec ut ante porttitor, ultr + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Mwu449dg5OOcWsG5UB1+EViMYVu910XvGa5abHsTBXs= + Content-Length: + - "65592" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 23:44:27 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-53storagemessagesuitetestputmessagepeekupdatedelete/messages + method: POST + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x37\x36\x31\x30\x30\x39\x33\x36\x2D\x34\x37\x38\x36\x2D\x34\x36\x35\x65\x2D\x62\x62\x36\x37\x2D\x62\x65\x39\x33\x34\x64\x38\x32\x38\x65\x63\x63\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x3C\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x33\x3A\x34\x34\x3A\x32\x36\x20\x47\x4D\x54\x3C\x2F\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x31\x32\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x33\x3A\x34\x34\x3A\x32\x36\x20\x47\x4D\x54\x3C\x2F\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x41\x67\x41\x41\x41\x41\x4D\x41\x41\x41\x41\x41\x41\x41\x41\x41\x59\x2B\x4C\x4B\x6A\x32\x61\x75\x30\x67\x45\x3D\x3C\x2F\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x3C\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x33\x3A\x34\x34\x3A\x32\x36\x20\x47\x4D\x54\x3C\x2F\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 23:44:26 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 3890b661-0003-0012-0d66-ae36a5000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: and other message + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:shg3ibKARCSQOK3ve4S1StRrGJ2Vh67dAztqTWQNSc0= + Content-Length: + - "73" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 23:44:27 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-53storagemessagesuitetestputmessagepeekupdatedelete/messages + method: POST + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x30\x64\x38\x62\x65\x30\x37\x39\x2D\x61\x37\x66\x64\x2D\x34\x62\x62\x36\x2D\x38\x64\x64\x61\x2D\x64\x64\x32\x33\x31\x62\x63\x30\x35\x66\x34\x66\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x3C\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x33\x3A\x34\x34\x3A\x32\x36\x20\x47\x4D\x54\x3C\x2F\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x31\x32\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x33\x3A\x34\x34\x3A\x32\x36\x20\x47\x4D\x54\x3C\x2F\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x41\x67\x41\x41\x41\x41\x4D\x41\x41\x41\x41\x41\x41\x41\x41\x41\x72\x6A\x62\x53\x6A\x32\x61\x75\x30\x67\x45\x3D\x3C\x2F\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x3C\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x33\x3A\x34\x34\x3A\x32\x36\x20\x47\x4D\x54\x3C\x2F\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 23:44:26 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 3890b665-0003-0012-1166-ae36a5000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:JxBWseqRl5v9vbQS6oLmJhN7tcwsCSlBKOf33GI9Sdg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 23:44:27 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-53storagemessagesuitetestputmessagepeekupdatedelete/messages?numofmessages=2&visibilitytimeout=2 + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x37\x36\x31\x30\x30\x39\x33\x36\x2D\x34\x37\x38\x36\x2D\x34\x36\x35\x65\x2D\x62\x62\x36\x37\x2D\x62\x65\x39\x33\x34\x64\x38\x32\x38\x65\x63\x63\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x3C\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x33\x3A\x34\x34\x3A\x32\x36\x20\x47\x4D\x54\x3C\x2F\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x31\x32\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x33\x3A\x34\x34\x3A\x32\x36\x20\x47\x4D\x54\x3C\x2F\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x41\x67\x41\x41\x41\x41\x4D\x41\x41\x41\x41\x41\x41\x41\x41\x41\x75\x55\x49\x4B\x6B\x57\x61\x75\x30\x67\x45\x3D\x3C\x2F\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x3C\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x33\x3A\x34\x34\x3A\x32\x39\x20\x47\x4D\x54\x3C\x2F\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x3C\x44\x65\x71\x75\x65\x75\x65\x43\x6F\x75\x6E\x74\x3E\x31\x3C\x2F\x44\x65\x71\x75\x65\x75\x65\x43\x6F\x75\x6E\x74\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x54\x65\x78\x74\x3E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x69\x63\x69\x65\x73\x20\x61\x6E\x74\x65\x20\x61\x63\x2C\x20\x70\x75\x6C\x76\x69\x6E\x61\x72\x20\x6D\x65\x74\x75\x73\x2E\x20\x4E\x75\x6E\x63\x20\x73\x75\x73\x63\x69\x70\x69\x74\x20\x65\x6C\x69\x74\x20\x67\x72\x61\x76\x69\x64\x61\x20\x64\x6F\x6C\x6F\x72\x20\x66\x61\x63\x69\x6C\x69\x73\x69\x73\x20\x73\x6F\x6C\x6C\x69\x63\x69\x74\x75\x64\x69\x6E\x2E\x20\x46\x75\x73\x63\x65\x20\x61\x63\x20\x75\x6C\x74\x72\x69\x63\x65\x73\x20\x6C\x69\x62\x65\x72\x6F\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x72\x61\x74\x20\x6C\x65\x63\x74\x75\x73\x2C\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x76\x6F\x6C\x75\x74\x70\x61\x74\x20\x6E\x69\x73\x6C\x20\x71\x75\x69\x73\x2C\x20\x70\x6F\x72\x74\x61\x20\x61\x63\x63\x75\x6D\x73\x61\x6E\x20\x6E\x69\x62\x68\x2E\x20\x50\x65\x6C\x6C\x65\x6E\x74\x65\x73\x71\x75\x65\x20\x68\x65\x6E\x64\x72\x65\x72\x69\x74\x20\x6E\x69\x73\x69\x20\x69\x64\x20\x6D\x69\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x20\x6D\x61\x78\x69\x6D\x75\x73\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x76\x69\x74\x61\x65\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x20\x76\x65\x6C\x69\x74\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x66\x65\x6C\x69\x73\x20\x6E\x65\x63\x20\x6C\x61\x63\x75\x73\x20\x69\x61\x63\x75\x6C\x69\x73\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2E\x20\x4D\x61\x65\x63\x65\x6E\x61\x73\x20\x65\x67\x65\x73\x74\x61\x73\x20\x74\x6F\x72\x74\x6F\x72\x20\x65\x74\x20\x6E\x75\x6C\x6C\x61\x20\x64\x61\x70\x69\x62\x75\x73\x20\x76\x61\x72\x69\x75\x73\x2E\x20\x49\x6E\x20\x68\x61\x63\x20\x68\x61\x62\x69\x74\x61\x73\x73\x65\x20\x70\x6C\x61\x74\x65\x61\x20\x64\x69\x63\x74\x75\x6D\x73\x74\x2E\x4C\x6F\x72\x65\x6D\x20\x69\x70\x73\x75\x6D\x20\x64\x6F\x6C\x6F\x72\x20\x73\x69\x74\x20\x61\x6D\x65\x74\x2C\x20\x63\x6F\x6E\x73\x65\x63\x74\x65\x74\x75\x72\x20\x61\x64\x69\x70\x69\x73\x63\x69\x6E\x67\x20\x65\x6C\x69\x74\x2E\x20\x49\x6E\x74\x65\x67\x65\x72\x20\x66\x65\x75\x67\x69\x61\x74\x20\x65\x6C\x65\x69\x66\x65\x6E\x64\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x2E\x20\x50\x68\x61\x73\x65\x6C\x6C\x75\x73\x20\x74\x65\x6D\x70\x6F\x72\x20\x74\x75\x72\x70\x69\x73\x20\x65\x67\x65\x74\x20\x6D\x61\x67\x6E\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2C\x20\x65\x74\x20\x66\x69\x6E\x69\x62\x75\x73\x20\x6D\x61\x73\x73\x61\x20\x63\x6F\x6E\x76\x61\x6C\x6C\x69\x73\x2E\x20\x44\x6F\x6E\x65\x63\x20\x65\x67\x65\x74\x20\x6C\x61\x63\x69\x6E\x69\x61\x20\x6E\x69\x62\x68\x2E\x20\x55\x74\x20\x75\x74\x20\x63\x75\x72\x73\x75\x73\x20\x6F\x64\x69\x6F\x2E\x20\x51\x75\x69\x73\x71\x75\x65\x20\x69\x64\x20\x6A\x75\x73\x74\x6F\x20\x69\x6E\x74\x65\x72\x64\x75\x6D\x2C\x20\x6D\x61\x78\x69\x6D\x75\x73\x20\x65\x78\x20\x61\x2C\x20\x64\x61\x70\x69\x62\x75\x73\x20\x6C\x65\x6F\x2E\x20\x4E\x75\x6C\x6C\x61\x6D\x20\x6D\x61\x74\x74\x69\x73\x20\x61\x72\x63\x75\x20\x6E\x65\x63\x20\x6A\x75\x73\x74\x6F\x20\x76\x65\x68\x69\x63\x75\x6C\x61\x20\x70\x72\x65\x74\x69\x75\x6D\x2E\x20\x43\x75\x72\x61\x62\x69\x74\x75\x72\x20\x66\x65\x72\x6D\x65\x6E\x74\x75\x6D\x20\x71\x75\x61\x6D\x20\x61\x63\x20\x64\x6F\x6C\x6F\x72\x20\x76\x65\x6E\x65\x6E\x61\x74\x69\x73\x2C\x20\x76\x69\x74\x61\x65\x20\x73\x63\x65\x6C\x65\x72\x69\x73\x71\x75\x65\x20\x65\x78\x20\x70\x6F\x73\x75\x65\x72\x65\x2E\x20\x44\x6F\x6E\x65\x63\x20\x75\x74\x20\x61\x6E\x74\x65\x20\x70\x6F\x72\x74\x74\x69\x74\x6F\x72\x2C\x20\x75\x6C\x74\x72\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x54\x65\x78\x74\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x30\x64\x38\x62\x65\x30\x37\x39\x2D\x61\x37\x66\x64\x2D\x34\x62\x62\x36\x2D\x38\x64\x64\x61\x2D\x64\x64\x32\x33\x31\x62\x63\x30\x35\x66\x34\x66\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x3C\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x33\x3A\x34\x34\x3A\x32\x36\x20\x47\x4D\x54\x3C\x2F\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x31\x32\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x33\x3A\x34\x34\x3A\x32\x36\x20\x47\x4D\x54\x3C\x2F\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x41\x67\x41\x41\x41\x41\x4D\x41\x41\x41\x41\x41\x41\x41\x41\x41\x75\x55\x49\x4B\x6B\x57\x61\x75\x30\x67\x45\x3D\x3C\x2F\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x3C\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x33\x3A\x34\x34\x3A\x32\x39\x20\x47\x4D\x54\x3C\x2F\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x3C\x44\x65\x71\x75\x65\x75\x65\x43\x6F\x75\x6E\x74\x3E\x31\x3C\x2F\x44\x65\x71\x75\x65\x75\x65\x43\x6F\x75\x6E\x74\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x54\x65\x78\x74\x3E\x61\x6E\x64\x20\x6F\x74\x68\x65\x72\x20\x6D\x65\x73\x73\x61\x67\x65\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x54\x65\x78\x74\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E" + headers: + Cache-Control: + - no-cache + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 23:44:26 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 3890b676-0003-0012-1e66-ae36a5000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: updated message + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Y/zmFd4BK2FzcgDhxbum2PummIKv2ibUPVHoFlWjjjU= + Content-Length: + - "71" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 23:44:27 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-53storagemessagesuitetestputmessagepeekupdatedelete/messages/76100936-4786-465e-bb67-be934d828ecc?popreceipt=AgAAAAMAAAAAAAAAuUIKkWau0gE%3D&visibilitytimeout=2 + method: PUT + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 23:44:26 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Popreceipt: + - AwAAAAMAAAAAAAAAS6MfkWau0gEBAAAA + X-Ms-Request-Id: + - 3890b683-0003-0012-2b66-ae36a5000000 + X-Ms-Time-Next-Visible: + - Wed, 05 Apr 2017 23:44:29 GMT + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:U6xmldejHoOxAPeQq+GeQW5O/mRFtrQ0+Np6gOrOzKc= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 23:44:27 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-53storagemessagesuitetestputmessagepeekupdatedelete/messages/0d8be079-a7fd-4bb6-8dda-dd231bc05f4f?popreceipt=AgAAAAMAAAAAAAAAuUIKkWau0gE%3D + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 23:44:26 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 3890b68a-0003-0012-3066-ae36a5000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:YJcjKmyyQtwvD8cxzqQ0jmLFFxAS3/n4dIDE8rPRPtA= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 23:44:27 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-53storagemessagesuitetestputmessagepeekupdatedelete + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 23:44:26 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 3890b693-0003-0012-3866-ae36a5000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageQueueSuite/TestCreateQueue_DeleteQueue.yaml b/storage/recordings/StorageQueueSuite/TestCreateQueue_DeleteQueue.yaml new file mode 100644 index 000000000000..0bca299e21c4 --- /dev/null +++ b/storage/recordings/StorageQueueSuite/TestCreateQueue_DeleteQueue.yaml @@ -0,0 +1,60 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:D4YZwQMwu7TfF7r1N1+LUgAD7N+OhwSW/BE8o3lWzVU= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:31 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-45storagequeuesuitetestcreatequeuedeletequeue + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:31 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 564c770b-0003-006f-245c-aeaa6d000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:gAGWjSBnkYm7E/rNvaHRIBexGeYk+Ea1uzSnklzhQj8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:31 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-45storagequeuesuitetestcreatequeuedeletequeue + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:31 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 564c771a-0003-006f-305c-aeaa6d000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageQueueSuite/TestDeleteMessages.yaml b/storage/recordings/StorageQueueSuite/TestDeleteMessages.yaml new file mode 100644 index 000000000000..30f31fa37ef3 --- /dev/null +++ b/storage/recordings/StorageQueueSuite/TestDeleteMessages.yaml @@ -0,0 +1,151 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:nk53vfpVAAlmXhUHLbjmxYwikFX0egfiGIuCUMoSAw4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:31 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-36storagequeuesuitetestdeletemessages + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:31 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 564c771f-0003-006f-355c-aeaa6d000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: message + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:cFXXl/I/qw5yoeiGhGuUjUe/ZmLj7alVCpfq7sNkwa8= + Content-Length: + - "63" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:31 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-36storagequeuesuitetestdeletemessages/messages + method: POST + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x36\x64\x38\x63\x65\x63\x62\x39\x2D\x32\x36\x31\x35\x2D\x34\x61\x33\x31\x2D\x39\x36\x65\x35\x2D\x65\x38\x66\x64\x32\x64\x32\x35\x66\x38\x39\x34\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x3C\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x33\x31\x20\x47\x4D\x54\x3C\x2F\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x31\x32\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x33\x31\x20\x47\x4D\x54\x3C\x2F\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x41\x67\x41\x41\x41\x41\x4D\x41\x41\x41\x41\x41\x41\x41\x41\x41\x4D\x6C\x78\x73\x70\x31\x79\x75\x30\x67\x45\x3D\x3C\x2F\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x3C\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x33\x31\x20\x47\x4D\x54\x3C\x2F\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:31 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 564c772a-0003-006f-3e5c-aeaa6d000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Rr2aYJQASzTJlBYriLhh40lJApOaAXPNUKjryGC/gec= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:31 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-36storagequeuesuitetestdeletemessages/messages?visibilitytimeout=1 + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x36\x64\x38\x63\x65\x63\x62\x39\x2D\x32\x36\x31\x35\x2D\x34\x61\x33\x31\x2D\x39\x36\x65\x35\x2D\x65\x38\x66\x64\x32\x64\x32\x35\x66\x38\x39\x34\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x3C\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x33\x31\x20\x47\x4D\x54\x3C\x2F\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x31\x32\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x33\x31\x20\x47\x4D\x54\x3C\x2F\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x41\x67\x41\x41\x41\x41\x4D\x41\x41\x41\x41\x41\x41\x41\x41\x41\x39\x78\x38\x4D\x71\x46\x79\x75\x30\x67\x45\x3D\x3C\x2F\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x3C\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x33\x32\x20\x47\x4D\x54\x3C\x2F\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x3C\x44\x65\x71\x75\x65\x75\x65\x43\x6F\x75\x6E\x74\x3E\x31\x3C\x2F\x44\x65\x71\x75\x65\x75\x65\x43\x6F\x75\x6E\x74\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x54\x65\x78\x74\x3E\x6D\x65\x73\x73\x61\x67\x65\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x54\x65\x78\x74\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E" + headers: + Cache-Control: + - no-cache + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:31 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 564c7737-0003-006f-4b5c-aeaa6d000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:pPce1MGXcTx4Gs8kUY8I84n0HJjzd1ISGxkoZuGtehE= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:32 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-36storagequeuesuitetestdeletemessages/messages/6d8cecb9-2615-4a31-96e5-e8fd2d25f894?popreceipt=AgAAAAMAAAAAAAAA9x8MqFyu0gE%3D + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:31 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 564c7742-0003-006f-545c-aeaa6d000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:v95Fmln4vyQ4P8wWzpcYVx0//WUTk6X5p9oMudWFAf8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:32 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-36storagequeuesuitetestdeletemessages + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:31 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 564c7746-0003-006f-585c-aeaa6d000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageQueueSuite/TestGetMessages.yaml b/storage/recordings/StorageQueueSuite/TestGetMessages.yaml new file mode 100644 index 000000000000..9f13712e786e --- /dev/null +++ b/storage/recordings/StorageQueueSuite/TestGetMessages.yaml @@ -0,0 +1,215 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:JxkXabRowDdtuodGGJteSMckJ2MCrKhoweTsGlYDmF8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Thu, 06 Apr 2017 18:55:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-33storagequeuesuitetestgetmessages + method: PUT + response: + body: "" + headers: + Date: + - Thu, 06 Apr 2017 18:55:29 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 9c31c2c7-0003-0018-5807-af2f2c000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: message + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:hak/DoI1TggDfL4G9OJC0EpO3E+RArNwIDuB5o8ULNU= + Content-Length: + - "63" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Thu, 06 Apr 2017 18:55:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-33storagequeuesuitetestgetmessages/messages + method: POST + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x37\x65\x30\x34\x62\x30\x38\x62\x2D\x62\x36\x32\x31\x2D\x34\x34\x36\x30\x2D\x39\x30\x39\x62\x2D\x65\x39\x34\x30\x64\x62\x30\x63\x33\x37\x62\x36\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x3C\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x54\x68\x75\x2C\x20\x30\x36\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x35\x3A\x33\x30\x20\x47\x4D\x54\x3C\x2F\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x54\x68\x75\x2C\x20\x31\x33\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x35\x3A\x33\x30\x20\x47\x4D\x54\x3C\x2F\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x41\x67\x41\x41\x41\x41\x4D\x41\x41\x41\x41\x41\x41\x41\x41\x41\x45\x74\x63\x53\x58\x51\x65\x76\x30\x67\x45\x3D\x3C\x2F\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x3C\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x54\x68\x75\x2C\x20\x30\x36\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x35\x3A\x33\x30\x20\x47\x4D\x54\x3C\x2F\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E" + headers: + Content-Type: + - application/xml + Date: + - Thu, 06 Apr 2017 18:55:29 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 9c31c2d0-0003-0018-5e07-af2f2c000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: message + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:hak/DoI1TggDfL4G9OJC0EpO3E+RArNwIDuB5o8ULNU= + Content-Length: + - "63" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Thu, 06 Apr 2017 18:55:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-33storagequeuesuitetestgetmessages/messages + method: POST + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x39\x31\x65\x36\x30\x66\x33\x61\x2D\x32\x34\x32\x62\x2D\x34\x37\x30\x64\x2D\x39\x32\x34\x35\x2D\x34\x33\x31\x36\x66\x30\x38\x32\x39\x37\x38\x38\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x3C\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x54\x68\x75\x2C\x20\x30\x36\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x35\x3A\x33\x30\x20\x47\x4D\x54\x3C\x2F\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x54\x68\x75\x2C\x20\x31\x33\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x35\x3A\x33\x30\x20\x47\x4D\x54\x3C\x2F\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x41\x67\x41\x41\x41\x41\x4D\x41\x41\x41\x41\x41\x41\x41\x41\x41\x4F\x4E\x30\x5A\x58\x51\x65\x76\x30\x67\x45\x3D\x3C\x2F\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x3C\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x54\x68\x75\x2C\x20\x30\x36\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x35\x3A\x33\x30\x20\x47\x4D\x54\x3C\x2F\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E" + headers: + Content-Type: + - application/xml + Date: + - Thu, 06 Apr 2017 18:55:29 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 9c31c2d9-0003-0018-6607-af2f2c000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: message + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:hak/DoI1TggDfL4G9OJC0EpO3E+RArNwIDuB5o8ULNU= + Content-Length: + - "63" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Thu, 06 Apr 2017 18:55:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-33storagequeuesuitetestgetmessages/messages + method: POST + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x32\x63\x35\x38\x33\x30\x35\x62\x2D\x61\x64\x65\x61\x2D\x34\x66\x37\x37\x2D\x39\x31\x61\x31\x2D\x64\x38\x34\x38\x34\x37\x31\x38\x62\x36\x35\x36\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x3C\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x54\x68\x75\x2C\x20\x30\x36\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x35\x3A\x33\x30\x20\x47\x4D\x54\x3C\x2F\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x54\x68\x75\x2C\x20\x31\x33\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x35\x3A\x33\x30\x20\x47\x4D\x54\x3C\x2F\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x41\x67\x41\x41\x41\x41\x4D\x41\x41\x41\x41\x41\x41\x41\x41\x41\x6B\x44\x45\x68\x58\x51\x65\x76\x30\x67\x45\x3D\x3C\x2F\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x3C\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x54\x68\x75\x2C\x20\x30\x36\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x35\x3A\x33\x30\x20\x47\x4D\x54\x3C\x2F\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E" + headers: + Content-Type: + - application/xml + Date: + - Thu, 06 Apr 2017 18:55:29 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 9c31c2e2-0003-0018-6f07-af2f2c000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: message + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:hak/DoI1TggDfL4G9OJC0EpO3E+RArNwIDuB5o8ULNU= + Content-Length: + - "63" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Thu, 06 Apr 2017 18:55:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-33storagequeuesuitetestgetmessages/messages + method: POST + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x63\x37\x37\x31\x34\x61\x39\x61\x2D\x64\x37\x39\x38\x2D\x34\x36\x31\x32\x2D\x61\x63\x66\x37\x2D\x37\x36\x39\x32\x64\x61\x66\x64\x62\x66\x63\x39\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x3C\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x54\x68\x75\x2C\x20\x30\x36\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x35\x3A\x33\x30\x20\x47\x4D\x54\x3C\x2F\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x54\x68\x75\x2C\x20\x31\x33\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x35\x3A\x33\x30\x20\x47\x4D\x54\x3C\x2F\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x41\x67\x41\x41\x41\x41\x4D\x41\x41\x41\x41\x41\x41\x41\x41\x41\x7A\x56\x34\x6F\x58\x51\x65\x76\x30\x67\x45\x3D\x3C\x2F\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x3C\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x54\x68\x75\x2C\x20\x30\x36\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x35\x3A\x33\x30\x20\x47\x4D\x54\x3C\x2F\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E" + headers: + Content-Type: + - application/xml + Date: + - Thu, 06 Apr 2017 18:55:29 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 9c31c2ee-0003-0018-7a07-af2f2c000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:oxBqsKflHYklkTu7gOASUPLnlgjai3dpfaw3ot/eFCQ= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Thu, 06 Apr 2017 18:55:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-33storagequeuesuitetestgetmessages/messages?numofmessages=4 + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x37\x65\x30\x34\x62\x30\x38\x62\x2D\x62\x36\x32\x31\x2D\x34\x34\x36\x30\x2D\x39\x30\x39\x62\x2D\x65\x39\x34\x30\x64\x62\x30\x63\x33\x37\x62\x36\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x3C\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x54\x68\x75\x2C\x20\x30\x36\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x35\x3A\x33\x30\x20\x47\x4D\x54\x3C\x2F\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x54\x68\x75\x2C\x20\x31\x33\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x35\x3A\x33\x30\x20\x47\x4D\x54\x3C\x2F\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x41\x67\x41\x41\x41\x41\x4D\x41\x41\x41\x41\x41\x41\x41\x41\x41\x2B\x41\x63\x52\x62\x77\x65\x76\x30\x67\x45\x3D\x3C\x2F\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x3C\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x54\x68\x75\x2C\x20\x30\x36\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x36\x3A\x30\x31\x20\x47\x4D\x54\x3C\x2F\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x3C\x44\x65\x71\x75\x65\x75\x65\x43\x6F\x75\x6E\x74\x3E\x31\x3C\x2F\x44\x65\x71\x75\x65\x75\x65\x43\x6F\x75\x6E\x74\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x54\x65\x78\x74\x3E\x6D\x65\x73\x73\x61\x67\x65\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x54\x65\x78\x74\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x39\x31\x65\x36\x30\x66\x33\x61\x2D\x32\x34\x32\x62\x2D\x34\x37\x30\x64\x2D\x39\x32\x34\x35\x2D\x34\x33\x31\x36\x66\x30\x38\x32\x39\x37\x38\x38\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x3C\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x54\x68\x75\x2C\x20\x30\x36\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x35\x3A\x33\x30\x20\x47\x4D\x54\x3C\x2F\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x54\x68\x75\x2C\x20\x31\x33\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x35\x3A\x33\x30\x20\x47\x4D\x54\x3C\x2F\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x41\x67\x41\x41\x41\x41\x4D\x41\x41\x41\x41\x41\x41\x41\x41\x41\x2B\x41\x63\x52\x62\x77\x65\x76\x30\x67\x45\x3D\x3C\x2F\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x3C\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x54\x68\x75\x2C\x20\x30\x36\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x36\x3A\x30\x31\x20\x47\x4D\x54\x3C\x2F\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x3C\x44\x65\x71\x75\x65\x75\x65\x43\x6F\x75\x6E\x74\x3E\x31\x3C\x2F\x44\x65\x71\x75\x65\x75\x65\x43\x6F\x75\x6E\x74\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x54\x65\x78\x74\x3E\x6D\x65\x73\x73\x61\x67\x65\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x54\x65\x78\x74\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x32\x63\x35\x38\x33\x30\x35\x62\x2D\x61\x64\x65\x61\x2D\x34\x66\x37\x37\x2D\x39\x31\x61\x31\x2D\x64\x38\x34\x38\x34\x37\x31\x38\x62\x36\x35\x36\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x3C\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x54\x68\x75\x2C\x20\x30\x36\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x35\x3A\x33\x30\x20\x47\x4D\x54\x3C\x2F\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x54\x68\x75\x2C\x20\x31\x33\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x35\x3A\x33\x30\x20\x47\x4D\x54\x3C\x2F\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x41\x67\x41\x41\x41\x41\x4D\x41\x41\x41\x41\x41\x41\x41\x41\x41\x2B\x41\x63\x52\x62\x77\x65\x76\x30\x67\x45\x3D\x3C\x2F\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x3C\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x54\x68\x75\x2C\x20\x30\x36\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x36\x3A\x30\x31\x20\x47\x4D\x54\x3C\x2F\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x3C\x44\x65\x71\x75\x65\x75\x65\x43\x6F\x75\x6E\x74\x3E\x31\x3C\x2F\x44\x65\x71\x75\x65\x75\x65\x43\x6F\x75\x6E\x74\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x54\x65\x78\x74\x3E\x6D\x65\x73\x73\x61\x67\x65\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x54\x65\x78\x74\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x63\x37\x37\x31\x34\x61\x39\x61\x2D\x64\x37\x39\x38\x2D\x34\x36\x31\x32\x2D\x61\x63\x66\x37\x2D\x37\x36\x39\x32\x64\x61\x66\x64\x62\x66\x63\x39\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x3C\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x54\x68\x75\x2C\x20\x30\x36\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x35\x3A\x33\x30\x20\x47\x4D\x54\x3C\x2F\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x54\x68\x75\x2C\x20\x31\x33\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x35\x3A\x33\x30\x20\x47\x4D\x54\x3C\x2F\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x41\x67\x41\x41\x41\x41\x4D\x41\x41\x41\x41\x41\x41\x41\x41\x41\x2B\x41\x63\x52\x62\x77\x65\x76\x30\x67\x45\x3D\x3C\x2F\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x3C\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x54\x68\x75\x2C\x20\x30\x36\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x31\x38\x3A\x35\x36\x3A\x30\x31\x20\x47\x4D\x54\x3C\x2F\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x3C\x44\x65\x71\x75\x65\x75\x65\x43\x6F\x75\x6E\x74\x3E\x31\x3C\x2F\x44\x65\x71\x75\x65\x75\x65\x43\x6F\x75\x6E\x74\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x54\x65\x78\x74\x3E\x6D\x65\x73\x73\x61\x67\x65\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x54\x65\x78\x74\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E" + headers: + Cache-Control: + - no-cache + Content-Type: + - application/xml + Date: + - Thu, 06 Apr 2017 18:55:29 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 9c31c2f6-0003-0018-0207-af2f2c000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:K0tHMVDU9HaCDtqKfzgOW+LfaOOkaZ7DTu4AfqvwuZ4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Thu, 06 Apr 2017 18:55:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-33storagequeuesuitetestgetmessages + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Thu, 06 Apr 2017 18:55:30 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 9c31c2fb-0003-0018-0707-af2f2c000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageQueueSuite/TestQueueExists.yaml b/storage/recordings/StorageQueueSuite/TestQueueExists.yaml new file mode 100644 index 000000000000..7946d10d06ea --- /dev/null +++ b/storage/recordings/StorageQueueSuite/TestQueueExists.yaml @@ -0,0 +1,122 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:GRCOP7MGPV+J+oykE99rS+REBONe62B2yoZYcYGqyy4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Thu, 06 Apr 2017 18:55:19 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-nonexistent33storagequeuesuitetestqueueexists?comp=metadata + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x72\x72\x6F\x72\x3E\x3C\x43\x6F\x64\x65\x3E\x51\x75\x65\x75\x65\x4E\x6F\x74\x46\x6F\x75\x6E\x64\x3C\x2F\x43\x6F\x64\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x3E\x54\x68\x65\x20\x73\x70\x65\x63\x69\x66\x69\x65\x64\x20\x71\x75\x65\x75\x65\x20\x64\x6F\x65\x73\x20\x6E\x6F\x74\x20\x65\x78\x69\x73\x74\x2E\n\x52\x65\x71\x75\x65\x73\x74\x49\x64\x3A\x62\x32\x32\x33\x32\x64\x61\x36\x2D\x30\x30\x30\x33\x2D\x30\x30\x32\x32\x2D\x33\x39\x30\x37\x2D\x61\x66\x36\x63\x38\x66\x30\x30\x30\x30\x30\x30\n\x54\x69\x6D\x65\x3A\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x36\x54\x31\x38\x3A\x35\x35\x3A\x31\x39\x2E\x35\x30\x36\x37\x32\x33\x37\x5A\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x45\x72\x72\x6F\x72\x3E" + headers: + Content-Length: + - "217" + Content-Type: + - application/xml + Date: + - Thu, 06 Apr 2017 18:55:19 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - b2232da6-0003-0022-3907-af6c8f000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The specified queue does not exist. + code: 404 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:uuc+semVb2KEuBSqlm3+lVnJTyHI9D4zGxICZ0XFQHk= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Thu, 06 Apr 2017 18:55:19 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-exisiting33storagequeuesuitetestqueueexists + method: PUT + response: + body: "" + headers: + Date: + - Thu, 06 Apr 2017 18:55:19 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - b2232db5-0003-0022-4507-af6c8f000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Zt9POEMxLUlhP27KMXetFPkPFhwmgFWUwUAsk3J9YfU= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Thu, 06 Apr 2017 18:55:19 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-exisiting33storagequeuesuitetestqueueexists?comp=metadata + method: GET + response: + body: "" + headers: + Cache-Control: + - no-cache + Date: + - Thu, 06 Apr 2017 18:55:19 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Approximate-Messages-Count: + - "0" + X-Ms-Request-Id: + - b2232dfc-0003-0022-0907-af6c8f000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:SH91Rf0ONFITAFOdY/1AxL5Xr8p0jYotqPqOnSbu8HI= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Thu, 06 Apr 2017 18:55:20 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-exisiting33storagequeuesuitetestqueueexists + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Thu, 06 Apr 2017 18:55:19 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - b2232e08-0003-0022-1407-af6c8f000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageQueueSuite/Test_GetMetadata_GetApproximateCount.yaml b/storage/recordings/StorageQueueSuite/Test_GetMetadata_GetApproximateCount.yaml new file mode 100644 index 000000000000..cffd10776412 --- /dev/null +++ b/storage/recordings/StorageQueueSuite/Test_GetMetadata_GetApproximateCount.yaml @@ -0,0 +1,271 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:6gc6xQ0Q9A3sfOfDo1I0XXDi5RV5/y/t2EHE/OPBD6s= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:33 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-154storagequeuesuitetestgetmetadatagetapproximatecount + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:33 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 564c780a-0003-006f-795c-aeaa6d000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:DFhzb0xiv22eBYhV3ytE1ByYry3A7VWJdXEYPs1RJ+c= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:33 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-154storagequeuesuitetestgetmetadatagetapproximatecount?comp=metadata + method: GET + response: + body: "" + headers: + Cache-Control: + - no-cache + Date: + - Wed, 05 Apr 2017 22:33:33 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Approximate-Messages-Count: + - "0" + X-Ms-Request-Id: + - 564c780d-0003-006f-7b5c-aeaa6d000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:XSgbYf86D1ecs3YMqCKihilyvh/sV0J1KuFOY+g9U68= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:33 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-254storagequeuesuitetestgetmetadatagetapproximatecount + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:33 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 564c7812-0003-006f-7f5c-aeaa6d000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: lolrofl + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:HIMSaKmxDcKBGcnJyZcHKyFWjRKXHoJv/3tvrq40qhA= + Content-Length: + - "63" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:33 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-254storagequeuesuitetestgetmetadatagetapproximatecount/messages + method: POST + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x37\x64\x34\x30\x30\x30\x64\x37\x2D\x34\x37\x65\x30\x2D\x34\x34\x65\x30\x2D\x61\x61\x32\x63\x2D\x64\x35\x63\x39\x61\x39\x39\x63\x32\x36\x32\x34\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x3C\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x33\x33\x20\x47\x4D\x54\x3C\x2F\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x31\x32\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x33\x33\x20\x47\x4D\x54\x3C\x2F\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x41\x67\x41\x41\x41\x41\x4D\x41\x41\x41\x41\x41\x41\x41\x41\x41\x39\x41\x32\x65\x71\x46\x79\x75\x30\x67\x45\x3D\x3C\x2F\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x3C\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x33\x33\x20\x47\x4D\x54\x3C\x2F\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:33 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 564c781e-0003-006f-095c-aeaa6d000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: lolrofl + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:gC6RSMK/qg1jIfnV5TIs4iXFPDSXJbyEqaxALGBfpC8= + Content-Length: + - "63" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:34 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-254storagequeuesuitetestgetmetadatagetapproximatecount/messages + method: POST + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x61\x38\x61\x34\x36\x61\x61\x36\x2D\x61\x39\x65\x66\x2D\x34\x66\x62\x64\x2D\x38\x31\x32\x31\x2D\x64\x39\x38\x31\x64\x36\x36\x63\x66\x66\x36\x37\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x3C\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x33\x33\x20\x47\x4D\x54\x3C\x2F\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x31\x32\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x33\x33\x20\x47\x4D\x54\x3C\x2F\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x41\x67\x41\x41\x41\x41\x4D\x41\x41\x41\x41\x41\x41\x41\x41\x41\x4C\x44\x75\x6C\x71\x46\x79\x75\x30\x67\x45\x3D\x3C\x2F\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x3C\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x33\x33\x20\x47\x4D\x54\x3C\x2F\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:33 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 564c7828-0003-006f-135c-aeaa6d000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: lolrofl + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:gC6RSMK/qg1jIfnV5TIs4iXFPDSXJbyEqaxALGBfpC8= + Content-Length: + - "63" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:34 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-254storagequeuesuitetestgetmetadatagetapproximatecount/messages + method: POST + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E\x3C\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x34\x39\x35\x37\x31\x37\x31\x30\x2D\x66\x61\x36\x39\x2D\x34\x33\x62\x30\x2D\x39\x37\x66\x36\x2D\x35\x62\x64\x65\x39\x62\x64\x62\x37\x34\x32\x66\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x49\x64\x3E\x3C\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x33\x33\x20\x47\x4D\x54\x3C\x2F\x49\x6E\x73\x65\x72\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x57\x65\x64\x2C\x20\x31\x32\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x33\x33\x20\x47\x4D\x54\x3C\x2F\x45\x78\x70\x69\x72\x61\x74\x69\x6F\x6E\x54\x69\x6D\x65\x3E\x3C\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x41\x67\x41\x41\x41\x41\x4D\x41\x41\x41\x41\x41\x41\x41\x41\x41\x4D\x68\x71\x73\x71\x46\x79\x75\x30\x67\x45\x3D\x3C\x2F\x50\x6F\x70\x52\x65\x63\x65\x69\x70\x74\x3E\x3C\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x33\x33\x20\x47\x4D\x54\x3C\x2F\x54\x69\x6D\x65\x4E\x65\x78\x74\x56\x69\x73\x69\x62\x6C\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x51\x75\x65\x75\x65\x4D\x65\x73\x73\x61\x67\x65\x73\x4C\x69\x73\x74\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:33 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 564c7830-0003-006f-1a5c-aeaa6d000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:NnaoW4ra9PGN+mPPDo/aqbkebIcYOhcvSQk8+9Zgito= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:35 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-254storagequeuesuitetestgetmetadatagetapproximatecount?comp=metadata + method: GET + response: + body: "" + headers: + Cache-Control: + - no-cache + Date: + - Wed, 05 Apr 2017 22:33:34 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Approximate-Messages-Count: + - "3" + X-Ms-Request-Id: + - 564c78c2-0003-006f-185c-aeaa6d000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:41EP0/eIM5i2dObwkAcXsRL0Ac/GSGlkI35lPG0JR3c= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:35 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-254storagequeuesuitetestgetmetadatagetapproximatecount + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:34 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 564c78c6-0003-006f-1c5c-aeaa6d000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:B/U84Unufpi1DoUIx1z9Nc1xn5sDSryVvcEGOBhHY5Q= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:35 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-154storagequeuesuitetestgetmetadatagetapproximatecount + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:34 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 564c78cd-0003-006f-215c-aeaa6d000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageQueueSuite/Test_GetPermissionsAllTrueNoTimeout.yaml b/storage/recordings/StorageQueueSuite/Test_GetPermissionsAllTrueNoTimeout.yaml new file mode 100644 index 000000000000..f423045c31be --- /dev/null +++ b/storage/recordings/StorageQueueSuite/Test_GetPermissionsAllTrueNoTimeout.yaml @@ -0,0 +1,122 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:zo8JEyh9EENVBRdXExInSvutVAgraQ6OwMIGqlVvEsQ= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:27 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-153storagequeuesuitetestgetpermissionsalltruenotimeout + method: PUT + response: + body: "" + headers: + Date: + - Fri, 21 Apr 2017 07:03:27 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108ec6d-0003-0000-156d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: GolangRocksOnAzure2050-12-20T21:55:00Z2051-12-20T21:55:00Zraup + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:W4khUmbLXWT3SFalpmqXlLsy05fZ88kVxcAIBcOKj54= + Content-Length: + - "233" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:28 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-153storagequeuesuitetestgetpermissionsalltruenotimeout?comp=acl + method: PUT + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Fri, 21 Apr 2017 07:03:28 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108ec7b-0003-0000-176d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Uoena/8a370/fP/wAcFFi3vRj1P0l5S8pORPgxAB6Yo= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:28 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-153storagequeuesuitetestgetpermissionsalltruenotimeout?comp=acl + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x73\x3E\x3C\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x3E\x3C\x49\x64\x3E\x47\x6F\x6C\x61\x6E\x67\x52\x6F\x63\x6B\x73\x4F\x6E\x41\x7A\x75\x72\x65\x3C\x2F\x49\x64\x3E\x3C\x41\x63\x63\x65\x73\x73\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x53\x74\x61\x72\x74\x3E\x32\x30\x35\x30\x2D\x31\x32\x2D\x32\x30\x54\x32\x31\x3A\x35\x35\x3A\x30\x30\x2E\x30\x30\x30\x30\x30\x30\x30\x5A\x3C\x2F\x53\x74\x61\x72\x74\x3E\x3C\x45\x78\x70\x69\x72\x79\x3E\x32\x30\x35\x31\x2D\x31\x32\x2D\x32\x30\x54\x32\x31\x3A\x35\x35\x3A\x30\x30\x2E\x30\x30\x30\x30\x30\x30\x30\x5A\x3C\x2F\x45\x78\x70\x69\x72\x79\x3E\x3C\x50\x65\x72\x6D\x69\x73\x73\x69\x6F\x6E\x3E\x72\x70\x61\x75\x3C\x2F\x50\x65\x72\x6D\x69\x73\x73\x69\x6F\x6E\x3E\x3C\x2F\x41\x63\x63\x65\x73\x73\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x2F\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x3E\x3C\x2F\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x73\x3E" + headers: + Cache-Control: + - no-cache + Content-Type: + - application/xml + Date: + - Fri, 21 Apr 2017 07:03:28 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108ec80-0003-0000-1a6d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:gn0ySQpnA/3nw6fVQ8Gcqa8HM70GY+veTfaKLT0hr6I= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:28 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-153storagequeuesuitetestgetpermissionsalltruenotimeout + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Fri, 21 Apr 2017 07:03:28 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108ec86-0003-0000-1e6d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageQueueSuite/Test_GetPermissionsAllTrueWithTimeout.yaml b/storage/recordings/StorageQueueSuite/Test_GetPermissionsAllTrueWithTimeout.yaml new file mode 100644 index 000000000000..1086f4515d81 --- /dev/null +++ b/storage/recordings/StorageQueueSuite/Test_GetPermissionsAllTrueWithTimeout.yaml @@ -0,0 +1,122 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:9Q+joySVquKCbapR9Wmo7syvk6Oc4LsuzqwnLqtAEcU= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:29 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-155storagequeuesuitetestgetpermissionsalltruewithtimeout + method: PUT + response: + body: "" + headers: + Date: + - Fri, 21 Apr 2017 07:03:28 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108ec87-0003-0000-1f6d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: GolangRocksOnAzure2050-12-20T21:55:00Z2051-12-20T21:55:00Zraup + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:PEb0gu18mlZQ/7Exe4we9OUAESVabkqjgw7U3KVSyYg= + Content-Length: + - "233" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:29 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-155storagequeuesuitetestgetpermissionsalltruewithtimeout?comp=acl + method: PUT + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Fri, 21 Apr 2017 07:03:28 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108ec8c-0003-0000-226d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:7AWA9mMpPC9xC+6FvjOgipeAFVpSVwTBrsULXmYyKHQ= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:29 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-155storagequeuesuitetestgetpermissionsalltruewithtimeout?comp=acl&timeout=30 + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x73\x3E\x3C\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x3E\x3C\x49\x64\x3E\x47\x6F\x6C\x61\x6E\x67\x52\x6F\x63\x6B\x73\x4F\x6E\x41\x7A\x75\x72\x65\x3C\x2F\x49\x64\x3E\x3C\x41\x63\x63\x65\x73\x73\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x53\x74\x61\x72\x74\x3E\x32\x30\x35\x30\x2D\x31\x32\x2D\x32\x30\x54\x32\x31\x3A\x35\x35\x3A\x30\x30\x2E\x30\x30\x30\x30\x30\x30\x30\x5A\x3C\x2F\x53\x74\x61\x72\x74\x3E\x3C\x45\x78\x70\x69\x72\x79\x3E\x32\x30\x35\x31\x2D\x31\x32\x2D\x32\x30\x54\x32\x31\x3A\x35\x35\x3A\x30\x30\x2E\x30\x30\x30\x30\x30\x30\x30\x5A\x3C\x2F\x45\x78\x70\x69\x72\x79\x3E\x3C\x50\x65\x72\x6D\x69\x73\x73\x69\x6F\x6E\x3E\x72\x70\x61\x75\x3C\x2F\x50\x65\x72\x6D\x69\x73\x73\x69\x6F\x6E\x3E\x3C\x2F\x41\x63\x63\x65\x73\x73\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x2F\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x3E\x3C\x2F\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x73\x3E" + headers: + Cache-Control: + - no-cache + Content-Type: + - application/xml + Date: + - Fri, 21 Apr 2017 07:03:29 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108ec90-0003-0000-256d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:/OYpS0m+LyfVRSl0HujlyefeQEADxAq6TISOLSL+p2A= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:29 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-155storagequeuesuitetestgetpermissionsalltruewithtimeout + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Fri, 21 Apr 2017 07:03:29 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108ec92-0003-0000-276d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageQueueSuite/Test_GetPermissionsAlternateTrueNoTimeout.yaml b/storage/recordings/StorageQueueSuite/Test_GetPermissionsAlternateTrueNoTimeout.yaml new file mode 100644 index 000000000000..8109fdc45c00 --- /dev/null +++ b/storage/recordings/StorageQueueSuite/Test_GetPermissionsAlternateTrueNoTimeout.yaml @@ -0,0 +1,122 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:9mej1IZVWcP2rwmRp4t5Uz+T09tOKROi6s31ko0AkRw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:29 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-159storagequeuesuitetestgetpermissionsalternatetruenotime + method: PUT + response: + body: "" + headers: + Date: + - Fri, 21 Apr 2017 07:03:29 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108ec99-0003-0000-2c6d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: GolangRocksOnAzure2050-12-20T21:55:00Z2051-12-20T21:55:00Zru + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:SGaRGrq/vLK5mGuosXhmXBfKpvtSw9GTQgP1h3lIq3Q= + Content-Length: + - "231" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:29 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-159storagequeuesuitetestgetpermissionsalternatetruenotime?comp=acl + method: PUT + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Fri, 21 Apr 2017 07:03:29 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108eca0-0003-0000-306d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:DgHuYSoMqRnfBS9hXwSuH2GVW/zyhXBO/UGlOK5Im5U= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-159storagequeuesuitetestgetpermissionsalternatetruenotime?comp=acl + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x73\x3E\x3C\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x3E\x3C\x49\x64\x3E\x47\x6F\x6C\x61\x6E\x67\x52\x6F\x63\x6B\x73\x4F\x6E\x41\x7A\x75\x72\x65\x3C\x2F\x49\x64\x3E\x3C\x41\x63\x63\x65\x73\x73\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x53\x74\x61\x72\x74\x3E\x32\x30\x35\x30\x2D\x31\x32\x2D\x32\x30\x54\x32\x31\x3A\x35\x35\x3A\x30\x30\x2E\x30\x30\x30\x30\x30\x30\x30\x5A\x3C\x2F\x53\x74\x61\x72\x74\x3E\x3C\x45\x78\x70\x69\x72\x79\x3E\x32\x30\x35\x31\x2D\x31\x32\x2D\x32\x30\x54\x32\x31\x3A\x35\x35\x3A\x30\x30\x2E\x30\x30\x30\x30\x30\x30\x30\x5A\x3C\x2F\x45\x78\x70\x69\x72\x79\x3E\x3C\x50\x65\x72\x6D\x69\x73\x73\x69\x6F\x6E\x3E\x72\x75\x3C\x2F\x50\x65\x72\x6D\x69\x73\x73\x69\x6F\x6E\x3E\x3C\x2F\x41\x63\x63\x65\x73\x73\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x2F\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x3E\x3C\x2F\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x73\x3E" + headers: + Cache-Control: + - no-cache + Content-Type: + - application/xml + Date: + - Fri, 21 Apr 2017 07:03:29 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108eca5-0003-0000-336d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:78naDiGZFGzp2RY26SWjXygRMzrwJBIO1z7MI5GZ+2Q= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-159storagequeuesuitetestgetpermissionsalternatetruenotime + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Fri, 21 Apr 2017 07:03:29 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108ecab-0003-0000-376d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageQueueSuite/Test_SetMetadataGetMetadata_Roundtrips.yaml b/storage/recordings/StorageQueueSuite/Test_SetMetadataGetMetadata_Roundtrips.yaml new file mode 100644 index 000000000000..00c08ca935e7 --- /dev/null +++ b/storage/recordings/StorageQueueSuite/Test_SetMetadataGetMetadata_Roundtrips.yaml @@ -0,0 +1,128 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:9STNQNuRgLtLXSuzN/CNnvtS24JQyAfjC+BwgHyxYbs= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Thu, 06 Apr 2017 18:55:21 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-156storagequeuesuitetestsetmetadatagetmetadataroundtrips + method: PUT + response: + body: "" + headers: + Date: + - Thu, 06 Apr 2017 18:55:20 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - b2232eb6-0003-0022-3007-af6c8f000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:TmUzCmzJ2i4DrPUGOUCtwrM0m64EwhuRM6wiO4+qwkw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Thu, 06 Apr 2017 18:55:21 GMT + X-Ms-Meta-Lol1: + - rofl1 + X-Ms-Meta-Lolbaz: + - rofl + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-156storagequeuesuitetestsetmetadatagetmetadataroundtrips?comp=metadata + method: PUT + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Thu, 06 Apr 2017 18:55:20 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - b2232ec5-0003-0022-3d07-af6c8f000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Nit/ykJJuSLD7zD8IRtMk0V0eda7m0FkfAHwpXJz0lY= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Thu, 06 Apr 2017 18:55:21 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-156storagequeuesuitetestsetmetadatagetmetadataroundtrips?comp=metadata + method: GET + response: + body: "" + headers: + Cache-Control: + - no-cache + Date: + - Thu, 06 Apr 2017 18:55:20 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Approximate-Messages-Count: + - "0" + X-Ms-Meta-Lol1: + - rofl1 + X-Ms-Meta-Lolbaz: + - rofl + X-Ms-Request-Id: + - b2232ed4-0003-0022-4b07-af6c8f000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:ce17BEy8cbRpDaR6KQos2YG0Lu0vIC5Kpwp7EE6LYJs= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Thu, 06 Apr 2017 18:55:21 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-156storagequeuesuitetestsetmetadatagetmetadataroundtrips + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Thu, 06 Apr 2017 18:55:20 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - b2232edf-0003-0022-5507-af6c8f000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageQueueSuite/Test_SetPermissionsAllTrueNoTimeout.yaml b/storage/recordings/StorageQueueSuite/Test_SetPermissionsAllTrueNoTimeout.yaml new file mode 100644 index 000000000000..c171a1420e3e --- /dev/null +++ b/storage/recordings/StorageQueueSuite/Test_SetPermissionsAllTrueNoTimeout.yaml @@ -0,0 +1,91 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:V0atokOdklBzQp3ZVD4bK3BVEr9OxkmPis8Ul3vxV5o= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-153storagequeuesuitetestsetpermissionsalltruenotimeout + method: PUT + response: + body: "" + headers: + Date: + - Fri, 21 Apr 2017 07:03:30 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108ecac-0003-0000-386d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: GolangRocksOnAzure2050-12-20T21:55:06Z2051-12-20T21:55:06Zraup + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:td2Y9/rBg/uQpGjNS6L4Bhp3Ks25YO+NSvC8M7XPEd4= + Content-Length: + - "233" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-153storagequeuesuitetestsetpermissionsalltruenotimeout?comp=acl + method: PUT + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Fri, 21 Apr 2017 07:03:30 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108ecb2-0003-0000-3b6d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Z4/LFDk3Z1yr2je7MHza3EaYEi+u0r5uyH/7LkL5MKw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-153storagequeuesuitetestsetpermissionsalltruenotimeout + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Fri, 21 Apr 2017 07:03:30 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108ecb5-0003-0000-3d6d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageQueueSuite/Test_SetPermissionsAllTrueWithTimeout.yaml b/storage/recordings/StorageQueueSuite/Test_SetPermissionsAllTrueWithTimeout.yaml new file mode 100644 index 000000000000..cc9afee4c68c --- /dev/null +++ b/storage/recordings/StorageQueueSuite/Test_SetPermissionsAllTrueWithTimeout.yaml @@ -0,0 +1,91 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:FWXT3whjAM+ap8DYMpl0BOA8jY8kG1LTKI9lAxqH2ec= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:30 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-155storagequeuesuitetestsetpermissionsalltruewithtimeout + method: PUT + response: + body: "" + headers: + Date: + - Fri, 21 Apr 2017 07:03:30 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108ecbe-0003-0000-426d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: GolangRocksOnAzure2050-12-20T21:55:06Z2051-12-20T21:55:06Zraup + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:6Yx8pPgRrSM09qBzBwJUYXAjrhDmvu25PiCODPW9MjU= + Content-Length: + - "233" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:31 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-155storagequeuesuitetestsetpermissionsalltruewithtimeout?comp=acl&timeout=30 + method: PUT + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Fri, 21 Apr 2017 07:03:30 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108ecc4-0003-0000-456d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:75JdRNsKSuxK8iNFm/6NG1HM13OAO7EsLe2rHgpg7Cc= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:31 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-155storagequeuesuitetestsetpermissionsalltruewithtimeout + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Fri, 21 Apr 2017 07:03:31 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108eccd-0003-0000-4b6d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageQueueSuite/Test_SetPermissionsAlternateTrueNoTimeout.yaml b/storage/recordings/StorageQueueSuite/Test_SetPermissionsAlternateTrueNoTimeout.yaml new file mode 100644 index 000000000000..009b1459ccb0 --- /dev/null +++ b/storage/recordings/StorageQueueSuite/Test_SetPermissionsAlternateTrueNoTimeout.yaml @@ -0,0 +1,91 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:L7MIoa0uGSpcwbpoMhLR40gd6xnJCp4H5tFMa3BRWsM= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:31 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-159storagequeuesuitetestsetpermissionsalternatetruenotime + method: PUT + response: + body: "" + headers: + Date: + - Fri, 21 Apr 2017 07:03:31 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108eccf-0003-0000-4d6d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: GolangRocksOnAzure2050-12-20T21:55:06Z2051-12-20T21:55:06Zru + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:NPUtgYX9N7LUdcMqyFR0czWOEmDXNTxf6hf0iBZ8big= + Content-Length: + - "231" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:31 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-159storagequeuesuitetestsetpermissionsalternatetruenotime?comp=acl + method: PUT + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Fri, 21 Apr 2017 07:03:31 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108ecd6-0003-0000-526d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:VDxsdevWZd17miXLhNP6NZaSx8/RLLAFOM5iiOyuKnI= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:31 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-159storagequeuesuitetestsetpermissionsalternatetruenotime + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Fri, 21 Apr 2017 07:03:31 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108ecdf-0003-0000-586d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageQueueSuite/Test_SetPermissionsAlternateTrueWithTimeout.yaml b/storage/recordings/StorageQueueSuite/Test_SetPermissionsAlternateTrueWithTimeout.yaml new file mode 100644 index 000000000000..78a18bc7465b --- /dev/null +++ b/storage/recordings/StorageQueueSuite/Test_SetPermissionsAlternateTrueWithTimeout.yaml @@ -0,0 +1,91 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:QSi/TF5fln9g3HmHwLuIyLkVDETLVQ9R7uoLqUZoXGQ= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:32 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-161storagequeuesuitetestsetpermissionsalternatetruewithti + method: PUT + response: + body: "" + headers: + Date: + - Fri, 21 Apr 2017 07:03:31 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108ece5-0003-0000-5c6d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: GolangRocksOnAzure2050-12-20T21:55:06Z2051-12-20T21:55:06Zru + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:x4lxEpUvHaQLKc5/sEG8MGZIZScR4U/LwawxUAQ9uAk= + Content-Length: + - "231" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:32 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-161storagequeuesuitetestsetpermissionsalternatetruewithti?comp=acl&timeout=30 + method: PUT + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Fri, 21 Apr 2017 07:03:31 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108ece8-0003-0000-5e6d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:XTt/tV1s6gtH4hh0ezXLFbI3KVX1HbS6P0StwrLff1Y= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 queue + X-Ms-Date: + - Fri, 21 Apr 2017 07:03:32 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.queue.core.windows.net/queue-161storagequeuesuitetestsetpermissionsalternatetruewithti + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Fri, 21 Apr 2017 07:03:32 GMT + Server: + - Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8108eceb-0003-0000-616d-bab0ce000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageShareSuite/TestCreateShareDeleteShare.yaml b/storage/recordings/StorageShareSuite/TestCreateShareDeleteShare.yaml new file mode 100644 index 000000000000..34af44c70c52 --- /dev/null +++ b/storage/recordings/StorageShareSuite/TestCreateShareDeleteShare.yaml @@ -0,0 +1,62 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:7NgdfJGSYIZI1pWWXwmAvpo5CLMI2TBV2gI3/1RkoJE= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:35 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-44storagesharesuitetestcreatesharedeleteshare?restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:34 GMT + Etag: + - '"0x8D47C73CC1140A1"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:35 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027256-001a-00eb-265c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:K0H6ITM3xUOw/lWTW26297XfV1xNOR+rf+rl5P/REK4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:35 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-44storagesharesuitetestcreatesharedeleteshare?restype=share + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:35 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027258-001a-00eb-275c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageShareSuite/TestCreateShareIfExists.yaml b/storage/recordings/StorageShareSuite/TestCreateShareIfExists.yaml new file mode 100644 index 000000000000..3e1ef6f01b01 --- /dev/null +++ b/storage/recordings/StorageShareSuite/TestCreateShareIfExists.yaml @@ -0,0 +1,68 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:BTMAiP7WFgxgziaPnEMXLFj5QFu5ipbkZLnHZifog9g= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:35 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-exists41storagesharesuitetestcreateshareifexists?restype=share + method: PUT + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x72\x72\x6F\x72\x3E\x3C\x43\x6F\x64\x65\x3E\x53\x68\x61\x72\x65\x41\x6C\x72\x65\x61\x64\x79\x45\x78\x69\x73\x74\x73\x3C\x2F\x43\x6F\x64\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x3E\x54\x68\x65\x20\x73\x70\x65\x63\x69\x66\x69\x65\x64\x20\x73\x68\x61\x72\x65\x20\x61\x6C\x72\x65\x61\x64\x79\x20\x65\x78\x69\x73\x74\x73\x2E\n\x52\x65\x71\x75\x65\x73\x74\x49\x64\x3A\x35\x61\x30\x32\x37\x32\x35\x62\x2D\x30\x30\x31\x61\x2D\x30\x30\x65\x62\x2D\x32\x39\x35\x63\x2D\x61\x65\x66\x63\x34\x35\x30\x30\x30\x30\x30\x30\n\x54\x69\x6D\x65\x3A\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x33\x35\x2E\x34\x35\x30\x39\x37\x33\x38\x5A\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x45\x72\x72\x6F\x72\x3E" + headers: + Content-Length: + - "222" + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:35 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02725b-001a-00eb-295c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 409 The specified share already exists. + code: 409 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:aD+MnQPm1iUmsfqxIa3fcvYwKzqzhiYn5mmd/pwUZzk= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:35 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-exists41storagesharesuitetestcreateshareifexists?restype=share + method: HEAD + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:35 GMT + Etag: + - '"0x8D47C73CC234551"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:35 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02725c-001a-00eb-2a5c-aefc45000000 + X-Ms-Share-Quota: + - "5120" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 diff --git a/storage/recordings/StorageShareSuite/TestCreateShareIfNotExists.yaml b/storage/recordings/StorageShareSuite/TestCreateShareIfNotExists.yaml new file mode 100644 index 000000000000..81ce8b81a9c0 --- /dev/null +++ b/storage/recordings/StorageShareSuite/TestCreateShareIfNotExists.yaml @@ -0,0 +1,62 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:0mLifyQz9kZJhM9JKvug3K9kgzNnd3WTKXqFeEYIgro= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:35 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-notexists44storagesharesuitetestcreateshareifnotexists?restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:35 GMT + Etag: + - '"0x8D47C73CC410BFE"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:35 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02725f-001a-00eb-2c5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:s+DVz24NgsdttG8MiYq3OKHvZoRKKJZsI1j0nFehcTI= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:35 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-notexists44storagesharesuitetestcreateshareifnotexists?restype=share + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:35 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027261-001a-00eb-2d5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageShareSuite/TestDeleteShareIfNotExists.yaml b/storage/recordings/StorageShareSuite/TestDeleteShareIfNotExists.yaml new file mode 100644 index 000000000000..597e967fab59 --- /dev/null +++ b/storage/recordings/StorageShareSuite/TestDeleteShareIfNotExists.yaml @@ -0,0 +1,93 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:azUp0+juL5LJAkbLl1u7XpnCcF8HZnm4U8vaz7dWJRE= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:35 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-144storagesharesuitetestdeleteshareifnotexists?restype=share + method: DELETE + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x72\x72\x6F\x72\x3E\x3C\x43\x6F\x64\x65\x3E\x53\x68\x61\x72\x65\x4E\x6F\x74\x46\x6F\x75\x6E\x64\x3C\x2F\x43\x6F\x64\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x3E\x54\x68\x65\x20\x73\x70\x65\x63\x69\x66\x69\x65\x64\x20\x73\x68\x61\x72\x65\x20\x64\x6F\x65\x73\x20\x6E\x6F\x74\x20\x65\x78\x69\x73\x74\x2E\n\x52\x65\x71\x75\x65\x73\x74\x49\x64\x3A\x35\x61\x30\x32\x37\x32\x36\x32\x2D\x30\x30\x31\x61\x2D\x30\x30\x65\x62\x2D\x32\x65\x35\x63\x2D\x61\x65\x66\x63\x34\x35\x30\x30\x30\x30\x30\x30\n\x54\x69\x6D\x65\x3A\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x33\x35\x2E\x37\x31\x36\x31\x36\x34\x32\x5A\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x45\x72\x72\x6F\x72\x3E" + headers: + Content-Length: + - "217" + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:35 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027262-001a-00eb-2e5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The specified share does not exist. + code: 404 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:9LxGIWlAKojDdLO/vKAHZiqyGVhXyjv5vhKX0ctrPVc= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:36 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-244storagesharesuitetestdeleteshareifnotexists?restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:35 GMT + Etag: + - '"0x8D47C73CC5A16D8"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:35 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027263-001a-00eb-2f5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:/8SCx3TQKkc+SKpN85eMpLmtZ4qswt9/WfRM3hU8XwI= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:36 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-244storagesharesuitetestdeleteshareifnotexists?restype=share + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:35 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027265-001a-00eb-305c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageShareSuite/TestGetAndSetShareMetadata.yaml b/storage/recordings/StorageShareSuite/TestGetAndSetShareMetadata.yaml new file mode 100644 index 000000000000..1418e54662f4 --- /dev/null +++ b/storage/recordings/StorageShareSuite/TestGetAndSetShareMetadata.yaml @@ -0,0 +1,225 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:4iU0Ujbyf35Pc85VAwWvvM7pN3kyXgaB/aTri89TWnQ= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:36 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-144storagesharesuitetestgetandsetsharemetadata?restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:35 GMT + Etag: + - '"0x8D47C73CC69AA0D"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:35 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027266-001a-00eb-315c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:6t8WcqRaXYprik7Kh+M2BXGg+3ZHGEtaNLiptQrk2Pw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:36 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-144storagesharesuitetestgetandsetsharemetadata?restype=share + method: HEAD + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:35 GMT + Etag: + - '"0x8D47C73CC69AA0D"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:35 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027268-001a-00eb-325c-aefc45000000 + X-Ms-Share-Quota: + - "5120" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:B4Oeb7TJ5C/OSs9gMUavvVZiI+SdgQNpZ33pcWgiDt4= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:36 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-244storagesharesuitetestgetandsetsharemetadata?restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:35 GMT + Etag: + - '"0x8D47C73CC7BD5D8"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:35 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027269-001a-00eb-335c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:B6/A9PlV85lu0TaCmc82hXR7MBxNAcauFV2y5J+Qukw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:36 GMT + X-Ms-Meta-Lol: + - rofl + X-Ms-Meta-Rofl_baz: + - waz qux + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-244storagesharesuitetestgetandsetsharemetadata?comp=metadata&restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:35 GMT + Etag: + - '"0x8D47C73CCFFF17C"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:36 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02726b-001a-00eb-345c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:3g6A7NRAjwpFEwrmJjhTeFKGWMpWSwAI5a9H90NdRsA= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:36 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-244storagesharesuitetestgetandsetsharemetadata?restype=share + method: HEAD + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:35 GMT + Etag: + - '"0x8D47C73CCFFF17C"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:36 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Meta-Lol: + - rofl + X-Ms-Meta-Rofl_baz: + - waz qux + X-Ms-Request-Id: + - 5a02726c-001a-00eb-355c-aefc45000000 + X-Ms-Share-Quota: + - "5120" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:PJTpoH/AO+SIEVz2i00xxUkYFMvXJH78JIp87WNYTwo= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:36 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-244storagesharesuitetestgetandsetsharemetadata?restype=share + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:35 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02726d-001a-00eb-365c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:vwUGIfU9TxZpBXsJBDM9k37lVARTuGTCI/t5gm4Yibg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:36 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-144storagesharesuitetestgetandsetsharemetadata?restype=share + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:35 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02726e-001a-00eb-375c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageShareSuite/TestGetAndSetShareProperties.yaml b/storage/recordings/StorageShareSuite/TestGetAndSetShareProperties.yaml new file mode 100644 index 000000000000..c7a26759d1c7 --- /dev/null +++ b/storage/recordings/StorageShareSuite/TestGetAndSetShareProperties.yaml @@ -0,0 +1,128 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:/Zfudoq8l/Y1expHqNgObHsmqBRvQD0n9ilMQMs/qT0= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:36 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-46storagesharesuitetestgetandsetshareproperties?restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:35 GMT + Etag: + - '"0x8D47C73CCA6701C"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:36 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027270-001a-00eb-385c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:noD/0Qbcy4Du9Y8riAEwwASuNbLcfUdwQ2CmUCaQVG0= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:36 GMT + X-Ms-Share-Quota: + - "55" + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-46storagesharesuitetestgetandsetshareproperties?comp=properties&restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:36 GMT + Etag: + - '"0x8D47C73CD26BA75"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:37 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027272-001a-00eb-395c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:GT08gyxXW1pEFfNn8BP4DbMGR5VFf1h7x4KqRZl+HUs= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:36 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-46storagesharesuitetestgetandsetshareproperties?restype=share + method: HEAD + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:36 GMT + Etag: + - '"0x8D47C73CD26BA75"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:37 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027273-001a-00eb-3a5c-aefc45000000 + X-Ms-Share-Quota: + - "55" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:EmD5oVW05gBZexacMnqI99yNnF+6OJcWzAqQViSpjuo= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:36 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-46storagesharesuitetestgetandsetshareproperties?restype=share + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:36 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027274-001a-00eb-3b5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageShareSuite/TestListShares.yaml b/storage/recordings/StorageShareSuite/TestListShares.yaml new file mode 100644 index 000000000000..de2d5a7dbc56 --- /dev/null +++ b/storage/recordings/StorageShareSuite/TestListShares.yaml @@ -0,0 +1,91 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:+X1PGkRLGQGTb1tCeCZd/mWYxkUBMIMTMcQbeXy+RGg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:36 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-32storagesharesuitetestlistshares?restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:36 GMT + Etag: + - '"0x8D47C73CCCC9CC1"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:36 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027276-001a-00eb-3d5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:B1VZSDtFkLZznYVhm3YVuhmZTRlIVNzvHPRf/f3NdYA= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:36 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/?comp=list&maxresults=5 + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x20\x53\x65\x72\x76\x69\x63\x65\x45\x6E\x64\x70\x6F\x69\x6E\x74\x3D\"\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x6F\x6C\x61\x6E\x67\x72\x6F\x63\x6B\x73\x6F\x6E\x61\x7A\x75\x72\x65\x2E\x66\x69\x6C\x65\x2E\x63\x6F\x72\x65\x2E\x77\x69\x6E\x64\x6F\x77\x73\x2E\x6E\x65\x74\x2F\"\x3E\x3C\x4D\x61\x78\x52\x65\x73\x75\x6C\x74\x73\x3E\x35\x3C\x2F\x4D\x61\x78\x52\x65\x73\x75\x6C\x74\x73\x3E\x3C\x53\x68\x61\x72\x65\x73\x3E\x3C\x53\x68\x61\x72\x65\x3E\x3C\x4E\x61\x6D\x65\x3E\x73\x68\x61\x72\x65\x2D\x33\x32\x73\x74\x6F\x72\x61\x67\x65\x73\x68\x61\x72\x65\x73\x75\x69\x74\x65\x74\x65\x73\x74\x6C\x69\x73\x74\x73\x68\x61\x72\x65\x73\x3C\x2F\x4E\x61\x6D\x65\x3E\x3C\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x57\x65\x64\x2C\x20\x30\x35\x20\x41\x70\x72\x20\x32\x30\x31\x37\x20\x32\x32\x3A\x33\x33\x3A\x33\x36\x20\x47\x4D\x54\x3C\x2F\x4C\x61\x73\x74\x2D\x4D\x6F\x64\x69\x66\x69\x65\x64\x3E\x3C\x45\x74\x61\x67\x3E\"\x30\x78\x38\x44\x34\x37\x43\x37\x33\x43\x43\x43\x43\x39\x43\x43\x31\"\x3C\x2F\x45\x74\x61\x67\x3E\x3C\x51\x75\x6F\x74\x61\x3E\x35\x31\x32\x30\x3C\x2F\x51\x75\x6F\x74\x61\x3E\x3C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x2F\x53\x68\x61\x72\x65\x3E\x3C\x2F\x53\x68\x61\x72\x65\x73\x3E\x3C\x4E\x65\x78\x74\x4D\x61\x72\x6B\x65\x72\x20\x2F\x3E\x3C\x2F\x45\x6E\x75\x6D\x65\x72\x61\x74\x69\x6F\x6E\x52\x65\x73\x75\x6C\x74\x73\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:36 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027278-001a-00eb-3e5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:qn3fe0ZWXn8hfmPs+fIhHGoj3j+AJwQlMA29STjSKms= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:36 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-32storagesharesuitetestlistshares?restype=share + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:36 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027279-001a-00eb-3f5c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageShareSuite/TestMetadataCaseMunging.yaml b/storage/recordings/StorageShareSuite/TestMetadataCaseMunging.yaml new file mode 100644 index 000000000000..7f761fdb04e8 --- /dev/null +++ b/storage/recordings/StorageShareSuite/TestMetadataCaseMunging.yaml @@ -0,0 +1,134 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:F1r1tBB0areOBebzrgBmOq2Jtg923AfOEH4mjZnx7F8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:36 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-41storagesharesuitetestmetadatacasemunging?restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:36 GMT + Etag: + - '"0x8D47C73CCE58084"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:36 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02727a-001a-00eb-405c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:+kA0Bl9invamuXyFodhoQ37csz8f20lBl/eYoZUyWd8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:36 GMT + X-Ms-Meta-Lol: + - different rofl + X-Ms-Meta-Rofl_baz: + - different waz qux + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-41storagesharesuitetestmetadatacasemunging?comp=metadata&restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:36 GMT + Etag: + - '"0x8D47C73CD65F1F0"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:37 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02727c-001a-00eb-415c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:2sctvq/KbCjOi3tKqgVPzDgOQsjimufOT5NFTO0zTxI= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:37 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-41storagesharesuitetestmetadatacasemunging?restype=share + method: HEAD + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:36 GMT + Etag: + - '"0x8D47C73CD65F1F0"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:37 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Meta-Lol: + - different rofl + X-Ms-Meta-Rofl_baz: + - different waz qux + X-Ms-Request-Id: + - 5a02727d-001a-00eb-425c-aefc45000000 + X-Ms-Share-Quota: + - "5120" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:CGGTwuFCxkOE38WPNc2Ks4xgCwe5C9mtWlqRtFED5eg= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:37 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-41storagesharesuitetestmetadatacasemunging?restype=share + method: DELETE + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:36 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02727e-001a-00eb-435c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 diff --git a/storage/recordings/StorageShareSuite/TestShareExists.yaml b/storage/recordings/StorageShareSuite/TestShareExists.yaml new file mode 100644 index 000000000000..edd91f7b812f --- /dev/null +++ b/storage/recordings/StorageShareSuite/TestShareExists.yaml @@ -0,0 +1,126 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:uDWA9l5GcB+W4k70EwvhVapYgp689WmoGSsYQAgE7QY= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:37 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-133storagesharesuitetestshareexists?restype=share + method: HEAD + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:36 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a02727f-001a-00eb-445c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The specified share does not exist. + code: 404 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:M83pAjQm4nxng2lFXLbynszPcsFxxe9SfrHGpNA3HTw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:37 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-233storagesharesuitetestshareexists?restype=share + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:36 GMT + Etag: + - '"0x8D47C73CD0E6CC9"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:36 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027281-001a-00eb-455c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:Yf/U9qwc5r1t4rfn6grWKrc8HVIdd4agLZ48HwGFmTo= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:37 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-233storagesharesuitetestshareexists?restype=share + method: HEAD + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:36 GMT + Etag: + - '"0x8D47C73CD0E6CC9"' + Last-Modified: + - Wed, 05 Apr 2017 22:33:36 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027283-001a-00eb-465c-aefc45000000 + X-Ms-Share-Quota: + - "5120" + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:1KXGG9P3zYpS2yLzch5VVsDcjHTuBngVE2q9v8M4IVY= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 file + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:37 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.file.core.windows.net/share-133storagesharesuitetestshareexists?restype=share + method: DELETE + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x45\x72\x72\x6F\x72\x3E\x3C\x43\x6F\x64\x65\x3E\x53\x68\x61\x72\x65\x4E\x6F\x74\x46\x6F\x75\x6E\x64\x3C\x2F\x43\x6F\x64\x65\x3E\x3C\x4D\x65\x73\x73\x61\x67\x65\x3E\x54\x68\x65\x20\x73\x70\x65\x63\x69\x66\x69\x65\x64\x20\x73\x68\x61\x72\x65\x20\x64\x6F\x65\x73\x20\x6E\x6F\x74\x20\x65\x78\x69\x73\x74\x2E\n\x52\x65\x71\x75\x65\x73\x74\x49\x64\x3A\x35\x61\x30\x32\x37\x32\x38\x34\x2D\x30\x30\x31\x61\x2D\x30\x30\x65\x62\x2D\x34\x37\x35\x63\x2D\x61\x65\x66\x63\x34\x35\x30\x30\x30\x30\x30\x30\n\x54\x69\x6D\x65\x3A\x32\x30\x31\x37\x2D\x30\x34\x2D\x30\x35\x54\x32\x32\x3A\x33\x33\x3A\x33\x37\x2E\x30\x34\x31\x31\x31\x35\x34\x5A\x3C\x2F\x4D\x65\x73\x73\x61\x67\x65\x3E\x3C\x2F\x45\x72\x72\x6F\x72\x3E" + headers: + Content-Length: + - "217" + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:36 GMT + Server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 5a027284-001a-00eb-475c-aefc45000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The specified share does not exist. + code: 404 diff --git a/storage/recordings/StorageSuite/TestGetServiceProperties.yaml b/storage/recordings/StorageSuite/TestGetServiceProperties.yaml new file mode 100644 index 000000000000..7babe21856c3 --- /dev/null +++ b/storage/recordings/StorageSuite/TestGetServiceProperties.yaml @@ -0,0 +1,33 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:gwUioVuGmO6fOLSuniOpLJWt5TZWHnOwrolVZpMkplw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:37 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/?comp=properties&restype=service + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x53\x74\x6F\x72\x61\x67\x65\x53\x65\x72\x76\x69\x63\x65\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x6F\x67\x67\x69\x6E\x67\x3E\x3C\x56\x65\x72\x73\x69\x6F\x6E\x3E\x31\x2E\x30\x3C\x2F\x56\x65\x72\x73\x69\x6F\x6E\x3E\x3C\x52\x65\x61\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x52\x65\x61\x64\x3E\x3C\x57\x72\x69\x74\x65\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x57\x72\x69\x74\x65\x3E\x3C\x44\x65\x6C\x65\x74\x65\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x44\x65\x6C\x65\x74\x65\x3E\x3C\x52\x65\x74\x65\x6E\x74\x69\x6F\x6E\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x45\x6E\x61\x62\x6C\x65\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x45\x6E\x61\x62\x6C\x65\x64\x3E\x3C\x2F\x52\x65\x74\x65\x6E\x74\x69\x6F\x6E\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x2F\x4C\x6F\x67\x67\x69\x6E\x67\x3E\x3C\x48\x6F\x75\x72\x4D\x65\x74\x72\x69\x63\x73\x3E\x3C\x56\x65\x72\x73\x69\x6F\x6E\x3E\x31\x2E\x30\x3C\x2F\x56\x65\x72\x73\x69\x6F\x6E\x3E\x3C\x45\x6E\x61\x62\x6C\x65\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x45\x6E\x61\x62\x6C\x65\x64\x3E\x3C\x52\x65\x74\x65\x6E\x74\x69\x6F\x6E\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x45\x6E\x61\x62\x6C\x65\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x45\x6E\x61\x62\x6C\x65\x64\x3E\x3C\x2F\x52\x65\x74\x65\x6E\x74\x69\x6F\x6E\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x2F\x48\x6F\x75\x72\x4D\x65\x74\x72\x69\x63\x73\x3E\x3C\x4D\x69\x6E\x75\x74\x65\x4D\x65\x74\x72\x69\x63\x73\x3E\x3C\x56\x65\x72\x73\x69\x6F\x6E\x3E\x31\x2E\x30\x3C\x2F\x56\x65\x72\x73\x69\x6F\x6E\x3E\x3C\x45\x6E\x61\x62\x6C\x65\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x45\x6E\x61\x62\x6C\x65\x64\x3E\x3C\x52\x65\x74\x65\x6E\x74\x69\x6F\x6E\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x45\x6E\x61\x62\x6C\x65\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x45\x6E\x61\x62\x6C\x65\x64\x3E\x3C\x2F\x52\x65\x74\x65\x6E\x74\x69\x6F\x6E\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x2F\x4D\x69\x6E\x75\x74\x65\x4D\x65\x74\x72\x69\x63\x73\x3E\x3C\x43\x6F\x72\x73\x20\x2F\x3E\x3C\x2F\x53\x74\x6F\x72\x61\x67\x65\x53\x65\x72\x76\x69\x63\x65\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:37 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - ab33c61b-0002-0064-5f5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 diff --git a/storage/recordings/StorageSuite/TestSetServiceProperties.yaml b/storage/recordings/StorageSuite/TestSetServiceProperties.yaml new file mode 100644 index 000000000000..6740877fc2d3 --- /dev/null +++ b/storage/recordings/StorageSuite/TestSetServiceProperties.yaml @@ -0,0 +1,66 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: 1.0truefalsetruetrue71.0truetruetrue71.0truetruetrue7*GET,PUT500x-ms-meta-customheader,x-ms-meta-data*x-ms-meta-customheader,x-ms-meta-target* + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:+Bntn6Hj/QSEeYqPmpghthxRvTBMQGpUJX81+53tfRs= + Content-Length: + - "868" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:37 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/?comp=properties&restype=service + method: PUT + response: + body: "" + headers: + Date: + - Wed, 05 Apr 2017 22:33:37 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - ab33c635-0002-0064-745c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:gwUioVuGmO6fOLSuniOpLJWt5TZWHnOwrolVZpMkplw= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:37 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/?comp=properties&restype=service + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x53\x74\x6F\x72\x61\x67\x65\x53\x65\x72\x76\x69\x63\x65\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E\x3C\x4C\x6F\x67\x67\x69\x6E\x67\x3E\x3C\x56\x65\x72\x73\x69\x6F\x6E\x3E\x31\x2E\x30\x3C\x2F\x56\x65\x72\x73\x69\x6F\x6E\x3E\x3C\x52\x65\x61\x64\x3E\x66\x61\x6C\x73\x65\x3C\x2F\x52\x65\x61\x64\x3E\x3C\x57\x72\x69\x74\x65\x3E\x74\x72\x75\x65\x3C\x2F\x57\x72\x69\x74\x65\x3E\x3C\x44\x65\x6C\x65\x74\x65\x3E\x74\x72\x75\x65\x3C\x2F\x44\x65\x6C\x65\x74\x65\x3E\x3C\x52\x65\x74\x65\x6E\x74\x69\x6F\x6E\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x45\x6E\x61\x62\x6C\x65\x64\x3E\x74\x72\x75\x65\x3C\x2F\x45\x6E\x61\x62\x6C\x65\x64\x3E\x3C\x44\x61\x79\x73\x3E\x37\x3C\x2F\x44\x61\x79\x73\x3E\x3C\x2F\x52\x65\x74\x65\x6E\x74\x69\x6F\x6E\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x2F\x4C\x6F\x67\x67\x69\x6E\x67\x3E\x3C\x48\x6F\x75\x72\x4D\x65\x74\x72\x69\x63\x73\x3E\x3C\x56\x65\x72\x73\x69\x6F\x6E\x3E\x31\x2E\x30\x3C\x2F\x56\x65\x72\x73\x69\x6F\x6E\x3E\x3C\x45\x6E\x61\x62\x6C\x65\x64\x3E\x74\x72\x75\x65\x3C\x2F\x45\x6E\x61\x62\x6C\x65\x64\x3E\x3C\x49\x6E\x63\x6C\x75\x64\x65\x41\x50\x49\x73\x3E\x74\x72\x75\x65\x3C\x2F\x49\x6E\x63\x6C\x75\x64\x65\x41\x50\x49\x73\x3E\x3C\x52\x65\x74\x65\x6E\x74\x69\x6F\x6E\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x45\x6E\x61\x62\x6C\x65\x64\x3E\x74\x72\x75\x65\x3C\x2F\x45\x6E\x61\x62\x6C\x65\x64\x3E\x3C\x44\x61\x79\x73\x3E\x37\x3C\x2F\x44\x61\x79\x73\x3E\x3C\x2F\x52\x65\x74\x65\x6E\x74\x69\x6F\x6E\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x2F\x48\x6F\x75\x72\x4D\x65\x74\x72\x69\x63\x73\x3E\x3C\x4D\x69\x6E\x75\x74\x65\x4D\x65\x74\x72\x69\x63\x73\x3E\x3C\x56\x65\x72\x73\x69\x6F\x6E\x3E\x31\x2E\x30\x3C\x2F\x56\x65\x72\x73\x69\x6F\x6E\x3E\x3C\x45\x6E\x61\x62\x6C\x65\x64\x3E\x74\x72\x75\x65\x3C\x2F\x45\x6E\x61\x62\x6C\x65\x64\x3E\x3C\x49\x6E\x63\x6C\x75\x64\x65\x41\x50\x49\x73\x3E\x74\x72\x75\x65\x3C\x2F\x49\x6E\x63\x6C\x75\x64\x65\x41\x50\x49\x73\x3E\x3C\x52\x65\x74\x65\x6E\x74\x69\x6F\x6E\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x45\x6E\x61\x62\x6C\x65\x64\x3E\x74\x72\x75\x65\x3C\x2F\x45\x6E\x61\x62\x6C\x65\x64\x3E\x3C\x44\x61\x79\x73\x3E\x37\x3C\x2F\x44\x61\x79\x73\x3E\x3C\x2F\x52\x65\x74\x65\x6E\x74\x69\x6F\x6E\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x2F\x4D\x69\x6E\x75\x74\x65\x4D\x65\x74\x72\x69\x63\x73\x3E\x3C\x43\x6F\x72\x73\x3E\x3C\x43\x6F\x72\x73\x52\x75\x6C\x65\x3E\x3C\x41\x6C\x6C\x6F\x77\x65\x64\x4D\x65\x74\x68\x6F\x64\x73\x3E\x47\x45\x54\x2C\x50\x55\x54\x3C\x2F\x41\x6C\x6C\x6F\x77\x65\x64\x4D\x65\x74\x68\x6F\x64\x73\x3E\x3C\x41\x6C\x6C\x6F\x77\x65\x64\x4F\x72\x69\x67\x69\x6E\x73\x3E\x2A\x3C\x2F\x41\x6C\x6C\x6F\x77\x65\x64\x4F\x72\x69\x67\x69\x6E\x73\x3E\x3C\x41\x6C\x6C\x6F\x77\x65\x64\x48\x65\x61\x64\x65\x72\x73\x3E\x78\x2D\x6D\x73\x2D\x6D\x65\x74\x61\x2D\x63\x75\x73\x74\x6F\x6D\x68\x65\x61\x64\x65\x72\x2C\x78\x2D\x6D\x73\x2D\x6D\x65\x74\x61\x2D\x74\x61\x72\x67\x65\x74\x2A\x3C\x2F\x41\x6C\x6C\x6F\x77\x65\x64\x48\x65\x61\x64\x65\x72\x73\x3E\x3C\x45\x78\x70\x6F\x73\x65\x64\x48\x65\x61\x64\x65\x72\x73\x3E\x78\x2D\x6D\x73\x2D\x6D\x65\x74\x61\x2D\x63\x75\x73\x74\x6F\x6D\x68\x65\x61\x64\x65\x72\x2C\x78\x2D\x6D\x73\x2D\x6D\x65\x74\x61\x2D\x64\x61\x74\x61\x2A\x3C\x2F\x45\x78\x70\x6F\x73\x65\x64\x48\x65\x61\x64\x65\x72\x73\x3E\x3C\x4D\x61\x78\x41\x67\x65\x49\x6E\x53\x65\x63\x6F\x6E\x64\x73\x3E\x35\x30\x30\x3C\x2F\x4D\x61\x78\x41\x67\x65\x49\x6E\x53\x65\x63\x6F\x6E\x64\x73\x3E\x3C\x2F\x43\x6F\x72\x73\x52\x75\x6C\x65\x3E\x3C\x2F\x43\x6F\x72\x73\x3E\x3C\x2F\x53\x74\x6F\x72\x61\x67\x65\x53\x65\x72\x76\x69\x63\x65\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3E" + headers: + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - x-ms-meta-customheader + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:37 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - ab33c657-0002-0064-105c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 diff --git a/storage/recordings/StorageTableSuite/TestGet.yaml b/storage/recordings/StorageTableSuite/TestGet.yaml new file mode 100644 index 000000000000..39ff3d9ff346 --- /dev/null +++ b/storage/recordings/StorageTableSuite/TestGet.yaml @@ -0,0 +1,126 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: | + {"TableName":"table25storagetablesuitetestget"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:oFkVVxYbvsi0eavYxzYyO+K1yj1RtfoYCG8k0Nby2A8= + Content-Length: + - "48" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Fri, 21 Apr 2017 19:01:31 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table25storagetablesuitetestget') + Date: + - Fri, 21 Apr 2017 19:01:31 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table25storagetablesuitetestget') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 01dca575-0002-0077-18d1-ba87f8000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Authorization: + - SharedKey golangrocksonazure:XcVA9Plm6Mv6/t+Yz2+MGKxJpuQAvBOx866YjeMdpc8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Fri, 21 Apr 2017 19:01:31 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table25storagetablesuitetestget%27%29?timeout=30 + method: GET + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#Tables/@Element","odata.type":"golangrocksonazure.Tables","odata.id":"https://golangrocksonazure.table.core.windows.net/Tables(''table25storagetablesuitetestget'')","odata.editLink":"Tables(''table25storagetablesuitetestget'')","TableName":"table25storagetablesuitetestget"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Fri, 21 Apr 2017 19:01:31 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 01dca57f-0002-0077-20d1-ba87f8000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:cRjC+bNv9D958nFowOo3XHO0IMUhnMDG1lfNbeLMOHw= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Fri, 21 Apr 2017 19:01:31 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table25storagetablesuitetestget%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Fri, 21 Apr 2017 19:01:31 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 01dca585-0002-0077-26d1-ba87f8000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageTableSuite/TestQueryTablesNextResults.yaml b/storage/recordings/StorageTableSuite/TestQueryTablesNextResults.yaml new file mode 100644 index 000000000000..14c579479823 --- /dev/null +++ b/storage/recordings/StorageTableSuite/TestQueryTablesNextResults.yaml @@ -0,0 +1,337 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: | + {"TableName":"table044storagetablesuitetestque"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:gSTg/IffFXHUM2hc03D6IFJlaWJyqjogU1J5d6LkvbI= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:37 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table044storagetablesuitetestque') + Date: + - Wed, 05 Apr 2017 22:33:37 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table044storagetablesuitetestque') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33c67a-0002-0064-325c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: | + {"TableName":"table144storagetablesuitetestque"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:gSTg/IffFXHUM2hc03D6IFJlaWJyqjogU1J5d6LkvbI= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:37 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table144storagetablesuitetestque') + Date: + - Wed, 05 Apr 2017 22:33:37 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table144storagetablesuitetestque') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33c688-0002-0064-3f5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: | + {"TableName":"table244storagetablesuitetestque"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:gSTg/IffFXHUM2hc03D6IFJlaWJyqjogU1J5d6LkvbI= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:37 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table244storagetablesuitetestque') + Date: + - Wed, 05 Apr 2017 22:33:37 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table244storagetablesuitetestque') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33c695-0002-0064-4b5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - SharedKey golangrocksonazure:R51QYZu7Bf1ra4piRxz6RkwiltzJNZ0fO41RIoo8Kmk= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:37 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?%24top=2 + method: GET + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#Tables","value":[{"TableName":"table044storagetablesuitetestque"},{"TableName":"table144storagetablesuitetestque"}]}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:37 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Continuation-Nexttablename: + - 1!68!dGFibGUyNDRzdG9yYWdldGFibGVzdWl0ZXRlc3RxdWUBMDFkMmFlNWNhYWQ3OTFhMw-- + X-Ms-Request-Id: + - ab33c6a5-0002-0064-585c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - SharedKey golangrocksonazure:R51QYZu7Bf1ra4piRxz6RkwiltzJNZ0fO41RIoo8Kmk= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:37 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?%24top=2&NextTableName=1%2168%21dGFibGUyNDRzdG9yYWdldGFibGVzdWl0ZXRlc3RxdWUBMDFkMmFlNWNhYWQ3OTFhMw-- + method: GET + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#Tables","value":[{"TableName":"table244storagetablesuitetestque"}]}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:37 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33c6b5-0002-0064-665c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:jpeBUhYkjP7S2Yk+Xp8EyGtEoLQxfbG71Zzr9iPFEtw= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:37 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table244storagetablesuitetestque%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:37 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33c6bd-0002-0064-6e5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:9uJ3dM3GEgR5R/JHiOhnTYl/WZISnvhKh4EC9mBGYzk= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:37 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table144storagetablesuitetestque%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:37 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33c6c8-0002-0064-785c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:XGWtTP7dLcC0v5KmE2kAarfwOFm//o2F6AhNki7yfks= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:38 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table044storagetablesuitetestque%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:37 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33c6d8-0002-0064-075c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageTableSuite/TestSetPermissionsSuccessfully.yaml b/storage/recordings/StorageTableSuite/TestSetPermissionsSuccessfully.yaml new file mode 100644 index 000000000000..8c137ed3d3e3 --- /dev/null +++ b/storage/recordings/StorageTableSuite/TestSetPermissionsSuccessfully.yaml @@ -0,0 +1,122 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: | + {"TableName":"table48storagetablesuitetestsetp"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:FGdH/rDYACY5yqYP0qQnD+uBzj+bK8+AoqOf264baxY= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:38 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table48storagetablesuitetestsetp') + Date: + - Wed, 05 Apr 2017 22:33:37 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table48storagetablesuitetestsetp') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33c6ea-0002-0064-195c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: GolangRocksOnAzure2050-12-20T21:55:06Z2050-12-21T07:55:06Zraud + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:WZmgk259mDd6HO5e9Y/EXwyGTHQTbEunHC7egL9F2fQ= + Content-Length: + - "233" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:38 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table48storagetablesuitetestsetp?comp=acl&timeout=30 + method: PUT + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:37 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - ab33c6ef-0002-0064-1d5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:A2sZC6ncp2Kzua+9vQt1wGDkKw5W+XiTBPRJ2G0GZb4= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:38 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table48storagetablesuitetestsetp%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:38 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33c6f9-0002-0064-265c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageTableSuite/TestSetPermissionsUnsuccessfully.yaml b/storage/recordings/StorageTableSuite/TestSetPermissionsUnsuccessfully.yaml new file mode 100644 index 000000000000..918fc98e24da --- /dev/null +++ b/storage/recordings/StorageTableSuite/TestSetPermissionsUnsuccessfully.yaml @@ -0,0 +1,40 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: GolangRocksOnAzure2050-12-20T21:55:06Z2050-12-21T07:55:06Zraud + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:CmYZq2Ifv5YV7xqZwn37rh92ygeD40NHmkqdlpZEhj0= + Content-Length: + - "233" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:38 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/nonexistingtable?comp=acl&timeout=30 + method: PUT + response: + body: |- + TableNotFoundThe table specified does not exist. + RequestId:ab33c70a-0002-0064-375c-aeb219000000 + Time:2017-04-05T22:33:38.2906021Z + headers: + Content-Length: + - "316" + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:38 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - ab33c70a-0002-0064-375c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 404 The table specified does not exist. + code: 404 diff --git a/storage/recordings/StorageTableSuite/TestSetThenGetPermissionsSuccessfully.yaml b/storage/recordings/StorageTableSuite/TestSetThenGetPermissionsSuccessfully.yaml new file mode 100644 index 000000000000..e0d3f6449501 --- /dev/null +++ b/storage/recordings/StorageTableSuite/TestSetThenGetPermissionsSuccessfully.yaml @@ -0,0 +1,151 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: | + {"TableName":"table55storagetablesuitetestsett"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:FGdH/rDYACY5yqYP0qQnD+uBzj+bK8+AoqOf264baxY= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:38 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table55storagetablesuitetestsett') + Date: + - Wed, 05 Apr 2017 22:33:38 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table55storagetablesuitetestsett') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33c733-0002-0064-5c5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: GolangRocksOnAzure2050-12-20T21:55:06Z2050-12-21T07:55:06ZraudAutoRestIsSuperCool2050-12-21T17:55:06Z2050-12-22T03:55:06Zrad + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:F8mXRaou6eIgfd9bOGCGXOLDVO/LPyX6MOhkSMvfuNs= + Content-Length: + - "427" + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:38 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table55storagetablesuitetestsett?comp=acl&timeout=30 + method: PUT + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:38 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - ab33c745-0002-0064-6b5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:UQmh1G4zMkc05NaH+oQQGd8ycqRFVyu28OYK69SSizY= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:38 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table55storagetablesuitetestsett?comp=acl&timeout=30 + method: GET + response: + body: "\uFEFF\x3C\x3F\x78\x6D\x6C\x20\x76\x65\x72\x73\x69\x6F\x6E\x3D\"\x31\x2E\x30\"\x20\x65\x6E\x63\x6F\x64\x69\x6E\x67\x3D\"\x75\x74\x66\x2D\x38\"\x3F\x3E\x3C\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x73\x3E\x3C\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x3E\x3C\x49\x64\x3E\x47\x6F\x6C\x61\x6E\x67\x52\x6F\x63\x6B\x73\x4F\x6E\x41\x7A\x75\x72\x65\x3C\x2F\x49\x64\x3E\x3C\x41\x63\x63\x65\x73\x73\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x53\x74\x61\x72\x74\x3E\x32\x30\x35\x30\x2D\x31\x32\x2D\x32\x30\x54\x32\x31\x3A\x35\x35\x3A\x30\x36\x2E\x30\x30\x30\x30\x30\x30\x30\x5A\x3C\x2F\x53\x74\x61\x72\x74\x3E\x3C\x45\x78\x70\x69\x72\x79\x3E\x32\x30\x35\x30\x2D\x31\x32\x2D\x32\x31\x54\x30\x37\x3A\x35\x35\x3A\x30\x36\x2E\x30\x30\x30\x30\x30\x30\x30\x5A\x3C\x2F\x45\x78\x70\x69\x72\x79\x3E\x3C\x50\x65\x72\x6D\x69\x73\x73\x69\x6F\x6E\x3E\x72\x61\x75\x64\x3C\x2F\x50\x65\x72\x6D\x69\x73\x73\x69\x6F\x6E\x3E\x3C\x2F\x41\x63\x63\x65\x73\x73\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x2F\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x3E\x3C\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x3E\x3C\x49\x64\x3E\x41\x75\x74\x6F\x52\x65\x73\x74\x49\x73\x53\x75\x70\x65\x72\x43\x6F\x6F\x6C\x3C\x2F\x49\x64\x3E\x3C\x41\x63\x63\x65\x73\x73\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x53\x74\x61\x72\x74\x3E\x32\x30\x35\x30\x2D\x31\x32\x2D\x32\x31\x54\x31\x37\x3A\x35\x35\x3A\x30\x36\x2E\x30\x30\x30\x30\x30\x30\x30\x5A\x3C\x2F\x53\x74\x61\x72\x74\x3E\x3C\x45\x78\x70\x69\x72\x79\x3E\x32\x30\x35\x30\x2D\x31\x32\x2D\x32\x32\x54\x30\x33\x3A\x35\x35\x3A\x30\x36\x2E\x30\x30\x30\x30\x30\x30\x30\x5A\x3C\x2F\x45\x78\x70\x69\x72\x79\x3E\x3C\x50\x65\x72\x6D\x69\x73\x73\x69\x6F\x6E\x3E\x72\x61\x64\x3C\x2F\x50\x65\x72\x6D\x69\x73\x73\x69\x6F\x6E\x3E\x3C\x2F\x41\x63\x63\x65\x73\x73\x50\x6F\x6C\x69\x63\x79\x3E\x3C\x2F\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x3E\x3C\x2F\x53\x69\x67\x6E\x65\x64\x49\x64\x65\x6E\x74\x69\x66\x69\x65\x72\x73\x3E" + headers: + Content-Type: + - application/xml + Date: + - Wed, 05 Apr 2017 22:33:38 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - ab33c753-0002-0064-795c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:KyQ6PHCMyVS/RoEqU0aEDYcKpYd2526SWQh4G2PesNw= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:38 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table55storagetablesuitetestsett%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:38 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33c764-0002-0064-085c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageTableSuite/Test_CreateAndDeleteTable.yaml b/storage/recordings/StorageTableSuite/Test_CreateAndDeleteTable.yaml new file mode 100644 index 000000000000..f65b62e81dd8 --- /dev/null +++ b/storage/recordings/StorageTableSuite/Test_CreateAndDeleteTable.yaml @@ -0,0 +1,176 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: | + {"TableName":"table143storagetablesuitetestcre"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:FGdH/rDYACY5yqYP0qQnD+uBzj+bK8+AoqOf264baxY= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:38 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table143storagetablesuitetestcre') + Date: + - Wed, 05 Apr 2017 22:33:38 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table143storagetablesuitetestcre') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33c77f-0002-0064-235c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: | + {"TableName":"table243storagetablesuitetestcre"} + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:FGdH/rDYACY5yqYP0qQnD+uBzj+bK8+AoqOf264baxY= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:38 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#Tables/@Element","odata.type":"golangrocksonazure.Tables","odata.id":"https://golangrocksonazure.table.core.windows.net/Tables(''table243storagetablesuitetestcre'')","odata.editLink":"Tables(''table243storagetablesuitetestcre'')","TableName":"table243storagetablesuitetestcre"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:38 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table243storagetablesuitetestcre') + Preference-Applied: + - return-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33c797-0002-0064-365c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:gZagydr7XgaDzKM0Q+6sYN6uboOH1eMeHxpWLRKIwkE= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:38 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table143storagetablesuitetestcre%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:38 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33c7b0-0002-0064-4e5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:hU0P2a7tNoZeEqeYSMDVFF55jTfLHnq7TWmlWLeBEoM= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:38 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table243storagetablesuitetestcre%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:38 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33c7bb-0002-0064-595c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/StorageTableSuite/Test_CreateTableWithAllResponsePayloadLevels.yaml b/storage/recordings/StorageTableSuite/Test_CreateTableWithAllResponsePayloadLevels.yaml new file mode 100644 index 000000000000..295c08f7329e --- /dev/null +++ b/storage/recordings/StorageTableSuite/Test_CreateTableWithAllResponsePayloadLevels.yaml @@ -0,0 +1,346 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: | + {"TableName":"tableempty62storagetablesuitetes"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:FGdH/rDYACY5yqYP0qQnD+uBzj+bK8+AoqOf264baxY= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:38 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('tableempty62storagetablesuitetes') + Date: + - Wed, 05 Apr 2017 22:33:38 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('tableempty62storagetablesuitetes') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33c7cf-0002-0064-6c5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:dF/e5TDwQxk17VDrcX3bgxKMHuWeMrIuU+ygy32Koos= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:38 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27tableempty62storagetablesuitetes%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:38 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33c7d9-0002-0064-755c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: | + {"TableName":"tablenm62storagetablesuitetestcr"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:FGdH/rDYACY5yqYP0qQnD+uBzj+bK8+AoqOf264baxY= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:38 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: '{"TableName":"tablenm62storagetablesuitetestcr"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=nometadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:38 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('tablenm62storagetablesuitetestcr') + Preference-Applied: + - return-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33c7e5-0002-0064-015c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:Iceew5yxMs8KNGrIs7sgkd1Q2btKPGbKSUgWZ2jWD10= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:38 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27tablenm62storagetablesuitetestcr%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:38 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33c7ea-0002-0064-055c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: | + {"TableName":"tableminimal62storagetablesuitet"} + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:ouOoI8e61b/jY8OrrTp3mXiQPuqcHpDbOUuYpwZ8ubE= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:39 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#Tables/@Element","TableName":"tableminimal62storagetablesuitet"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:38 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('tableminimal62storagetablesuitet') + Preference-Applied: + - return-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33c7f2-0002-0064-0d5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:TAFcJGNoRn/SVMjtHZ3zVM+AwFmawZ+tXi6WFadx7Js= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:39 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27tableminimal62storagetablesuitet%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:38 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33c7fc-0002-0064-165c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: | + {"TableName":"tablefull62storagetablesuitetest"} + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:ouOoI8e61b/jY8OrrTp3mXiQPuqcHpDbOUuYpwZ8ubE= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:39 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#Tables/@Element","odata.type":"golangrocksonazure.Tables","odata.id":"https://golangrocksonazure.table.core.windows.net/Tables(''tablefull62storagetablesuitetest'')","odata.editLink":"Tables(''tablefull62storagetablesuitetest'')","TableName":"tablefull62storagetablesuitetest"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Wed, 05 Apr 2017 22:33:38 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('tablefull62storagetablesuitetest') + Preference-Applied: + - return-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33c807-0002-0064-215c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 201 Created + code: 201 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:m1VdnFK7v7MgjuqeoPzrQOFxGzoJAiwDNnyh+J6Kw3I= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Wed, 05 Apr 2017 22:33:39 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27tablefull62storagetablesuitetest%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Wed, 05 Apr 2017 22:33:39 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - ab33c811-0002-0064-2a5c-aeb219000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/TableBatchSuite/Test_BatchInsertDeleteSameEntity.yaml b/storage/recordings/TableBatchSuite/Test_BatchInsertDeleteSameEntity.yaml new file mode 100644 index 000000000000..d3bda170f141 --- /dev/null +++ b/storage/recordings/TableBatchSuite/Test_BatchInsertDeleteSameEntity.yaml @@ -0,0 +1,139 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: | + {"TableName":"table48tablebatchsuitetestbatchi"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:pOaHxR/s7rWzcksn6cFJDOO53tfCk8MAuDl7eKONElY= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Tue, 11 Apr 2017 18:11:09 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table48tablebatchsuitetestbatchi') + Date: + - Tue, 11 Apr 2017 18:11:10 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table48tablebatchsuitetestbatchi') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 532ac39d-0002-003f-42ee-b2b565000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "--batch_3da8ce75-1ee2-11e7-b451-6451064d81e8\r\nContent-Type: multipart/mixed; + boundary=changeset_3da8bae2-1ee2-11e7-b451-6451064d81e8\r\n\r\n\r\n--changeset_3da8bae2-1ee2-11e7-b451-6451064d81e8\r\nContent-Transfer-Encoding: + binary\r\nContent-Type: application/http\r\n\r\nPUT https://golangrocksonazure.table.core.windows.net/table48tablebatchsuitetestbatchi%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29 + HTTP/1.1\r\nAccept: application/json;odata=minimalmetadata\r\nContent-Type: + application/json\r\nPrefer: return-no-content\r\n\r\n{\"AmountDue\":200.23,\"CustomerCode\":\"c9da6455-213d-42c9-9a79-3e9149a57833\",\"CustomerCode@odata.type\":\"Edm.Guid\",\"CustomerSince\":\"1992-12-20T21:55:00Z\",\"CustomerSince@odata.type\":\"Edm.DateTime\",\"IsActive\":true,\"NumberOfOrders\":\"255\",\"NumberOfOrders@odata.type\":\"Edm.Int64\",\"PartitionKey\":\"mypartitionkey\",\"RowKey\":\"myrowkey\"}\r\n--changeset_3da8bae2-1ee2-11e7-b451-6451064d81e8\r\nContent-Transfer-Encoding: + binary\r\nContent-Type: application/http\r\n\r\nDELETE https://golangrocksonazure.table.core.windows.net/table48tablebatchsuitetestbatchi%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29 + HTTP/1.1\r\nAccept: application/json;odata=minimalmetadata\r\nContent-Type: + application/json\r\nIf-Match: *\r\nPrefer: return-no-content\r\n\r\n\r\n--changeset_3da8bae2-1ee2-11e7-b451-6451064d81e8--\r\n\r\n--batch_3da8ce75-1ee2-11e7-b451-6451064d81e8--\r\n" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:GLDJC/u/UBMvnETo4s5SFMlRb80M7AneKWvj1tg26Xs= + Content-Type: + - multipart/mixed; boundary=batch_3da8ce75-1ee2-11e7-b451-6451064d81e8 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Tue, 11 Apr 2017 18:11:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/$batch + method: POST + response: + body: "--batchresponse_9ca4f1d7-1656-48bb-9424-95df6ef992f7\r\nContent-Type: multipart/mixed; + boundary=changesetresponse_472d4d32-edd9-4a1a-91cc-e265a58fdb38\r\n\r\n--changesetresponse_472d4d32-edd9-4a1a-91cc-e265a58fdb38\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\n\r\nHTTP/1.1 400 Bad + Request\r\nX-Content-Type-Options: nosniff\r\nCache-Control: no-cache\r\nDataServiceVersion: + 3.0;\r\nContent-Type: application/json;odata=minimalmetadata;streaming=true;charset=utf-8\r\n\r\n{\"odata.error\":{\"code\":\"InvalidDuplicateRow\",\"message\":{\"lang\":\"en-US\",\"value\":\"1:The + batch request contains multiple changes with same row key. An entity can appear + only once in a batch request.\\nRequestId:532ac3ba-0002-003f-5bee-b2b565000000\\nTime:2017-04-11T18:11:10.6278114Z\"}}}\r\n--changesetresponse_472d4d32-edd9-4a1a-91cc-e265a58fdb38--\r\n--batchresponse_9ca4f1d7-1656-48bb-9424-95df6ef992f7--\r\n" + headers: + Cache-Control: + - no-cache + Content-Type: + - multipart/mixed; boundary=batchresponse_9ca4f1d7-1656-48bb-9424-95df6ef992f7 + Date: + - Tue, 11 Apr 2017 18:11:10 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 532ac3ba-0002-003f-5bee-b2b565000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:njb4+PrjVSZhwsBX15rCVfgCrdtFG+H56EoHnD3WmhU= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Tue, 11 Apr 2017 18:11:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table48tablebatchsuitetestbatchi%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Tue, 11 Apr 2017 18:11:10 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 532ac3d8-0002-003f-78ee-b2b565000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/TableBatchSuite/Test_BatchInsertMultipleEntities.yaml b/storage/recordings/TableBatchSuite/Test_BatchInsertMultipleEntities.yaml new file mode 100644 index 000000000000..f06f7aaf8d4c --- /dev/null +++ b/storage/recordings/TableBatchSuite/Test_BatchInsertMultipleEntities.yaml @@ -0,0 +1,175 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: | + {"TableName":"tableme48tablebatchsuitetestbatc"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:1t2kY6E0PFMc1W+posaBaQmjBq5FxR+gI/5VXQMEUEo= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Tue, 11 Apr 2017 18:11:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('tableme48tablebatchsuitetestbatc') + Date: + - Tue, 11 Apr 2017 18:11:10 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('tableme48tablebatchsuitetestbatc') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 532ac3f2-0002-003f-12ee-b2b565000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "--batch_3dc2084d-1ee2-11e7-b451-6451064d81e8\r\nContent-Type: multipart/mixed; + boundary=changeset_3dc1f365-1ee2-11e7-b451-6451064d81e8\r\n\r\n\r\n--changeset_3dc1f365-1ee2-11e7-b451-6451064d81e8\r\nContent-Transfer-Encoding: + binary\r\nContent-Type: application/http\r\n\r\nPUT https://golangrocksonazure.table.core.windows.net/tableme48tablebatchsuitetestbatc%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29 + HTTP/1.1\r\nAccept: application/json;odata=minimalmetadata\r\nContent-Type: + application/json\r\nPrefer: return-no-content\r\n\r\n{\"AmountDue\":200.23,\"CustomerCode\":\"c9da6455-213d-42c9-9a79-3e9149a57833\",\"CustomerCode@odata.type\":\"Edm.Guid\",\"CustomerSince\":\"1992-12-20T21:55:00Z\",\"CustomerSince@odata.type\":\"Edm.DateTime\",\"IsActive\":true,\"NumberOfOrders\":\"255\",\"NumberOfOrders@odata.type\":\"Edm.Int64\",\"PartitionKey\":\"mypartitionkey\",\"RowKey\":\"myrowkey\"}\r\n--changeset_3dc1f365-1ee2-11e7-b451-6451064d81e8\r\nContent-Transfer-Encoding: + binary\r\nContent-Type: application/http\r\n\r\nPUT https://golangrocksonazure.table.core.windows.net/tableme48tablebatchsuitetestbatc%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey2%27%29 + HTTP/1.1\r\nAccept: application/json;odata=minimalmetadata\r\nContent-Type: + application/json\r\nPrefer: return-no-content\r\n\r\n{\"AmountDue\":111.23,\"CustomerCode\":\"c9da6455-213d-42c9-9a79-3e9149a57833\",\"CustomerCode@odata.type\":\"Edm.Guid\",\"CustomerSince\":\"1992-12-20T21:55:00Z\",\"CustomerSince@odata.type\":\"Edm.DateTime\",\"IsActive\":true,\"NumberOfOrders\":\"255\",\"NumberOfOrders@odata.type\":\"Edm.Int64\",\"PartitionKey\":\"mypartitionkey\",\"RowKey\":\"myrowkey2\"}\r\n--changeset_3dc1f365-1ee2-11e7-b451-6451064d81e8--\r\n\r\n--batch_3dc2084d-1ee2-11e7-b451-6451064d81e8--\r\n" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:RGy3qLgRm7bByfCAkyVhvp3agRTqbXD9q8Do04EOF+o= + Content-Type: + - multipart/mixed; boundary=batch_3dc2084d-1ee2-11e7-b451-6451064d81e8 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Tue, 11 Apr 2017 18:11:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/$batch + method: POST + response: + body: "--batchresponse_bfc11b1c-a658-48ee-aa5b-bc376d99e9c1\r\nContent-Type: multipart/mixed; + boundary=changesetresponse_86be85ca-279f-4cfe-9621-888c22f50739\r\n\r\n--changesetresponse_86be85ca-279f-4cfe-9621-888c22f50739\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\n\r\nHTTP/1.1 204 No + Content\r\nX-Content-Type-Options: nosniff\r\nCache-Control: no-cache\r\nPreference-Applied: + return-no-content\r\nDataServiceVersion: 3.0;\r\nETag: W/\"datetime'2017-04-11T18%3A11%3A11.0200758Z'\"\r\n\r\n\r\n--changesetresponse_86be85ca-279f-4cfe-9621-888c22f50739\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\n\r\nHTTP/1.1 204 No + Content\r\nX-Content-Type-Options: nosniff\r\nCache-Control: no-cache\r\nPreference-Applied: + return-no-content\r\nDataServiceVersion: 3.0;\r\nETag: W/\"datetime'2017-04-11T18%3A11%3A11.0200758Z'\"\r\n\r\n\r\n--changesetresponse_86be85ca-279f-4cfe-9621-888c22f50739--\r\n--batchresponse_bfc11b1c-a658-48ee-aa5b-bc376d99e9c1--\r\n" + headers: + Cache-Control: + - no-cache + Content-Type: + - multipart/mixed; boundary=batchresponse_bfc11b1c-a658-48ee-aa5b-bc376d99e9c1 + Date: + - Tue, 11 Apr 2017 18:11:10 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 532ac404-0002-003f-22ee-b2b565000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Authorization: + - SharedKey golangrocksonazure:rXjmlnktLYdHXc3yoRSvyZadPKkRgnTg6EtWc37SJN8= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Tue, 11 Apr 2017 18:11:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/tableme48tablebatchsuitetestbatc?%24top=2&timeout=30 + method: GET + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#tableme48tablebatchsuitetestbatc","value":[{"odata.type":"golangrocksonazure.tableme48tablebatchsuitetestbatc","odata.id":"https://golangrocksonazure.table.core.windows.net/tableme48tablebatchsuitetestbatc(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')","odata.etag":"W/\"datetime''2017-04-11T18%3A11%3A11.0200758Z''\"","odata.editLink":"tableme48tablebatchsuitetestbatc(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')","PartitionKey":"mypartitionkey","RowKey":"myrowkey","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-11T18:11:11.0200758Z","AmountDue":200.23,"CustomerCode@odata.type":"Edm.Guid","CustomerCode":"c9da6455-213d-42c9-9a79-3e9149a57833","CustomerSince@odata.type":"Edm.DateTime","CustomerSince":"1992-12-20T21:55:00Z","IsActive":true,"NumberOfOrders@odata.type":"Edm.Int64","NumberOfOrders":"255"},{"odata.type":"golangrocksonazure.tableme48tablebatchsuitetestbatc","odata.id":"https://golangrocksonazure.table.core.windows.net/tableme48tablebatchsuitetestbatc(PartitionKey=''mypartitionkey'',RowKey=''myrowkey2'')","odata.etag":"W/\"datetime''2017-04-11T18%3A11%3A11.0200758Z''\"","odata.editLink":"tableme48tablebatchsuitetestbatc(PartitionKey=''mypartitionkey'',RowKey=''myrowkey2'')","PartitionKey":"mypartitionkey","RowKey":"myrowkey2","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-11T18:11:11.0200758Z","AmountDue":111.23,"CustomerCode@odata.type":"Edm.Guid","CustomerCode":"c9da6455-213d-42c9-9a79-3e9149a57833","CustomerSince@odata.type":"Edm.DateTime","CustomerSince":"1992-12-20T21:55:00Z","IsActive":true,"NumberOfOrders@odata.type":"Edm.Int64","NumberOfOrders":"255"}]}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Tue, 11 Apr 2017 18:11:10 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 532ac414-0002-003f-32ee-b2b565000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:XoadbcLScLmBf/0/Mxvx4pFrC4CXPG86sXfm8gbcj28= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Tue, 11 Apr 2017 18:11:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27tableme48tablebatchsuitetestbatc%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Tue, 11 Apr 2017 18:11:10 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 532ac41d-0002-003f-3bee-b2b565000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/TableBatchSuite/Test_BatchInsertSameEntryMultipleTimes.yaml b/storage/recordings/TableBatchSuite/Test_BatchInsertSameEntryMultipleTimes.yaml new file mode 100644 index 000000000000..eddcade56a1e --- /dev/null +++ b/storage/recordings/TableBatchSuite/Test_BatchInsertSameEntryMultipleTimes.yaml @@ -0,0 +1,139 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: | + {"TableName":"table54tablebatchsuitetestbatchi"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:1t2kY6E0PFMc1W+posaBaQmjBq5FxR+gI/5VXQMEUEo= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Tue, 11 Apr 2017 18:11:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table54tablebatchsuitetestbatchi') + Date: + - Tue, 11 Apr 2017 18:11:10 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table54tablebatchsuitetestbatchi') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 532ac430-0002-003f-4eee-b2b565000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "--batch_3de4c6dd-1ee2-11e7-b452-6451064d81e8\r\nContent-Type: multipart/mixed; + boundary=changeset_3de4c6dd-1ee2-11e7-b451-6451064d81e8\r\n\r\n\r\n--changeset_3de4c6dd-1ee2-11e7-b451-6451064d81e8\r\nContent-Transfer-Encoding: + binary\r\nContent-Type: application/http\r\n\r\nPUT https://golangrocksonazure.table.core.windows.net/table54tablebatchsuitetestbatchi%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29 + HTTP/1.1\r\nAccept: application/json;odata=minimalmetadata\r\nContent-Type: + application/json\r\nPrefer: return-no-content\r\n\r\n{\"AmountDue\":200.23,\"CustomerCode\":\"c9da6455-213d-42c9-9a79-3e9149a57833\",\"CustomerCode@odata.type\":\"Edm.Guid\",\"CustomerSince\":\"1992-12-20T21:55:00Z\",\"CustomerSince@odata.type\":\"Edm.DateTime\",\"IsActive\":true,\"NumberOfOrders\":\"255\",\"NumberOfOrders@odata.type\":\"Edm.Int64\",\"PartitionKey\":\"mypartitionkey\",\"RowKey\":\"myrowkey\"}\r\n--changeset_3de4c6dd-1ee2-11e7-b451-6451064d81e8\r\nContent-Transfer-Encoding: + binary\r\nContent-Type: application/http\r\n\r\nPUT https://golangrocksonazure.table.core.windows.net/table54tablebatchsuitetestbatchi%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29 + HTTP/1.1\r\nAccept: application/json;odata=minimalmetadata\r\nContent-Type: + application/json\r\nPrefer: return-no-content\r\n\r\n{\"AmountDue\":200.23,\"CustomerCode\":\"c9da6455-213d-42c9-9a79-3e9149a57833\",\"CustomerCode@odata.type\":\"Edm.Guid\",\"CustomerSince\":\"1992-12-20T21:55:00Z\",\"CustomerSince@odata.type\":\"Edm.DateTime\",\"IsActive\":true,\"NumberOfOrders\":\"255\",\"NumberOfOrders@odata.type\":\"Edm.Int64\",\"PartitionKey\":\"mypartitionkey\",\"RowKey\":\"myrowkey\"}\r\n--changeset_3de4c6dd-1ee2-11e7-b451-6451064d81e8--\r\n\r\n--batch_3de4c6dd-1ee2-11e7-b452-6451064d81e8--\r\n" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:uxFNTMoAUgZ/GMqj6jw/6t4jdmlHuLfzE3coBobRHJ4= + Content-Type: + - multipart/mixed; boundary=batch_3de4c6dd-1ee2-11e7-b452-6451064d81e8 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Tue, 11 Apr 2017 18:11:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/$batch + method: POST + response: + body: "--batchresponse_96d3b428-9daf-41b4-b4ac-d860a49e8d8f\r\nContent-Type: multipart/mixed; + boundary=changesetresponse_dee290b3-2a8d-457c-9cdf-fae6298ba725\r\n\r\n--changesetresponse_dee290b3-2a8d-457c-9cdf-fae6298ba725\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\n\r\nHTTP/1.1 400 Bad + Request\r\nX-Content-Type-Options: nosniff\r\nCache-Control: no-cache\r\nPreference-Applied: + return-no-content\r\nDataServiceVersion: 3.0;\r\nContent-Type: application/json;odata=minimalmetadata;streaming=true;charset=utf-8\r\n\r\n{\"odata.error\":{\"code\":\"InvalidDuplicateRow\",\"message\":{\"lang\":\"en-US\",\"value\":\"1:The + batch request contains multiple changes with same row key. An entity can appear + only once in a batch request.\\nRequestId:532ac444-0002-003f-60ee-b2b565000000\\nTime:2017-04-11T18:11:11.0180936Z\"}}}\r\n--changesetresponse_dee290b3-2a8d-457c-9cdf-fae6298ba725--\r\n--batchresponse_96d3b428-9daf-41b4-b4ac-d860a49e8d8f--\r\n" + headers: + Cache-Control: + - no-cache + Content-Type: + - multipart/mixed; boundary=batchresponse_96d3b428-9daf-41b4-b4ac-d860a49e8d8f + Date: + - Tue, 11 Apr 2017 18:11:10 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 532ac444-0002-003f-60ee-b2b565000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:ei0mh49CqmGLtaxg9XGZQPaQs17FMWuVMepYxvS34I0= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Tue, 11 Apr 2017 18:11:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table54tablebatchsuitetestbatchi%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Tue, 11 Apr 2017 18:11:10 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 532ac464-0002-003f-80ee-b2b565000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/TableBatchSuite/Test_BatchInsertThenDeleteDifferentBatches.yaml b/storage/recordings/TableBatchSuite/Test_BatchInsertThenDeleteDifferentBatches.yaml new file mode 100644 index 000000000000..6f8a07a91384 --- /dev/null +++ b/storage/recordings/TableBatchSuite/Test_BatchInsertThenDeleteDifferentBatches.yaml @@ -0,0 +1,247 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: | + {"TableName":"table58tablebatchsuitetestbatchi"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:ZQjoLUu4jawD/lq7c/3xRqALvT8f8g38m4N7oumNERg= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Tue, 11 Apr 2017 18:10:59 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table58tablebatchsuitetestbatchi') + Date: + - Tue, 11 Apr 2017 18:10:59 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table58tablebatchsuitetestbatchi') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - b800ff32-0002-00cb-42ee-b29089000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "--batch_370daf3b-1ee2-11e7-8317-6451064d81e8\r\nContent-Type: multipart/mixed; + boundary=changeset_370daf3b-1ee2-11e7-8316-6451064d81e8\r\n\r\n\r\n--changeset_370daf3b-1ee2-11e7-8316-6451064d81e8\r\nContent-Transfer-Encoding: + binary\r\nContent-Type: application/http\r\n\r\nPUT https://golangrocksonazure.table.core.windows.net/table58tablebatchsuitetestbatchi%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29 + HTTP/1.1\r\nAccept: application/json;odata=minimalmetadata\r\nContent-Type: + application/json\r\nPrefer: return-no-content\r\n\r\n{\"AmountDue\":200.23,\"CustomerCode\":\"c9da6455-213d-42c9-9a79-3e9149a57833\",\"CustomerCode@odata.type\":\"Edm.Guid\",\"CustomerSince\":\"1992-12-20T21:55:00Z\",\"CustomerSince@odata.type\":\"Edm.DateTime\",\"IsActive\":true,\"NumberOfOrders\":\"255\",\"NumberOfOrders@odata.type\":\"Edm.Int64\",\"PartitionKey\":\"mypartitionkey\",\"RowKey\":\"myrowkey\"}\r\n--changeset_370daf3b-1ee2-11e7-8316-6451064d81e8--\r\n\r\n--batch_370daf3b-1ee2-11e7-8317-6451064d81e8--\r\n" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:gTrel6MHrzDhnjAXvMxeSo+kteLobWHWbyZT4p1DoEg= + Content-Type: + - multipart/mixed; boundary=batch_370daf3b-1ee2-11e7-8317-6451064d81e8 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Tue, 11 Apr 2017 18:10:59 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/$batch + method: POST + response: + body: "--batchresponse_36b3f5cf-db00-43ec-9831-87f61fc944a6\r\nContent-Type: multipart/mixed; + boundary=changesetresponse_fed881dc-a747-4d56-b60d-c8d6763d1262\r\n\r\n--changesetresponse_fed881dc-a747-4d56-b60d-c8d6763d1262\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\n\r\nHTTP/1.1 204 No + Content\r\nX-Content-Type-Options: nosniff\r\nCache-Control: no-cache\r\nPreference-Applied: + return-no-content\r\nDataServiceVersion: 3.0;\r\nETag: W/\"datetime'2017-04-11T18%3A10%3A59.8211935Z'\"\r\n\r\n\r\n--changesetresponse_fed881dc-a747-4d56-b60d-c8d6763d1262--\r\n--batchresponse_36b3f5cf-db00-43ec-9831-87f61fc944a6--\r\n" + headers: + Cache-Control: + - no-cache + Content-Type: + - multipart/mixed; boundary=batchresponse_36b3f5cf-db00-43ec-9831-87f61fc944a6 + Date: + - Tue, 11 Apr 2017 18:10:59 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - b800ff5b-0002-00cb-69ee-b29089000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Authorization: + - SharedKey golangrocksonazure:3H/253yNS75pLlEe3et1OQDloOOhxRzKwaXbmoQMr70= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Tue, 11 Apr 2017 18:10:59 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table58tablebatchsuitetestbatchi?%24top=2&timeout=30 + method: GET + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table58tablebatchsuitetestbatchi","value":[{"odata.type":"golangrocksonazure.table58tablebatchsuitetestbatchi","odata.id":"https://golangrocksonazure.table.core.windows.net/table58tablebatchsuitetestbatchi(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')","odata.etag":"W/\"datetime''2017-04-11T18%3A10%3A59.8211935Z''\"","odata.editLink":"table58tablebatchsuitetestbatchi(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')","PartitionKey":"mypartitionkey","RowKey":"myrowkey","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-11T18:10:59.8211935Z","AmountDue":200.23,"CustomerCode@odata.type":"Edm.Guid","CustomerCode":"c9da6455-213d-42c9-9a79-3e9149a57833","CustomerSince@odata.type":"Edm.DateTime","CustomerSince":"1992-12-20T21:55:00Z","IsActive":true,"NumberOfOrders@odata.type":"Edm.Int64","NumberOfOrders":"255"}]}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Tue, 11 Apr 2017 18:10:59 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - b800ff7f-0002-00cb-0cee-b29089000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "--batch_372510dc-1ee2-11e7-8318-6451064d81e8\r\nContent-Type: multipart/mixed; + boundary=changeset_372510dc-1ee2-11e7-8317-6451064d81e8\r\n\r\n\r\n--changeset_372510dc-1ee2-11e7-8317-6451064d81e8\r\nContent-Transfer-Encoding: + binary\r\nContent-Type: application/http\r\n\r\nDELETE https://golangrocksonazure.table.core.windows.net/table58tablebatchsuitetestbatchi%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29 + HTTP/1.1\r\nAccept: application/json;odata=minimalmetadata\r\nContent-Type: + application/json\r\nIf-Match: *\r\nPrefer: return-no-content\r\n\r\n\r\n--changeset_372510dc-1ee2-11e7-8317-6451064d81e8--\r\n\r\n--batch_372510dc-1ee2-11e7-8318-6451064d81e8--\r\n" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:N6gOtxf+slIZfj5WjvFlcvuzTzWaEcPLF7Z4pcDhnz8= + Content-Type: + - multipart/mixed; boundary=batch_372510dc-1ee2-11e7-8318-6451064d81e8 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Tue, 11 Apr 2017 18:10:59 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/$batch + method: POST + response: + body: "--batchresponse_116ab46a-7032-4c60-9147-9909a6e7952a\r\nContent-Type: multipart/mixed; + boundary=changesetresponse_2e8ecc3d-ff43-408c-9f0d-decb9e160bf0\r\n\r\n--changesetresponse_2e8ecc3d-ff43-408c-9f0d-decb9e160bf0\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\n\r\nHTTP/1.1 204 No + Content\r\nX-Content-Type-Options: nosniff\r\nCache-Control: no-cache\r\nDataServiceVersion: + 1.0;\r\n\r\n\r\n--changesetresponse_2e8ecc3d-ff43-408c-9f0d-decb9e160bf0--\r\n--batchresponse_116ab46a-7032-4c60-9147-9909a6e7952a--\r\n" + headers: + Cache-Control: + - no-cache + Content-Type: + - multipart/mixed; boundary=batchresponse_116ab46a-7032-4c60-9147-9909a6e7952a + Date: + - Tue, 11 Apr 2017 18:10:59 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - b800ff98-0002-00cb-24ee-b29089000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Authorization: + - SharedKey golangrocksonazure:3H/253yNS75pLlEe3et1OQDloOOhxRzKwaXbmoQMr70= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Tue, 11 Apr 2017 18:10:59 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table58tablebatchsuitetestbatchi?%24top=2&timeout=15 + method: GET + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table58tablebatchsuitetestbatchi","value":[]}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Tue, 11 Apr 2017 18:10:59 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - b800ffad-0002-00cb-39ee-b29089000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:TlhMcLi8twonEpG/QCzz7vy3UsbnLLi+1DaGb/aC6sc= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Tue, 11 Apr 2017 18:10:59 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table58tablebatchsuitetestbatchi%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Tue, 11 Apr 2017 18:10:59 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - b800ffbe-0002-00cb-4aee-b29089000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/recordings/TableBatchSuite/Test_BatchInsertThenMergeDifferentBatches.yaml b/storage/recordings/TableBatchSuite/Test_BatchInsertThenMergeDifferentBatches.yaml new file mode 100644 index 000000000000..8290128a3e2a --- /dev/null +++ b/storage/recordings/TableBatchSuite/Test_BatchInsertThenMergeDifferentBatches.yaml @@ -0,0 +1,212 @@ +--- +version: 1 +rwmutex: {} +interactions: +- request: + body: | + {"TableName":"table57tablebatchsuitetestbatchi"} + form: {} + headers: + Accept: + - application/json;odata=nometadata + Accept-Charset: + - UTF-8 + Authorization: + - SharedKey golangrocksonazure:1t2kY6E0PFMc1W+posaBaQmjBq5FxR+gI/5VXQMEUEo= + Content-Length: + - "49" + Content-Type: + - application/json + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Tue, 11 Apr 2017 18:11:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://golangrocksonazure.table.core.windows.net/Tables('table57tablebatchsuitetestbatchi') + Date: + - Tue, 11 Apr 2017 18:11:10 GMT + Location: + - https://golangrocksonazure.table.core.windows.net/Tables('table57tablebatchsuitetestbatchi') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 532ac490-0002-003f-2cee-b2b565000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 +- request: + body: "--batch_3e004b55-1ee2-11e7-b454-6451064d81e8\r\nContent-Type: multipart/mixed; + boundary=changeset_3e004b55-1ee2-11e7-b453-6451064d81e8\r\n\r\n\r\n--changeset_3e004b55-1ee2-11e7-b453-6451064d81e8\r\nContent-Transfer-Encoding: + binary\r\nContent-Type: application/http\r\n\r\nPUT https://golangrocksonazure.table.core.windows.net/table57tablebatchsuitetestbatchi%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29 + HTTP/1.1\r\nAccept: application/json;odata=minimalmetadata\r\nContent-Type: + application/json\r\nPrefer: return-no-content\r\n\r\n{\"AmountDue\":200.23,\"CustomerCode\":\"c9da6455-213d-42c9-9a79-3e9149a57833\",\"CustomerCode@odata.type\":\"Edm.Guid\",\"CustomerSince\":\"1992-12-20T21:55:00Z\",\"CustomerSince@odata.type\":\"Edm.DateTime\",\"IsActive\":true,\"NumberOfOrders\":\"255\",\"NumberOfOrders@odata.type\":\"Edm.Int64\",\"PartitionKey\":\"mypartitionkey\",\"RowKey\":\"myrowkey\"}\r\n--changeset_3e004b55-1ee2-11e7-b453-6451064d81e8--\r\n\r\n--batch_3e004b55-1ee2-11e7-b454-6451064d81e8--\r\n" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:MNYkaMVXUmwr78A4rKs6MJvi/scN2r6+JhTAA1KPZjw= + Content-Type: + - multipart/mixed; boundary=batch_3e004b55-1ee2-11e7-b454-6451064d81e8 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Tue, 11 Apr 2017 18:11:10 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/$batch + method: POST + response: + body: "--batchresponse_dba5b2db-650e-48c5-b5b9-a3770097be23\r\nContent-Type: multipart/mixed; + boundary=changesetresponse_9787c335-dd9c-49b5-9a1b-8ea7983786d9\r\n\r\n--changesetresponse_9787c335-dd9c-49b5-9a1b-8ea7983786d9\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\n\r\nHTTP/1.1 204 No + Content\r\nX-Content-Type-Options: nosniff\r\nCache-Control: no-cache\r\nPreference-Applied: + return-no-content\r\nDataServiceVersion: 3.0;\r\nETag: W/\"datetime'2017-04-11T18%3A11%3A11.4273629Z'\"\r\n\r\n\r\n--changesetresponse_9787c335-dd9c-49b5-9a1b-8ea7983786d9--\r\n--batchresponse_dba5b2db-650e-48c5-b5b9-a3770097be23--\r\n" + headers: + Cache-Control: + - no-cache + Content-Type: + - multipart/mixed; boundary=batchresponse_dba5b2db-650e-48c5-b5b9-a3770097be23 + Date: + - Tue, 11 Apr 2017 18:11:10 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 532ac4a3-0002-003f-3eee-b2b565000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "--batch_3e085bac-1ee2-11e7-b455-6451064d81e8\r\nContent-Type: multipart/mixed; + boundary=changeset_3e085bac-1ee2-11e7-b454-6451064d81e8\r\n\r\n\r\n--changeset_3e085bac-1ee2-11e7-b454-6451064d81e8\r\nContent-Transfer-Encoding: + binary\r\nContent-Type: application/http\r\n\r\nPUT https://golangrocksonazure.table.core.windows.net/table57tablebatchsuitetestbatchi%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29 + HTTP/1.1\r\nAccept: application/json;odata=minimalmetadata\r\nContent-Type: + application/json\r\nPrefer: return-no-content\r\n\r\n{\"AmountDue\":200.23,\"CustomerCode\":\"c9da6455-213d-42c9-9a79-3e9149a57833\",\"CustomerCode@odata.type\":\"Edm.Guid\",\"CustomerSince\":\"1992-12-20T21:55:00Z\",\"CustomerSince@odata.type\":\"Edm.DateTime\",\"DifferentField\":123,\"NumberOfOrders\":\"255\",\"NumberOfOrders@odata.type\":\"Edm.Int64\",\"PartitionKey\":\"mypartitionkey\",\"RowKey\":\"myrowkey\"}\r\n--changeset_3e085bac-1ee2-11e7-b454-6451064d81e8--\r\n\r\n--batch_3e085bac-1ee2-11e7-b455-6451064d81e8--\r\n" + form: {} + headers: + Authorization: + - SharedKey golangrocksonazure:X19NrQ82k2XSNtPA3NIJJvIC+QoZLxhxBBYslyYLUnQ= + Content-Type: + - multipart/mixed; boundary=batch_3e085bac-1ee2-11e7-b455-6451064d81e8 + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Tue, 11 Apr 2017 18:11:11 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/$batch + method: POST + response: + body: "--batchresponse_7a3cefa7-bd6f-4ca0-81c1-69bae992a821\r\nContent-Type: multipart/mixed; + boundary=changesetresponse_0ce041c5-c9ca-4cf9-886e-44542e81235d\r\n\r\n--changesetresponse_0ce041c5-c9ca-4cf9-886e-44542e81235d\r\nContent-Type: + application/http\r\nContent-Transfer-Encoding: binary\r\n\r\nHTTP/1.1 204 No + Content\r\nX-Content-Type-Options: nosniff\r\nCache-Control: no-cache\r\nPreference-Applied: + return-no-content\r\nDataServiceVersion: 3.0;\r\nETag: W/\"datetime'2017-04-11T18%3A11%3A11.476397Z'\"\r\n\r\n\r\n--changesetresponse_0ce041c5-c9ca-4cf9-886e-44542e81235d--\r\n--batchresponse_7a3cefa7-bd6f-4ca0-81c1-69bae992a821--\r\n" + headers: + Cache-Control: + - no-cache + Content-Type: + - multipart/mixed; boundary=batchresponse_7a3cefa7-bd6f-4ca0-81c1-69bae992a821 + Date: + - Tue, 11 Apr 2017 18:11:10 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 532ac4be-0002-003f-59ee-b2b565000000 + X-Ms-Version: + - 2016-05-31 + status: 202 Accepted + code: 202 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=fullmetadata + Authorization: + - SharedKey golangrocksonazure:fVYsV74PwOzoaxoWf4Z8Gm0hcROYbMQp7/g26UW/nls= + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Tue, 11 Apr 2017 18:11:11 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/table57tablebatchsuitetestbatchi?%24top=2&timeout=30 + method: GET + response: + body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table57tablebatchsuitetestbatchi","value":[{"odata.type":"golangrocksonazure.table57tablebatchsuitetestbatchi","odata.id":"https://golangrocksonazure.table.core.windows.net/table57tablebatchsuitetestbatchi(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')","odata.etag":"W/\"datetime''2017-04-11T18%3A11%3A11.476397Z''\"","odata.editLink":"table57tablebatchsuitetestbatchi(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')","PartitionKey":"mypartitionkey","RowKey":"myrowkey","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-11T18:11:11.476397Z","AmountDue":200.23,"CustomerCode@odata.type":"Edm.Guid","CustomerCode":"c9da6455-213d-42c9-9a79-3e9149a57833","CustomerSince@odata.type":"Edm.DateTime","CustomerSince":"1992-12-20T21:55:00Z","DifferentField":123,"NumberOfOrders@odata.type":"Edm.Int64","NumberOfOrders":"255"}]}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=fullmetadata;streaming=true;charset=utf-8 + Date: + - Tue, 11 Apr 2017 18:11:10 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 532ac4db-0002-003f-74ee-b2b565000000 + X-Ms-Version: + - 2016-05-31 + status: 200 OK + code: 200 +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=nometadata + Authorization: + - SharedKey golangrocksonazure:ReX2dTRJLE2TBb/qmswmRFOPQjkv4otu9COqHtNUrvE= + Prefer: + - return-no-content + User-Agent: + - Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table + X-Ms-Date: + - Tue, 11 Apr 2017 18:11:11 GMT + X-Ms-Version: + - 2016-05-31 + url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table57tablebatchsuitetestbatchi%27%29?timeout=30 + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Tue, 11 Apr 2017 18:11:10 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 532ac4ef-0002-003f-08ee-b2b565000000 + X-Ms-Version: + - 2016-05-31 + status: 204 No Content + code: 204 diff --git a/storage/share.go b/storage/share.go index e190097ea5cd..e6a868081a01 100644 --- a/storage/share.go +++ b/storage/share.go @@ -30,9 +30,15 @@ func (s *Share) buildPath() string { // Create this share under the associated account. // If a share with the same name already exists, the operation fails. // -// See https://msdn.microsoft.com/en-us/library/azure/dn167008.aspx -func (s *Share) Create() error { - headers, err := s.fsc.createResource(s.buildPath(), resourceShare, nil, mergeMDIntoExtraHeaders(s.Metadata, nil), []int{http.StatusCreated}) +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Create-Share +func (s *Share) Create(options *FileRequestOptions) error { + extraheaders := map[string]string{} + if s.Properties.Quota > 0 { + extraheaders["x-ms-share-quota"] = strconv.Itoa(s.Properties.Quota) + } + + params := prepareOptions(options) + headers, err := s.fsc.createResource(s.buildPath(), resourceShare, params, mergeMDIntoExtraHeaders(s.Metadata, extraheaders), []int{http.StatusCreated}) if err != nil { return err } @@ -45,9 +51,15 @@ func (s *Share) Create() error { // it does not exist. Returns true if the share is newly created or false if // the share already exists. // -// See https://msdn.microsoft.com/en-us/library/azure/dn167008.aspx -func (s *Share) CreateIfNotExists() (bool, error) { - resp, err := s.fsc.createResourceNoClose(s.buildPath(), resourceShare, nil, nil) +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Create-Share +func (s *Share) CreateIfNotExists(options *FileRequestOptions) (bool, error) { + extraheaders := map[string]string{} + if s.Properties.Quota > 0 { + extraheaders["x-ms-share-quota"] = strconv.Itoa(s.Properties.Quota) + } + + params := prepareOptions(options) + resp, err := s.fsc.createResourceNoClose(s.buildPath(), resourceShare, params, extraheaders) if resp != nil { defer readAndCloseBody(resp.body) if resp.statusCode == http.StatusCreated || resp.statusCode == http.StatusConflict { @@ -55,7 +67,7 @@ func (s *Share) CreateIfNotExists() (bool, error) { s.updateEtagAndLastModified(resp.headers) return true, nil } - return false, s.FetchAttributes() + return false, s.FetchAttributes(nil) } } @@ -66,16 +78,16 @@ func (s *Share) CreateIfNotExists() (bool, error) { // and directories contained within it are later deleted during garbage // collection. If the share does not exist the operation fails // -// See https://msdn.microsoft.com/en-us/library/azure/dn689090.aspx -func (s *Share) Delete() error { - return s.fsc.deleteResource(s.buildPath(), resourceShare) +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Delete-Share +func (s *Share) Delete(options *FileRequestOptions) error { + return s.fsc.deleteResource(s.buildPath(), resourceShare, options) } // DeleteIfExists operation marks this share for deletion if it exists. // -// See https://msdn.microsoft.com/en-us/library/azure/dn689090.aspx -func (s *Share) DeleteIfExists() (bool, error) { - resp, err := s.fsc.deleteResourceNoClose(s.buildPath(), resourceShare) +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Delete-Share +func (s *Share) DeleteIfExists(options *FileRequestOptions) (bool, error) { + resp, err := s.fsc.deleteResourceNoClose(s.buildPath(), resourceShare, options) if resp != nil { defer readAndCloseBody(resp.body) if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound { @@ -97,8 +109,10 @@ func (s *Share) Exists() (bool, error) { } // FetchAttributes retrieves metadata and properties for this share. -func (s *Share) FetchAttributes() error { - headers, err := s.fsc.getResourceHeaders(s.buildPath(), compNone, resourceShare, http.MethodHead) +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-share-properties +func (s *Share) FetchAttributes(options *FileRequestOptions) error { + params := prepareOptions(options) + headers, err := s.fsc.getResourceHeaders(s.buildPath(), compNone, resourceShare, params, http.MethodHead) if err != nil { return err } @@ -130,9 +144,9 @@ func (s *Share) ServiceClient() *FileServiceClient { // are case-insensitive so case munging should not matter to other // applications either. // -// See https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx -func (s *Share) SetMetadata() error { - headers, err := s.fsc.setResourceHeaders(s.buildPath(), compMetadata, resourceShare, mergeMDIntoExtraHeaders(s.Metadata, nil)) +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/set-share-metadata +func (s *Share) SetMetadata(options *FileRequestOptions) error { + headers, err := s.fsc.setResourceHeaders(s.buildPath(), compMetadata, resourceShare, mergeMDIntoExtraHeaders(s.Metadata, nil), options) if err != nil { return err } @@ -148,15 +162,17 @@ func (s *Share) SetMetadata() error { // are case-insensitive so case munging should not matter to other // applications either. // -// See https://msdn.microsoft.com/en-us/library/azure/mt427368.aspx -func (s *Share) SetProperties() error { - if s.Properties.Quota < 1 || s.Properties.Quota > 5120 { - return fmt.Errorf("invalid value %v for quota, valid values are [1, 5120]", s.Properties.Quota) +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Set-Share-Properties +func (s *Share) SetProperties(options *FileRequestOptions) error { + extraheaders := map[string]string{} + if s.Properties.Quota > 0 { + if s.Properties.Quota > 5120 { + return fmt.Errorf("invalid value %v for quota, valid values are [1, 5120]", s.Properties.Quota) + } + extraheaders["x-ms-share-quota"] = strconv.Itoa(s.Properties.Quota) } - headers, err := s.fsc.setResourceHeaders(s.buildPath(), compProperties, resourceShare, map[string]string{ - "x-ms-share-quota": strconv.Itoa(s.Properties.Quota), - }) + headers, err := s.fsc.setResourceHeaders(s.buildPath(), compProperties, resourceShare, extraheaders, options) if err != nil { return err } diff --git a/storage/share_test.go b/storage/share_test.go index 863c32d0bc82..2e207bdc9d5c 100644 --- a/storage/share_test.go +++ b/storage/share_test.go @@ -1,118 +1,133 @@ package storage -import ( - "math/rand" - - chk "gopkg.in/check.v1" -) +import chk "gopkg.in/check.v1" type StorageShareSuite struct{} var _ = chk.Suite(&StorageShareSuite{}) -const testSharePrefix = "zzzzztest" - -func randShare() string { - return testSharePrefix + randString(32-len(testSharePrefix)) -} - func getFileClient(c *chk.C) FileServiceClient { return getBasicClient(c).GetFileService() } func (s *StorageShareSuite) TestCreateShareDeleteShare(c *chk.C) { cli := getFileClient(c) - share := cli.GetShareReference(randShare()) - c.Assert(share.Create(), chk.IsNil) - c.Assert(share.Delete(), chk.IsNil) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + share := cli.GetShareReference(shareName(c)) + c.Assert(share.Create(nil), chk.IsNil) + c.Assert(share.Delete(nil), chk.IsNil) } func (s *StorageShareSuite) TestCreateShareIfNotExists(c *chk.C) { cli := getFileClient(c) - share := cli.GetShareReference(randShare()) + rec := cli.client.appendRecorder(c) + defer rec.Stop() - // First create - ok, err := share.CreateIfNotExists() + // Create non existing + share := cli.GetShareReference(shareName(c, "notexists")) + ok, err := share.CreateIfNotExists(nil) + defer share.Delete(nil) c.Assert(err, chk.IsNil) c.Assert(ok, chk.Equals, true) - // Second create, should not give errors - ok, err = share.CreateIfNotExists() +} + +func (s *StorageShareSuite) TestCreateShareIfExists(c *chk.C) { + cli := getFileClient(c) + share := cli.GetShareReference(shareName(c, "exists")) + share.Create(nil) + defer share.Delete(nil) + + rec := cli.client.appendRecorder(c) + share.fsc = &cli + defer rec.Stop() + + // Try to create exisiting + ok, err := share.CreateIfNotExists(nil) c.Assert(err, chk.IsNil) c.Assert(ok, chk.Equals, false) - - // cleanup - share.Delete() } func (s *StorageShareSuite) TestDeleteShareIfNotExists(c *chk.C) { cli := getFileClient(c) - share := cli.GetShareReference(randShare()) + rec := cli.client.appendRecorder(c) + defer rec.Stop() // delete non-existing share - ok, err := share.DeleteIfExists() + share1 := cli.GetShareReference(shareName(c, "1")) + ok, err := share1.DeleteIfExists(nil) c.Assert(err, chk.IsNil) c.Assert(ok, chk.Equals, false) - c.Assert(share.Create(), chk.IsNil) - // delete existing share - ok, err = share.DeleteIfExists() + share2 := cli.GetShareReference(shareName(c, "2")) + c.Assert(share2.Create(nil), chk.IsNil) + ok, err = share2.DeleteIfExists(nil) c.Assert(err, chk.IsNil) c.Assert(ok, chk.Equals, true) } func (s *StorageShareSuite) TestListShares(c *chk.C) { cli := getFileClient(c) - c.Assert(deleteTestShares(cli), chk.IsNil) + cli.deleteAllShares() + rec := cli.client.appendRecorder(c) + defer rec.Stop() - name := randShare() + name := shareName(c) share := cli.GetShareReference(name) - c.Assert(share.Create(), chk.IsNil) + c.Assert(share.Create(nil), chk.IsNil) resp, err := cli.ListShares(ListSharesParameters{ MaxResults: 5, - Prefix: testSharePrefix}) + }) c.Assert(err, chk.IsNil) c.Check(len(resp.Shares), chk.Equals, 1) c.Check(resp.Shares[0].Name, chk.Equals, name) // clean up via the retrieved share object - resp.Shares[0].Delete() + resp.Shares[0].Delete(nil) } func (s *StorageShareSuite) TestShareExists(c *chk.C) { cli := getFileClient(c) - share := cli.GetShareReference(randShare()) + rec := cli.client.appendRecorder(c) + defer rec.Stop() - ok, err := share.Exists() + // Share does not exist + share1 := cli.GetShareReference(shareName(c, "1")) + ok, err := share1.Exists() c.Assert(err, chk.IsNil) c.Assert(ok, chk.Equals, false) - c.Assert(share.Create(), chk.IsNil) - defer share.Delete() - - ok, err = share.Exists() + // Share exists + share2 := cli.GetShareReference(shareName(c, "2")) + c.Assert(share2.Create(nil), chk.IsNil) + defer share1.Delete(nil) + ok, err = share2.Exists() c.Assert(err, chk.IsNil) c.Assert(ok, chk.Equals, true) } func (s *StorageShareSuite) TestGetAndSetShareProperties(c *chk.C) { cli := getFileClient(c) - share := cli.GetShareReference(randShare()) - quota := rand.Intn(5120) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + share := cli.GetShareReference(shareName(c)) + quota := 55 - c.Assert(share.Create(), chk.IsNil) - defer share.Delete() + c.Assert(share.Create(nil), chk.IsNil) + defer share.Delete(nil) c.Assert(share.Properties.LastModified, chk.Not(chk.Equals), "") share.Properties.Quota = quota - err := share.SetProperties() + err := share.SetProperties(nil) c.Assert(err, chk.IsNil) - err = share.FetchAttributes() + err = share.FetchAttributes(nil) c.Assert(err, chk.IsNil) c.Assert(share.Properties.Quota, chk.Equals, quota) @@ -120,69 +135,73 @@ func (s *StorageShareSuite) TestGetAndSetShareProperties(c *chk.C) { func (s *StorageShareSuite) TestGetAndSetShareMetadata(c *chk.C) { cli := getFileClient(c) - share1 := cli.GetShareReference(randShare()) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + share1 := cli.GetShareReference(shareName(c, "1")) - c.Assert(share1.Create(), chk.IsNil) - defer share1.Delete() + c.Assert(share1.Create(nil), chk.IsNil) + defer share1.Delete(nil) // by default there should be no metadata c.Assert(share1.Metadata, chk.IsNil) - c.Assert(share1.FetchAttributes(), chk.IsNil) + c.Assert(share1.FetchAttributes(nil), chk.IsNil) c.Assert(share1.Metadata, chk.IsNil) - share2 := cli.GetShareReference(randShare()) - c.Assert(share2.Create(), chk.IsNil) - defer share2.Delete() + share2 := cli.GetShareReference(shareName(c, "2")) + c.Assert(share2.Create(nil), chk.IsNil) + defer share2.Delete(nil) c.Assert(share2.Metadata, chk.IsNil) mPut := map[string]string{ - "foo": "bar", - "bar_baz": "waz qux", + "lol": "rofl", + "rofl_baz": "waz qux", } share2.Metadata = mPut - c.Assert(share2.SetMetadata(), chk.IsNil) + c.Assert(share2.SetMetadata(nil), chk.IsNil) c.Check(share2.Metadata, chk.DeepEquals, mPut) - c.Assert(share2.FetchAttributes(), chk.IsNil) + c.Assert(share2.FetchAttributes(nil), chk.IsNil) c.Check(share2.Metadata, chk.DeepEquals, mPut) +} + +func (s *StorageShareSuite) TestMetadataCaseMunging(c *chk.C) { + cli := getFileClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + share := cli.GetShareReference(shareName(c)) - // Case munging + c.Assert(share.Create(nil), chk.IsNil) + defer share.Delete(nil) mPutUpper := map[string]string{ - "Foo": "different bar", - "bar_BAZ": "different waz qux", + "Lol": "different rofl", + "rofl_BAZ": "different waz qux", } mExpectLower := map[string]string{ - "foo": "different bar", - "bar_baz": "different waz qux", + "lol": "different rofl", + "rofl_baz": "different waz qux", } - share2.Metadata = mPutUpper - c.Assert(share2.SetMetadata(), chk.IsNil) + share.Metadata = mPutUpper + c.Assert(share.SetMetadata(nil), chk.IsNil) - c.Check(share2.Metadata, chk.DeepEquals, mPutUpper) - c.Assert(share2.FetchAttributes(), chk.IsNil) - c.Check(share2.Metadata, chk.DeepEquals, mExpectLower) + c.Check(share.Metadata, chk.DeepEquals, mPutUpper) + c.Assert(share.FetchAttributes(nil), chk.IsNil) + c.Check(share.Metadata, chk.DeepEquals, mExpectLower) } -func deleteTestShares(cli FileServiceClient) error { - for { - resp, err := cli.ListShares(ListSharesParameters{Prefix: testSharePrefix}) - if err != nil { - return err - } - if len(resp.Shares) == 0 { - break - } - for _, c := range resp.Shares { - share := cli.GetShareReference(c.Name) - err = share.Delete() - if err != nil { - return err - } +func (cli *FileServiceClient) deleteAllShares() { + resp, _ := cli.ListShares(ListSharesParameters{}) + if resp != nil && len(resp.Shares) > 0 { + for _, sh := range resp.Shares { + share := cli.GetShareReference(sh.Name) + share.Delete(nil) } } - return nil +} + +func shareName(c *chk.C, extras ...string) string { + return nameGenerator(63, "share-", alphanum, c, extras) } diff --git a/storage/storageservice.go b/storage/storageservice.go index 817560b782bf..88700fbc93e6 100644 --- a/storage/storageservice.go +++ b/storage/storageservice.go @@ -1,9 +1,9 @@ package storage import ( - "fmt" "net/http" "net/url" + "strconv" ) // ServiceProperties represents the storage account service properties @@ -106,13 +106,12 @@ func (c Client) setServiceProperties(props ServiceProperties, service string, au } headers := c.getStandardHeaders() - headers["Content-Length"] = fmt.Sprintf("%v", length) + headers["Content-Length"] = strconv.Itoa(length) resp, err := c.exec(http.MethodPut, uri, headers, body, auth) if err != nil { return err } - defer readAndCloseBody(resp.body) - + readAndCloseBody(resp.body) return checkRespCode(resp.statusCode, []int{http.StatusAccepted}) } diff --git a/storage/storageservice_test.go b/storage/storageservice_test.go index 138194ec8c28..713aeb8a2792 100644 --- a/storage/storageservice_test.go +++ b/storage/storageservice_test.go @@ -10,6 +10,9 @@ var _ = chk.Suite(&StorageSuite{}) func (s *StorageSuite) TestGetServiceProperties(c *chk.C) { cli := getTableClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + sp, err := cli.GetServiceProperties() c.Assert(err, chk.IsNil) c.Assert(sp, chk.NotNil) @@ -17,6 +20,7 @@ func (s *StorageSuite) TestGetServiceProperties(c *chk.C) { func (s *StorageSuite) TestSetServiceProperties(c *chk.C) { cli := getTableClient(c) + rec := cli.client.appendRecorder(c) t := true num := 7 @@ -61,6 +65,8 @@ func (s *StorageSuite) TestSetServiceProperties(c *chk.C) { c.Assert(spOutput, chk.NotNil) c.Assert(*spOutput, chk.DeepEquals, spInput) + rec.Stop() + // Back to defaults defaultRP := RetentionPolicy{ Enabled: false, @@ -75,11 +81,5 @@ func (s *StorageSuite) TestSetServiceProperties(c *chk.C) { spInput.Logging.RetentionPolicy = &defaultRP spInput.Cors = &Cors{nil} - err = cli.SetServiceProperties(spInput) - c.Assert(err, chk.IsNil) - - spOutput, err = cli.GetServiceProperties() - c.Assert(err, chk.IsNil) - c.Assert(spOutput, chk.NotNil) - c.Assert(*spOutput, chk.DeepEquals, spInput) + cli.SetServiceProperties(spInput) } diff --git a/storage/table.go b/storage/table.go index 4123746e501d..67fa3a343c02 100644 --- a/storage/table.go +++ b/storage/table.go @@ -9,20 +9,19 @@ import ( "net/http" "net/url" "strconv" + "strings" "time" ) -// AzureTable is the typedef of the Azure Table name -type AzureTable string - const ( - tablesURIPath = "/Tables" + tablesURIPath = "/Tables" + nextTableQueryParameter = "NextTableName" + headerNextPartitionKey = "x-ms-continuation-NextPartitionKey" + headerNextRowKey = "x-ms-continuation-NextRowKey" + nextPartitionKeyQueryParameter = "NextPartitionKey" + nextRowKeyQueryParameter = "NextRowKey" ) -type createTableRequest struct { - TableName string `json:"TableName"` -} - // TableAccessPolicy are used for SETTING table policies type TableAccessPolicy struct { ID string @@ -34,101 +33,142 @@ type TableAccessPolicy struct { CanDelete bool } -func pathForTable(table AzureTable) string { return fmt.Sprintf("%s", table) } +// Table represents an Azure table. +type Table struct { + tsc *TableServiceClient + Name string `json:"TableName"` + OdataEditLink string `json:"odata.editLink"` + OdataID string `json:"odata.id"` + OdataMetadata string `json:"odata.metadata"` + OdataType string `json:"odata.type"` +} -func (c *TableServiceClient) getStandardHeaders() map[string]string { - return map[string]string{ - "x-ms-version": "2015-02-21", - "x-ms-date": currentTimeRfc1123Formatted(), - "Accept": "application/json;odata=nometadata", - "Accept-Charset": "UTF-8", - "Content-Type": "application/json", - userAgentHeader: c.client.userAgent, - } +// EntityQueryResult contains the response from +// ExecuteQuery and ExecuteQueryNextResults functions. +type EntityQueryResult struct { + OdataMetadata string `json:"odata.metadata"` + Entities []Entity `json:"value"` + QueryNextLink + table *Table } -// QueryTables returns the tables created in the -// *TableServiceClient storage account. -func (c *TableServiceClient) QueryTables() ([]AzureTable, error) { - uri := c.client.getEndpoint(tableServiceName, tablesURIPath, url.Values{}) +type continuationToken struct { + NextPartitionKey string + NextRowKey string +} - headers := c.getStandardHeaders() - headers["Content-Length"] = "0" +func (t *Table) buildPath() string { + return fmt.Sprintf("/%s", t.Name) +} - resp, err := c.client.execInternalJSON(http.MethodGet, uri, headers, nil, c.auth) - if err != nil { - return nil, err - } - defer resp.body.Close() +func (t *Table) buildSpecificPath() string { + return fmt.Sprintf("%s('%s')", tablesURIPath, t.Name) +} - if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { - ioutil.ReadAll(resp.body) - return nil, err +// Get gets the referenced table. +// See: https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/querying-tables-and-entities +func (t *Table) Get(timeout uint, ml MetadataLevel) error { + if ml == EmptyPayload { + return errEmptyPayload } - buf := new(bytes.Buffer) - if _, err := buf.ReadFrom(resp.body); err != nil { - return nil, err + query := url.Values{ + "timeout": {strconv.FormatUint(uint64(timeout), 10)}, } + headers := t.tsc.client.getStandardHeaders() + headers[headerAccept] = string(ml) - var respArray queryTablesResponse - if err := json.Unmarshal(buf.Bytes(), &respArray); err != nil { - return nil, err + uri := t.tsc.client.getEndpoint(tableServiceName, t.buildSpecificPath(), query) + resp, err := t.tsc.client.exec(http.MethodGet, uri, headers, nil, t.tsc.auth) + if err != nil { + return err } + defer readAndCloseBody(resp.body) - s := make([]AzureTable, len(respArray.TableName)) - for i, elem := range respArray.TableName { - s[i] = AzureTable(elem.TableName) + if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + return err } - return s, nil + respBody, err := ioutil.ReadAll(resp.body) + if err != nil { + return err + } + err = json.Unmarshal(respBody, t) + if err != nil { + return err + } + return nil } -// CreateTable creates the table given the specific -// name. This function fails if the name is not compliant +// Create creates the referenced table. +// This function fails if the name is not compliant // with the specification or the tables already exists. -func (c *TableServiceClient) CreateTable(table AzureTable) error { - uri := c.client.getEndpoint(tableServiceName, tablesURIPath, url.Values{}) - - headers := c.getStandardHeaders() - - req := createTableRequest{TableName: string(table)} +// ml determines the level of detail of metadata in the operation response, +// or no data at all. +// See https://docs.microsoft.com/rest/api/storageservices/fileservices/create-table +func (t *Table) Create(timeout uint, ml MetadataLevel, options *TableOptions) error { + uri := t.tsc.client.getEndpoint(tableServiceName, tablesURIPath, url.Values{ + "timeout": {strconv.FormatUint(uint64(timeout), 10)}, + }) + + type createTableRequest struct { + TableName string `json:"TableName"` + } + req := createTableRequest{TableName: t.Name} buf := new(bytes.Buffer) - if err := json.NewEncoder(buf).Encode(req); err != nil { return err } - headers["Content-Length"] = fmt.Sprintf("%d", buf.Len()) - - resp, err := c.client.execInternalJSON(http.MethodPost, uri, headers, buf, c.auth) + headers := t.tsc.client.getStandardHeaders() + headers = addReturnContentHeaders(headers, ml) + headers = addBodyRelatedHeaders(headers, buf.Len()) + headers = options.addToHeaders(headers) + resp, err := t.tsc.client.exec(http.MethodPost, uri, headers, buf, t.tsc.auth) if err != nil { return err } defer readAndCloseBody(resp.body) - if err := checkRespCode(resp.statusCode, []int{http.StatusCreated}); err != nil { - return err + if ml == EmptyPayload { + if err := checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil { + return err + } + } else { + if err := checkRespCode(resp.statusCode, []int{http.StatusCreated}); err != nil { + return err + } + } + + if ml != EmptyPayload { + data, err := ioutil.ReadAll(resp.body) + if err != nil { + return err + } + err = json.Unmarshal(data, t) + if err != nil { + return err + } } return nil } -// DeleteTable deletes the table given the specific -// name. This function fails if the table is not present. -// Be advised: DeleteTable deletes all the entries -// that may be present. -func (c *TableServiceClient) DeleteTable(table AzureTable) error { - uri := c.client.getEndpoint(tableServiceName, tablesURIPath, url.Values{}) - uri += fmt.Sprintf("('%s')", string(table)) - - headers := c.getStandardHeaders() - - headers["Content-Length"] = "0" +// Delete deletes the referenced table. +// This function fails if the table is not present. +// Be advised: Delete deletes all the entries that may be present. +// See https://docs.microsoft.com/rest/api/storageservices/fileservices/delete-table +func (t *Table) Delete(timeout uint, options *TableOptions) error { + uri := t.tsc.client.getEndpoint(tableServiceName, t.buildSpecificPath(), url.Values{ + "timeout": {strconv.Itoa(int(timeout))}, + }) - resp, err := c.client.execInternalJSON(http.MethodDelete, uri, headers, nil, c.auth) + headers := t.tsc.client.getStandardHeaders() + headers = addReturnContentHeaders(headers, EmptyPayload) + headers = options.addToHeaders(headers) + resp, err := t.tsc.client.exec(http.MethodDelete, uri, headers, nil, t.tsc.auth) if err != nil { return err } @@ -141,24 +181,81 @@ func (c *TableServiceClient) DeleteTable(table AzureTable) error { return nil } -// SetTablePermissions sets up table ACL permissions as per REST details https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Set-Table-ACL -func (c *TableServiceClient) SetTablePermissions(table AzureTable, policies []TableAccessPolicy, timeout uint) (err error) { - params := url.Values{"comp": {"acl"}} +// QueryOptions includes options for a query entities operation. +// Top, filter and select are OData query options. +type QueryOptions struct { + Top uint + Filter string + Select []string + RequestID string +} + +func (options *QueryOptions) getParameters() (url.Values, map[string]string) { + query := url.Values{} + headers := map[string]string{} + if options != nil { + if options.Top > 0 { + query.Add(OdataTop, strconv.FormatUint(uint64(options.Top), 10)) + } + if options.Filter != "" { + query.Add(OdataFilter, options.Filter) + } + if len(options.Select) > 0 { + query.Add(OdataSelect, strings.Join(options.Select, ",")) + } + headers = addToHeaders(headers, "x-ms-client-request-id", options.RequestID) + } + return query, headers +} + +// QueryEntities returns the entities in the table. +// You can use query options defined by the OData Protocol specification. +// +// See: https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/query-entities +func (t *Table) QueryEntities(timeout uint, ml MetadataLevel, options *QueryOptions) (*EntityQueryResult, error) { + if ml == EmptyPayload { + return nil, errEmptyPayload + } + query, headers := options.getParameters() + query = addTimeout(query, timeout) + uri := t.tsc.client.getEndpoint(tableServiceName, t.buildPath(), query) + return t.queryEntities(uri, headers, ml) +} + +// NextResults returns the next page of results +// from a QueryEntities or NextResults operation. +// +// See: https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/query-entities +// See https://docs.microsoft.com/rest/api/storageservices/fileservices/query-timeout-and-pagination +func (eqr *EntityQueryResult) NextResults(options *TableOptions) (*EntityQueryResult, error) { + if eqr == nil { + return nil, errNilPreviousResult + } + if eqr.NextLink == nil { + return nil, errNilNextLink + } + headers := options.addToHeaders(map[string]string{}) + return eqr.table.queryEntities(*eqr.NextLink, headers, eqr.ml) +} - if timeout > 0 { - params.Add("timeout", fmt.Sprint(timeout)) +// SetPermissions sets up table ACL permissions +// See https://docs.microsoft.com/rest/api/storageservices/fileservices/Set-Table-ACL +func (t *Table) SetPermissions(tap []TableAccessPolicy, timeout uint, options *TableOptions) error { + params := url.Values{"comp": {"acl"}, + "timeout": {strconv.Itoa(int(timeout))}, } - uri := c.client.getEndpoint(tableServiceName, string(table), params) - headers := c.client.getStandardHeaders() + uri := t.tsc.client.getEndpoint(tableServiceName, t.Name, params) + headers := t.tsc.client.getStandardHeaders() + headers = options.addToHeaders(headers) - body, length, err := generateTableACLPayload(policies) + body, length, err := generateTableACLPayload(tap) if err != nil { return err } - headers["Content-Length"] = fmt.Sprintf("%v", length) + headers["Content-Length"] = strconv.Itoa(length) - resp, err := c.client.execInternalJSON(http.MethodPut, uri, headers, body, c.auth) + resp, err := t.tsc.client.exec(http.MethodPut, uri, headers, body, t.tsc.auth) if err != nil { return err } @@ -182,24 +279,24 @@ func generateTableACLPayload(policies []TableAccessPolicy) (io.Reader, int, erro return xmlMarshal(sil) } -// GetTablePermissions gets the table ACL permissions, as per REST details https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-table-acl -func (c *TableServiceClient) GetTablePermissions(table AzureTable, timeout int) (permissionResponse []TableAccessPolicy, err error) { - params := url.Values{"comp": {"acl"}} - - if timeout > 0 { - params.Add("timeout", strconv.Itoa(timeout)) +// GetPermissions gets the table ACL permissions +// See https://docs.microsoft.com/rest/api/storageservices/fileservices/get-table-acl +func (t *Table) GetPermissions(timeout int, options *TableOptions) ([]TableAccessPolicy, error) { + params := url.Values{"comp": {"acl"}, + "timeout": {strconv.Itoa(int(timeout))}, } - uri := c.client.getEndpoint(tableServiceName, string(table), params) - headers := c.client.getStandardHeaders() - resp, err := c.client.execInternalJSON(http.MethodGet, uri, headers, nil, c.auth) + uri := t.tsc.client.getEndpoint(tableServiceName, t.Name, params) + headers := t.tsc.client.getStandardHeaders() + headers = options.addToHeaders(headers) + + resp, err := t.tsc.client.exec(http.MethodGet, uri, headers, nil, t.tsc.auth) if err != nil { return nil, err } defer resp.body.Close() if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { - ioutil.ReadAll(resp.body) return nil, err } @@ -208,12 +305,73 @@ func (c *TableServiceClient) GetTablePermissions(table AzureTable, timeout int) if err != nil { return nil, err } - out := updateTableAccessPolicy(ap) - return out, nil + return updateTableAccessPolicy(ap), nil +} + +func (t *Table) queryEntities(uri string, headers map[string]string, ml MetadataLevel) (*EntityQueryResult, error) { + headers = mergeHeaders(headers, t.tsc.client.getStandardHeaders()) + if ml != EmptyPayload { + headers[headerAccept] = string(ml) + } + + resp, err := t.tsc.client.exec(http.MethodGet, uri, headers, nil, t.tsc.auth) + if err != nil { + return nil, err + } + defer resp.body.Close() + + if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + return nil, err + } + + data, err := ioutil.ReadAll(resp.body) + if err != nil { + return nil, err + } + var entities EntityQueryResult + err = json.Unmarshal(data, &entities) + if err != nil { + return nil, err + } + + for i := range entities.Entities { + entities.Entities[i].Table = t + } + entities.table = t + + contToken := extractContinuationTokenFromHeaders(resp.headers) + if contToken == nil { + entities.NextLink = nil + } else { + originalURI, err := url.Parse(uri) + if err != nil { + return nil, err + } + v := originalURI.Query() + v.Set(nextPartitionKeyQueryParameter, contToken.NextPartitionKey) + v.Set(nextRowKeyQueryParameter, contToken.NextRowKey) + newURI := t.tsc.client.getEndpoint(tableServiceName, t.buildPath(), v) + entities.NextLink = &newURI + entities.ml = ml + } + + return &entities, nil +} + +func extractContinuationTokenFromHeaders(h http.Header) *continuationToken { + ct := continuationToken{ + NextPartitionKey: h.Get(headerNextPartitionKey), + NextRowKey: h.Get(headerNextRowKey), + } + + if ct.NextPartitionKey != "" && ct.NextRowKey != "" { + return &ct + } + return nil } func updateTableAccessPolicy(ap AccessPolicy) []TableAccessPolicy { - out := []TableAccessPolicy{} + taps := []TableAccessPolicy{} for _, policy := range ap.SignedIdentifiersList.SignedIdentifiers { tap := TableAccessPolicy{ ID: policy.ID, @@ -225,9 +383,9 @@ func updateTableAccessPolicy(ap AccessPolicy) []TableAccessPolicy { tap.CanUpdate = updatePermissions(policy.AccessPolicy.Permission, "u") tap.CanDelete = updatePermissions(policy.AccessPolicy.Permission, "d") - out = append(out, tap) + taps = append(taps, tap) } - return out + return taps } func generateTablePermissions(tap *TableAccessPolicy) (permissions string) { diff --git a/storage/table_batch.go b/storage/table_batch.go new file mode 100644 index 000000000000..d875db04ae81 --- /dev/null +++ b/storage/table_batch.go @@ -0,0 +1,302 @@ +package storage + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io" + "mime/multipart" + "net/http" + "net/textproto" + "sort" + "strings" + + "github.com/satori/uuid" +) + +// Operation type. Insert, Delete, Replace etc. +type Operation int + +// consts for batch operations. +const ( + InsertOp = Operation(1) + DeleteOp = Operation(2) + ReplaceOp = Operation(3) + MergeOp = Operation(4) + InsertOrReplaceOp = Operation(5) + InsertOrMergeOp = Operation(6) +) + +// BatchEntity used for tracking Entities to operate on and +// whether operations (replace/merge etc) should be forced. +// Wrapper for regular Entity with additional data specific for the entity. +type BatchEntity struct { + *Entity + Force bool + Op Operation +} + +// TableBatch stores all the entities that will be operated on during a batch process. +// Entities can be inserted, replaced or deleted. +type TableBatch struct { + BatchEntitySlice []BatchEntity + + // reference to table we're operating on. + Table *Table +} + +// defaultChangesetHeaders for changeSets +var defaultChangesetHeaders = map[string]string{ + "Accept": "application/json;odata=minimalmetadata", + "Content-Type": "application/json", + "Prefer": "return-no-content", +} + +// NewBatch return new TableBatch for populating. +func (t *Table) NewBatch() TableBatch { + return TableBatch{ + Table: t, + } +} + +// InsertEntity adds an entity in preparation for a batch insert. +func (t *TableBatch) InsertEntity(entity *Entity) { + be := BatchEntity{Entity: entity, Force: false, Op: InsertOp} + t.BatchEntitySlice = append(t.BatchEntitySlice, be) +} + +// InsertOrReplaceEntity adds an entity in preparation for a batch insert or replace. +func (t *TableBatch) InsertOrReplaceEntity(entity *Entity, force bool) { + be := BatchEntity{Entity: entity, Force: false, Op: InsertOrReplaceOp} + t.BatchEntitySlice = append(t.BatchEntitySlice, be) +} + +// InsertOrReplaceEntityByForce adds an entity in preparation for a batch insert or replace. Forces regardless of ETag +func (t *TableBatch) InsertOrReplaceEntityByForce(entity *Entity) { + t.InsertOrReplaceEntity(entity, true) +} + +// InsertOrMergeEntity adds an entity in preparation for a batch insert or merge. +func (t *TableBatch) InsertOrMergeEntity(entity *Entity, force bool) { + be := BatchEntity{Entity: entity, Force: false, Op: InsertOrMergeOp} + t.BatchEntitySlice = append(t.BatchEntitySlice, be) +} + +// InsertOrMergeEntityByForce adds an entity in preparation for a batch insert or merge. Forces regardless of ETag +func (t *TableBatch) InsertOrMergeEntityByForce(entity *Entity) { + t.InsertOrMergeEntity(entity, true) +} + +// ReplaceEntity adds an entity in preparation for a batch replace. +func (t *TableBatch) ReplaceEntity(entity *Entity) { + be := BatchEntity{Entity: entity, Force: false, Op: ReplaceOp} + t.BatchEntitySlice = append(t.BatchEntitySlice, be) +} + +// DeleteEntity adds an entity in preparation for a batch delete +func (t *TableBatch) DeleteEntity(entity *Entity, force bool) { + be := BatchEntity{Entity: entity, Force: false, Op: DeleteOp} + t.BatchEntitySlice = append(t.BatchEntitySlice, be) +} + +// DeleteEntityByForce adds an entity in preparation for a batch delete. Forces regardless of ETag +func (t *TableBatch) DeleteEntityByForce(entity *Entity, force bool) { + t.DeleteEntity(entity, true) +} + +// MergeEntity adds an entity in preparation for a batch merge +func (t *TableBatch) MergeEntity(entity *Entity) { + be := BatchEntity{Entity: entity, Force: false, Op: MergeOp} + t.BatchEntitySlice = append(t.BatchEntitySlice, be) +} + +// ExecuteBatch executes many table operations in one request to Azure. +// The operations can be combinations of Insert, Delete, Replace and Merge +// Creates the inner changeset body (various operations, Insert, Delete etc) then creates the outer request packet that encompasses +// the changesets. +// As per document https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/performing-entity-group-transactions +func (t *TableBatch) ExecuteBatch() error { + changesetBoundary := fmt.Sprintf("changeset_%s", uuid.NewV1()) + uri := t.Table.tsc.client.getEndpoint(tableServiceName, "$batch", nil) + changesetBody, err := t.generateChangesetBody(changesetBoundary) + if err != nil { + return err + } + + boundary := fmt.Sprintf("batch_%s", uuid.NewV1()) + body, err := generateBody(changesetBody, changesetBoundary, boundary) + if err != nil { + return err + } + + headers := t.Table.tsc.client.getStandardHeaders() + headers[headerContentType] = fmt.Sprintf("multipart/mixed; boundary=%s", boundary) + + resp, err := t.Table.tsc.client.execBatchOperationJSON(http.MethodPost, uri, headers, bytes.NewReader(body.Bytes()), t.Table.tsc.auth) + if err != nil { + return err + } + defer resp.body.Close() + + if err = checkRespCode(resp.statusCode, []int{http.StatusAccepted}); err != nil { + + // check which batch failed. + operationFailedMessage := t.getFailedOperation(resp.odata.Err.Message.Value) + requestID, date, version := getDebugHeaders(resp.headers) + return AzureStorageServiceError{ + StatusCode: resp.statusCode, + Code: resp.odata.Err.Code, + RequestID: requestID, + Date: date, + APIVersion: version, + Message: operationFailedMessage, + } + } + + return nil +} + +// getFailedOperation parses the original Azure error string and determines which operation failed +// and generates appropriate message. +func (t *TableBatch) getFailedOperation(errorMessage string) string { + // errorMessage consists of "number:string" we just need the number. + sp := strings.Split(errorMessage, ":") + if len(sp) > 1 { + msg := fmt.Sprintf("Element %s in the batch returned an unexpected response code.\n%s", sp[0], errorMessage) + return msg + } + + // cant parse the message, just return the original message to client + return errorMessage +} + +// generateBody generates the complete body for the batch request. +func generateBody(changeSetBody *bytes.Buffer, changesetBoundary string, boundary string) (*bytes.Buffer, error) { + + body := new(bytes.Buffer) + writer := multipart.NewWriter(body) + writer.SetBoundary(boundary) + h := make(textproto.MIMEHeader) + h.Set(headerContentType, fmt.Sprintf("multipart/mixed; boundary=%s\r\n", changesetBoundary)) + batchWriter, err := writer.CreatePart(h) + if err != nil { + return nil, err + } + batchWriter.Write(changeSetBody.Bytes()) + writer.Close() + return body, nil +} + +// generateChangesetBody generates the individual changesets for the various operations within the batch request. +// There is a changeset for Insert, Delete, Merge etc. +func (t *TableBatch) generateChangesetBody(changesetBoundary string) (*bytes.Buffer, error) { + + body := new(bytes.Buffer) + writer := multipart.NewWriter(body) + writer.SetBoundary(changesetBoundary) + + for _, be := range t.BatchEntitySlice { + t.generateEntitySubset(&be, writer) + } + + writer.Close() + return body, nil +} + +// generateVerb generates the HTTP request VERB required for each changeset. +func generateVerb(op Operation) (string, error) { + switch op { + case InsertOp: + return http.MethodPost, nil + case DeleteOp: + return http.MethodDelete, nil + case ReplaceOp, InsertOrReplaceOp: + return http.MethodPut, nil + case MergeOp, InsertOrMergeOp: + return "MERGE", nil + default: + return "", errors.New("Unable to detect operation") + } +} + +// generateQueryPath generates the query path for within the changesets +// For inserts it will just be a table query path (table name) +// but for other operations (modifying an existing entity) then +// the partition/row keys need to be generated. +func (t *TableBatch) generateQueryPath(op Operation, entity *Entity) string { + if op == InsertOp { + return entity.Table.buildPath() + } + return entity.buildPath() +} + +// generateGenericOperationHeaders generates common headers for a given operation. +func generateGenericOperationHeaders(be *BatchEntity) map[string]string { + retval := map[string]string{} + + for k, v := range defaultChangesetHeaders { + retval[k] = v + } + + if be.Op == DeleteOp || be.Op == ReplaceOp || be.Op == MergeOp { + if be.Force || be.Entity.OdataEtag == "" { + retval["If-Match"] = "*" + } else { + retval["If-Match"] = be.Entity.OdataEtag + } + } + + return retval +} + +// generateEntitySubset generates body payload for particular batch entity +func (t *TableBatch) generateEntitySubset(batchEntity *BatchEntity, writer *multipart.Writer) error { + + h := make(textproto.MIMEHeader) + h.Set(headerContentType, "application/http") + h.Set(headerContentTransferEncoding, "binary") + + verb, err := generateVerb(batchEntity.Op) + if err != nil { + return err + } + + genericOpHeadersMap := generateGenericOperationHeaders(batchEntity) + queryPath := t.generateQueryPath(batchEntity.Op, batchEntity.Entity) + uri := t.Table.tsc.client.getEndpoint(tableServiceName, queryPath, nil) + + operationWriter, err := writer.CreatePart(h) + if err != nil { + return err + } + + urlAndVerb := fmt.Sprintf("%s %s HTTP/1.1\r\n", verb, uri) + operationWriter.Write([]byte(urlAndVerb)) + writeHeaders(genericOpHeadersMap, &operationWriter) + operationWriter.Write([]byte("\r\n")) // additional \r\n is needed per changeset separating the "headers" and the body. + + // delete operation doesn't need a body. + if batchEntity.Op != DeleteOp { + //var e Entity = batchEntity.Entity + body, err := json.Marshal(batchEntity.Entity) + if err != nil { + return err + } + operationWriter.Write(body) + } + + return nil +} + +func writeHeaders(h map[string]string, writer *io.Writer) { + // This way it is guaranteed the headers will be written in a sorted order + var keys []string + for k := range h { + keys = append(keys, k) + } + sort.Strings(keys) + for _, k := range keys { + (*writer).Write([]byte(fmt.Sprintf("%s: %s\r\n", k, h[k]))) + } +} diff --git a/storage/table_batch_test.go b/storage/table_batch_test.go new file mode 100644 index 000000000000..0e57f422565e --- /dev/null +++ b/storage/table_batch_test.go @@ -0,0 +1,216 @@ +package storage + +import ( + "time" + + "github.com/satori/uuid" + chk "gopkg.in/check.v1" +) + +type TableBatchSuite struct{} + +var _ = chk.Suite(&TableBatchSuite{}) + +func (s *TableBatchSuite) Test_BatchInsertMultipleEntities(c *chk.C) { + cli := getBasicClient(c).GetTableService() + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + table := cli.GetTableReference(tableName(c, "me")) + err := table.Create(30, EmptyPayload, nil) + c.Assert(err, chk.IsNil) + defer table.Delete(30, nil) + + entity := table.GetEntityReference("mypartitionkey", "myrowkey") + props := map[string]interface{}{ + "AmountDue": 200.23, + "CustomerCode": uuid.FromStringOrNil("c9da6455-213d-42c9-9a79-3e9149a57833"), + "CustomerSince": time.Date(1992, time.December, 20, 21, 55, 0, 0, time.UTC), + "IsActive": true, + "NumberOfOrders": int64(255), + } + entity.Properties = props + + entity2 := table.GetEntityReference("mypartitionkey", "myrowkey2") + props2 := map[string]interface{}{ + "AmountDue": 111.23, + "CustomerCode": uuid.FromStringOrNil("c9da6455-213d-42c9-9a79-3e9149a57833"), + "CustomerSince": time.Date(1992, time.December, 20, 21, 55, 0, 0, time.UTC), + "IsActive": true, + "NumberOfOrders": int64(255), + } + entity2.Properties = props2 + + batch := table.NewBatch() + batch.InsertOrReplaceEntity(&entity, false) + batch.InsertOrReplaceEntity(&entity2, false) + + err = batch.ExecuteBatch() + c.Assert(err, chk.IsNil) + + options := QueryOptions{ + Top: 2, + } + + results, err := table.QueryEntities(30, FullMetadata, &options) + c.Assert(err, chk.IsNil) + c.Assert(results.Entities, chk.HasLen, 2) +} + +func (s *TableBatchSuite) Test_BatchInsertSameEntryMultipleTimes(c *chk.C) { + cli := getBasicClient(c).GetTableService() + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + table := cli.GetTableReference(tableName(c)) + err := table.Create(30, EmptyPayload, nil) + c.Assert(err, chk.IsNil) + defer table.Delete(30, nil) + + entity := table.GetEntityReference("mypartitionkey", "myrowkey") + props := map[string]interface{}{ + "AmountDue": 200.23, + "CustomerCode": uuid.FromStringOrNil("c9da6455-213d-42c9-9a79-3e9149a57833"), + "CustomerSince": time.Date(1992, time.December, 20, 21, 55, 0, 0, time.UTC), + "IsActive": true, + "NumberOfOrders": int64(255), + } + entity.Properties = props + + batch := table.NewBatch() + batch.InsertOrReplaceEntity(&entity, false) + batch.InsertOrReplaceEntity(&entity, false) + + err = batch.ExecuteBatch() + c.Assert(err, chk.NotNil) + v, ok := err.(AzureStorageServiceError) + if ok { + c.Assert(v.Code, chk.Equals, "InvalidDuplicateRow") + } +} + +func (s *TableBatchSuite) Test_BatchInsertDeleteSameEntity(c *chk.C) { + cli := getBasicClient(c).GetTableService() + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + table := cli.GetTableReference(tableName(c)) + err := table.Create(30, EmptyPayload, nil) + c.Assert(err, chk.IsNil) + defer table.Delete(30, nil) + + entity := table.GetEntityReference("mypartitionkey", "myrowkey") + props := map[string]interface{}{ + "AmountDue": 200.23, + "CustomerCode": uuid.FromStringOrNil("c9da6455-213d-42c9-9a79-3e9149a57833"), + "CustomerSince": time.Date(1992, time.December, 20, 21, 55, 0, 0, time.UTC), + "IsActive": true, + "NumberOfOrders": int64(255), + } + entity.Properties = props + + batch := table.NewBatch() + batch.InsertOrReplaceEntity(&entity, false) + batch.DeleteEntity(&entity, true) + + err = batch.ExecuteBatch() + c.Assert(err, chk.NotNil) + + v, ok := err.(AzureStorageServiceError) + if ok { + c.Assert(v.Code, chk.Equals, "InvalidDuplicateRow") + } +} + +func (s *TableBatchSuite) Test_BatchInsertThenDeleteDifferentBatches(c *chk.C) { + cli := getBasicClient(c).GetTableService() + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + table := cli.GetTableReference(tableName(c)) + err := table.Create(30, EmptyPayload, nil) + c.Assert(err, chk.IsNil) + defer table.Delete(30, nil) + + entity := table.GetEntityReference("mypartitionkey", "myrowkey") + props := map[string]interface{}{ + "AmountDue": 200.23, + "CustomerCode": uuid.FromStringOrNil("c9da6455-213d-42c9-9a79-3e9149a57833"), + "CustomerSince": time.Date(1992, time.December, 20, 21, 55, 0, 0, time.UTC), + "IsActive": true, + "NumberOfOrders": int64(255), + } + entity.Properties = props + + batch := table.NewBatch() + batch.InsertOrReplaceEntity(&entity, false) + err = batch.ExecuteBatch() + c.Assert(err, chk.IsNil) + + options := QueryOptions{ + Top: 2, + } + + results, err := table.QueryEntities(30, FullMetadata, &options) + c.Assert(err, chk.IsNil) + c.Assert(results.Entities, chk.HasLen, 1) + + batch = table.NewBatch() + batch.DeleteEntity(&entity, true) + err = batch.ExecuteBatch() + c.Assert(err, chk.IsNil) + + // Timeout set to 15 for this test to work propwrly with the recordings + results, err = table.QueryEntities(15, FullMetadata, &options) + c.Assert(err, chk.IsNil) + c.Assert(results.Entities, chk.HasLen, 0) +} + +func (s *TableBatchSuite) Test_BatchInsertThenMergeDifferentBatches(c *chk.C) { + cli := getBasicClient(c).GetTableService() + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + table := cli.GetTableReference(tableName(c)) + err := table.Create(30, EmptyPayload, nil) + c.Assert(err, chk.IsNil) + defer table.Delete(30, nil) + + entity := table.GetEntityReference("mypartitionkey", "myrowkey") + props := map[string]interface{}{ + "AmountDue": 200.23, + "CustomerCode": uuid.FromStringOrNil("c9da6455-213d-42c9-9a79-3e9149a57833"), + "CustomerSince": time.Date(1992, time.December, 20, 21, 55, 0, 0, time.UTC), + "IsActive": true, + "NumberOfOrders": int64(255), + } + entity.Properties = props + + batch := table.NewBatch() + batch.InsertOrReplaceEntity(&entity, false) + err = batch.ExecuteBatch() + c.Assert(err, chk.IsNil) + + entity2 := table.GetEntityReference("mypartitionkey", "myrowkey") + props2 := map[string]interface{}{ + "AmountDue": 200.23, + "CustomerCode": uuid.FromStringOrNil("c9da6455-213d-42c9-9a79-3e9149a57833"), + "CustomerSince": time.Date(1992, time.December, 20, 21, 55, 0, 0, time.UTC), + "DifferentField": 123, + "NumberOfOrders": int64(255), + } + entity2.Properties = props2 + + batch = table.NewBatch() + batch.InsertOrReplaceEntity(&entity2, false) + err = batch.ExecuteBatch() + c.Assert(err, chk.IsNil) + + options := QueryOptions{ + Top: 2, + } + + results, err := table.QueryEntities(30, FullMetadata, &options) + c.Assert(err, chk.IsNil) + c.Assert(results.Entities, chk.HasLen, 1) +} diff --git a/storage/table_entities.go b/storage/table_entities.go deleted file mode 100644 index 1758d9f3eb21..000000000000 --- a/storage/table_entities.go +++ /dev/null @@ -1,345 +0,0 @@ -package storage - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "net/http" - "net/url" - "reflect" -) - -// Annotating as secure for gas scanning -/* #nosec */ -const ( - partitionKeyNode = "PartitionKey" - rowKeyNode = "RowKey" - tag = "table" - tagIgnore = "-" - continuationTokenPartitionKeyHeader = "X-Ms-Continuation-Nextpartitionkey" - continuationTokenRowHeader = "X-Ms-Continuation-Nextrowkey" - maxTopParameter = 1000 -) - -type queryTablesResponse struct { - TableName []struct { - TableName string `json:"TableName"` - } `json:"value"` -} - -const ( - tableOperationTypeInsert = iota - tableOperationTypeUpdate = iota - tableOperationTypeMerge = iota - tableOperationTypeInsertOrReplace = iota - tableOperationTypeInsertOrMerge = iota -) - -type tableOperation int - -// TableEntity interface specifies -// the functions needed to support -// marshaling and unmarshaling into -// Azure Tables. The struct must only contain -// simple types because Azure Tables do not -// support hierarchy. -type TableEntity interface { - PartitionKey() string - RowKey() string - SetPartitionKey(string) error - SetRowKey(string) error -} - -// ContinuationToken is an opaque (ie not useful to inspect) -// struct that Get... methods can return if there are more -// entries to be returned than the ones already -// returned. Just pass it to the same function to continue -// receiving the remaining entries. -type ContinuationToken struct { - NextPartitionKey string - NextRowKey string -} - -type getTableEntriesResponse struct { - Elements []map[string]interface{} `json:"value"` -} - -// QueryTableEntities queries the specified table and returns the unmarshaled -// entities of type retType. -// top parameter limits the returned entries up to top. Maximum top -// allowed by Azure API is 1000. In case there are more than top entries to be -// returned the function will return a non nil *ContinuationToken. You can call the -// same function again passing the received ContinuationToken as previousContToken -// parameter in order to get the following entries. The query parameter -// is the odata query. To retrieve all the entries pass the empty string. -// The function returns a pointer to a TableEntity slice, the *ContinuationToken -// if there are more entries to be returned and an error in case something went -// wrong. -// -// Example: -// entities, cToken, err = tSvc.QueryTableEntities("table", cToken, reflect.TypeOf(entity), 20, "") -func (c *TableServiceClient) QueryTableEntities(tableName AzureTable, previousContToken *ContinuationToken, retType reflect.Type, top int, query string) ([]TableEntity, *ContinuationToken, error) { - if top > maxTopParameter { - return nil, nil, fmt.Errorf("top accepts at maximum %d elements. Requested %d instead", maxTopParameter, top) - } - - uri := c.client.getEndpoint(tableServiceName, pathForTable(tableName), url.Values{}) - uri += fmt.Sprintf("?$top=%d", top) - if query != "" { - uri += fmt.Sprintf("&$filter=%s", url.QueryEscape(query)) - } - - if previousContToken != nil { - uri += fmt.Sprintf("&NextPartitionKey=%s&NextRowKey=%s", previousContToken.NextPartitionKey, previousContToken.NextRowKey) - } - - headers := c.getStandardHeaders() - - headers["Content-Length"] = "0" - - resp, err := c.client.execInternalJSON(http.MethodGet, uri, headers, nil, c.auth) - - if err != nil { - return nil, nil, err - } - - contToken := extractContinuationTokenFromHeaders(resp.headers) - - defer resp.body.Close() - - if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { - return nil, contToken, err - } - - retEntries, err := deserializeEntity(retType, resp.body) - if err != nil { - return nil, contToken, err - } - - return retEntries, contToken, nil -} - -// InsertEntity inserts an entity in the specified table. -// The function fails if there is an entity with the same -// PartitionKey and RowKey in the table. -func (c *TableServiceClient) InsertEntity(table AzureTable, entity TableEntity) error { - if sc, err := c.execTable(table, entity, false, http.MethodPost); err != nil { - return checkRespCode(sc, []int{http.StatusCreated}) - } - - return nil -} - -func (c *TableServiceClient) execTable(table AzureTable, entity TableEntity, specifyKeysInURL bool, method string) (int, error) { - uri := c.client.getEndpoint(tableServiceName, pathForTable(table), url.Values{}) - if specifyKeysInURL { - uri += fmt.Sprintf("(PartitionKey='%s',RowKey='%s')", url.QueryEscape(entity.PartitionKey()), url.QueryEscape(entity.RowKey())) - } - - headers := c.getStandardHeaders() - - var buf bytes.Buffer - - if err := injectPartitionAndRowKeys(entity, &buf); err != nil { - return 0, err - } - - headers["Content-Length"] = fmt.Sprintf("%d", buf.Len()) - - resp, err := c.client.execInternalJSON(method, uri, headers, &buf, c.auth) - - if err != nil { - return 0, err - } - - defer resp.body.Close() - - return resp.statusCode, nil -} - -// UpdateEntity updates the contents of an entity with the -// one passed as parameter. The function fails if there is no entity -// with the same PartitionKey and RowKey in the table. -func (c *TableServiceClient) UpdateEntity(table AzureTable, entity TableEntity) error { - if sc, err := c.execTable(table, entity, true, http.MethodPut); err != nil { - return checkRespCode(sc, []int{http.StatusNoContent}) - } - return nil -} - -// MergeEntity merges the contents of an entity with the -// one passed as parameter. -// The function fails if there is no entity -// with the same PartitionKey and RowKey in the table. -func (c *TableServiceClient) MergeEntity(table AzureTable, entity TableEntity) error { - if sc, err := c.execTable(table, entity, true, "MERGE"); err != nil { - return checkRespCode(sc, []int{http.StatusNoContent}) - } - return nil -} - -// DeleteEntityWithoutCheck deletes the entity matching by -// PartitionKey and RowKey. There is no check on IfMatch -// parameter so the entity is always deleted. -// The function fails if there is no entity -// with the same PartitionKey and RowKey in the table. -func (c *TableServiceClient) DeleteEntityWithoutCheck(table AzureTable, entity TableEntity) error { - return c.DeleteEntity(table, entity, "*") -} - -// DeleteEntity deletes the entity matching by -// PartitionKey, RowKey and ifMatch field. -// The function fails if there is no entity -// with the same PartitionKey and RowKey in the table or -// the ifMatch is different. -func (c *TableServiceClient) DeleteEntity(table AzureTable, entity TableEntity, ifMatch string) error { - uri := c.client.getEndpoint(tableServiceName, pathForTable(table), url.Values{}) - uri += fmt.Sprintf("(PartitionKey='%s',RowKey='%s')", url.QueryEscape(entity.PartitionKey()), url.QueryEscape(entity.RowKey())) - - headers := c.getStandardHeaders() - - headers["Content-Length"] = "0" - headers["If-Match"] = ifMatch - - resp, err := c.client.execInternalJSON(http.MethodDelete, uri, headers, nil, c.auth) - - if err != nil { - return err - } - defer resp.body.Close() - - if err := checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil { - return err - } - - return nil -} - -// InsertOrReplaceEntity inserts an entity in the specified table -// or replaced the existing one. -func (c *TableServiceClient) InsertOrReplaceEntity(table AzureTable, entity TableEntity) error { - if sc, err := c.execTable(table, entity, true, http.MethodPut); err != nil { - return checkRespCode(sc, []int{http.StatusNoContent}) - } - return nil -} - -// InsertOrMergeEntity inserts an entity in the specified table -// or merges the existing one. -func (c *TableServiceClient) InsertOrMergeEntity(table AzureTable, entity TableEntity) error { - if sc, err := c.execTable(table, entity, true, "MERGE"); err != nil { - return checkRespCode(sc, []int{http.StatusNoContent}) - } - return nil -} - -func injectPartitionAndRowKeys(entity TableEntity, buf *bytes.Buffer) error { - if err := json.NewEncoder(buf).Encode(entity); err != nil { - return err - } - - dec := make(map[string]interface{}) - if err := json.NewDecoder(buf).Decode(&dec); err != nil { - return err - } - - // Inject PartitionKey and RowKey - dec[partitionKeyNode] = entity.PartitionKey() - dec[rowKeyNode] = entity.RowKey() - - // Remove tagged fields - // The tag is defined in the const section - // This is useful to avoid storing the PartitionKey and RowKey twice. - numFields := reflect.ValueOf(entity).Elem().NumField() - for i := 0; i < numFields; i++ { - f := reflect.ValueOf(entity).Elem().Type().Field(i) - - if f.Tag.Get(tag) == tagIgnore { - // we must look for its JSON name in the dictionary - // as the user can rename it using a tag - jsonName := f.Name - if f.Tag.Get("json") != "" { - jsonName = f.Tag.Get("json") - } - delete(dec, jsonName) - } - } - - buf.Reset() - - if err := json.NewEncoder(buf).Encode(&dec); err != nil { - return err - } - - return nil -} - -func deserializeEntity(retType reflect.Type, reader io.Reader) ([]TableEntity, error) { - buf := new(bytes.Buffer) - - var ret getTableEntriesResponse - if err := json.NewDecoder(reader).Decode(&ret); err != nil { - return nil, err - } - - tEntries := make([]TableEntity, len(ret.Elements)) - - for i, entry := range ret.Elements { - - buf.Reset() - if err := json.NewEncoder(buf).Encode(entry); err != nil { - return nil, err - } - - dec := make(map[string]interface{}) - if err := json.NewDecoder(buf).Decode(&dec); err != nil { - return nil, err - } - - var pKey, rKey string - // strip pk and rk - for key, val := range dec { - switch key { - case partitionKeyNode: - pKey = val.(string) - case rowKeyNode: - rKey = val.(string) - } - } - - delete(dec, partitionKeyNode) - delete(dec, rowKeyNode) - - buf.Reset() - if err := json.NewEncoder(buf).Encode(dec); err != nil { - return nil, err - } - - // Create a empty retType instance - tEntries[i] = reflect.New(retType.Elem()).Interface().(TableEntity) - // Popolate it with the values - if err := json.NewDecoder(buf).Decode(&tEntries[i]); err != nil { - return nil, err - } - - // Reset PartitionKey and RowKey - if err := tEntries[i].SetPartitionKey(pKey); err != nil { - return nil, err - } - if err := tEntries[i].SetRowKey(rKey); err != nil { - return nil, err - } - } - - return tEntries, nil -} - -func extractContinuationTokenFromHeaders(h http.Header) *ContinuationToken { - ct := ContinuationToken{h.Get(continuationTokenPartitionKeyHeader), h.Get(continuationTokenRowHeader)} - - if ct.NextPartitionKey != "" && ct.NextRowKey != "" { - return &ct - } - return nil -} diff --git a/storage/table_test.go b/storage/table_test.go index b43c08e1fd28..fd17223dbf40 100644 --- a/storage/table_test.go +++ b/storage/table_test.go @@ -1,9 +1,7 @@ package storage import ( - "crypto/rand" - "fmt" - "reflect" + "strconv" "time" chk "gopkg.in/check.v1" @@ -13,241 +11,109 @@ type StorageTableSuite struct{} var _ = chk.Suite(&StorageTableSuite{}) -type TableClient struct{} - func getTableClient(c *chk.C) TableServiceClient { return getBasicClient(c).GetTableService() } -type CustomEntity struct { - Name string `json:"name"` - Surname string `json:"surname"` - Number int - PKey string `json:"pk" table:"-"` - RKey string `json:"rk" table:"-"` -} - -type CustomEntityExtended struct { - *CustomEntity - ExtraField string -} - -func (c *CustomEntity) PartitionKey() string { - return c.PKey -} - -func (c *CustomEntity) RowKey() string { - return c.RKey -} - -func (c *CustomEntity) SetPartitionKey(s string) error { - c.PKey = s - return nil -} - -func (c *CustomEntity) SetRowKey(s string) error { - c.RKey = s - return nil -} - -func (s *StorageTableSuite) Test_CreateAndDeleteTable(c *chk.C) { - cli := getTableClient(c) - - tn := AzureTable(randTable()) - - err := cli.CreateTable(tn) - c.Assert(err, chk.IsNil) - - err = cli.DeleteTable(tn) - c.Assert(err, chk.IsNil) -} - -func (s *StorageTableSuite) Test_InsertEntities(c *chk.C) { - cli := getTableClient(c) - - tn := AzureTable(randTable()) - - err := cli.CreateTable(tn) - c.Assert(err, chk.IsNil) - defer cli.DeleteTable(tn) - - ce := &CustomEntity{Name: "Luke", Surname: "Skywalker", Number: 1543, PKey: "pkey"} - - for i := 0; i < 12; i++ { - ce.SetRowKey(fmt.Sprintf("%d", i)) - - err = cli.InsertEntity(tn, ce) - c.Assert(err, chk.IsNil) +func (cli *TableServiceClient) deleteAllTables() { + if result, _ := cli.QueryTables(MinimalMetadata, nil); result != nil { + for _, t := range result.Tables { + t.Delete(30, nil) + } } } -func (s *StorageTableSuite) Test_InsertOrReplaceEntities(c *chk.C) { +func (s *StorageTableSuite) Test_CreateAndDeleteTable(c *chk.C) { cli := getTableClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() - tn := AzureTable(randTable()) - - err := cli.CreateTable(tn) + table1 := cli.GetTableReference(tableName(c, "1")) + err := table1.Create(30, EmptyPayload, nil) c.Assert(err, chk.IsNil) - defer cli.DeleteTable(tn) - ce := &CustomEntity{Name: "Darth", Surname: "Skywalker", Number: 60, PKey: "pkey", RKey: "5"} - - err = cli.InsertOrReplaceEntity(tn, ce) + // update table metadata + table2 := cli.GetTableReference(tableName(c, "2")) + err = table2.Create(30, FullMetadata, nil) + defer table2.Delete(30, nil) c.Assert(err, chk.IsNil) - cextra := &CustomEntityExtended{&CustomEntity{PKey: "pkey", RKey: "5"}, "extra"} - err = cli.InsertOrReplaceEntity(tn, cextra) - c.Assert(err, chk.IsNil) -} + // Check not empty values + c.Assert(table2.OdataEditLink, chk.Not(chk.Equals), "") + c.Assert(table2.OdataID, chk.Not(chk.Equals), "") + c.Assert(table2.OdataMetadata, chk.Not(chk.Equals), "") + c.Assert(table2.OdataType, chk.Not(chk.Equals), "") -func (s *StorageTableSuite) Test_InsertOrMergeEntities(c *chk.C) { - cli := getTableClient(c) - - tn := AzureTable(randTable()) - - err := cli.CreateTable(tn) - c.Assert(err, chk.IsNil) - defer cli.DeleteTable(tn) - - ce := &CustomEntity{Name: "Darth", Surname: "Skywalker", Number: 60, PKey: "pkey", RKey: "5"} - - err = cli.InsertOrMergeEntity(tn, ce) - c.Assert(err, chk.IsNil) - - cextra := &CustomEntityExtended{&CustomEntity{PKey: "pkey", RKey: "5"}, "extra"} - err = cli.InsertOrReplaceEntity(tn, cextra) + err = table1.Delete(30, nil) c.Assert(err, chk.IsNil) } -func (s *StorageTableSuite) Test_InsertAndGetEntities(c *chk.C) { +func (s *StorageTableSuite) Test_CreateTableWithAllResponsePayloadLevels(c *chk.C) { cli := getTableClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() - tn := AzureTable(randTable()) - - err := cli.CreateTable(tn) - c.Assert(err, chk.IsNil) - defer cli.DeleteTable(tn) - - ce := &CustomEntity{Name: "Darth", Surname: "Skywalker", Number: 60, PKey: "pkey", RKey: "100"} - c.Assert(cli.InsertOrReplaceEntity(tn, ce), chk.IsNil) - - ce.SetRowKey("200") - c.Assert(cli.InsertOrReplaceEntity(tn, ce), chk.IsNil) - - entries, _, err := cli.QueryTableEntities(tn, nil, reflect.TypeOf(ce), 10, "") - c.Assert(err, chk.IsNil) - - c.Assert(len(entries), chk.Equals, 2) - - c.Assert(ce.RowKey(), chk.Equals, entries[1].RowKey()) - - c.Assert(entries[1].(*CustomEntity), chk.DeepEquals, ce) + createAndDeleteTable(cli, EmptyPayload, c, "empty") + createAndDeleteTable(cli, NoMetadata, c, "nm") + createAndDeleteTable(cli, MinimalMetadata, c, "minimal") + createAndDeleteTable(cli, FullMetadata, c, "full") } -func (s *StorageTableSuite) Test_InsertAndQueryEntities(c *chk.C) { +func (s *StorageTableSuite) TestGet(c *chk.C) { cli := getTableClient(c) + rec := cli.client.appendRecorder(c) + defer rec.Stop() - tn := AzureTable(randTable()) - - err := cli.CreateTable(tn) + tn := tableName(c) + table := cli.GetTableReference(tn) + err := table.Create(30, EmptyPayload, nil) c.Assert(err, chk.IsNil) - defer cli.DeleteTable(tn) - - ce := &CustomEntity{Name: "Darth", Surname: "Skywalker", Number: 60, PKey: "pkey", RKey: "100"} - c.Assert(cli.InsertOrReplaceEntity(tn, ce), chk.IsNil) - - ce.SetRowKey("200") - c.Assert(cli.InsertOrReplaceEntity(tn, ce), chk.IsNil) + defer table.Delete(30, nil) - entries, _, err := cli.QueryTableEntities(tn, nil, reflect.TypeOf(ce), 10, "RowKey eq '200'") + err = table.Get(30, FullMetadata) c.Assert(err, chk.IsNil) - - c.Assert(len(entries), chk.Equals, 1) - - c.Assert(ce.RowKey(), chk.Equals, entries[0].RowKey()) + c.Assert(table.Name, chk.Equals, tn) + c.Assert(table.OdataEditLink, chk.Not(chk.Equals), "") + c.Assert(table.OdataID, chk.Not(chk.Equals), "") + c.Assert(table.OdataMetadata, chk.Not(chk.Equals), "") + c.Assert(table.OdataType, chk.Not(chk.Equals), "") } -func (s *StorageTableSuite) Test_InsertAndDeleteEntities(c *chk.C) { - cli := getTableClient(c) - - tn := AzureTable(randTable()) - - err := cli.CreateTable(tn) - c.Assert(err, chk.IsNil) - defer cli.DeleteTable(tn) - - ce := &CustomEntity{Name: "Test", Surname: "Test2", Number: 0, PKey: "pkey", RKey: "r01"} - c.Assert(cli.InsertOrReplaceEntity(tn, ce), chk.IsNil) - - ce.Number = 1 - ce.SetRowKey("r02") - c.Assert(cli.InsertOrReplaceEntity(tn, ce), chk.IsNil) - - entries, _, err := cli.QueryTableEntities(tn, nil, reflect.TypeOf(ce), 10, "Number eq 1") - c.Assert(err, chk.IsNil) - - c.Assert(len(entries), chk.Equals, 1) - - c.Assert(entries[0].(*CustomEntity), chk.DeepEquals, ce) - - c.Assert(cli.DeleteEntityWithoutCheck(tn, entries[0]), chk.IsNil) - - entries, _, err = cli.QueryTableEntities(tn, nil, reflect.TypeOf(ce), 10, "") - c.Assert(err, chk.IsNil) - - // only 1 entry must be present - c.Assert(len(entries), chk.Equals, 1) +func createAndDeleteTable(cli TableServiceClient, ml MetadataLevel, c *chk.C, extra string) { + table := cli.GetTableReference(tableName(c, extra)) + c.Assert(table.Create(30, ml, nil), chk.IsNil) + c.Assert(table.Delete(30, nil), chk.IsNil) } -func (s *StorageTableSuite) Test_ContinuationToken(c *chk.C) { +func (s *StorageTableSuite) TestQueryTablesNextResults(c *chk.C) { cli := getTableClient(c) + cli.deleteAllTables() + rec := cli.client.appendRecorder(c) + defer rec.Stop() - tn := AzureTable(randTable()) - - err := cli.CreateTable(tn) - c.Assert(err, chk.IsNil) - defer cli.DeleteTable(tn) - - var ce *CustomEntity - var ceList [5]*CustomEntity - - for i := 0; i < 5; i++ { - ce = &CustomEntity{Name: "Test", Surname: "Test2", Number: i, PKey: "pkey", RKey: fmt.Sprintf("r%d", i)} - ceList[i] = ce - c.Assert(cli.InsertOrReplaceEntity(tn, ce), chk.IsNil) + for i := 0; i < 3; i++ { + table := cli.GetTableReference(tableName(c, strconv.Itoa(i))) + err := table.Create(30, EmptyPayload, nil) + c.Assert(err, chk.IsNil) + defer table.Delete(30, nil) } - // retrieve using top = 2. Should return 2 entries, 2 entries and finally - // 1 entry - entries, contToken, err := cli.QueryTableEntities(tn, nil, reflect.TypeOf(ce), 2, "") - c.Assert(err, chk.IsNil) - c.Assert(len(entries), chk.Equals, 2) - c.Assert(entries[0].(*CustomEntity), chk.DeepEquals, ceList[0]) - c.Assert(entries[1].(*CustomEntity), chk.DeepEquals, ceList[1]) - c.Assert(contToken, chk.NotNil) - - entries, contToken, err = cli.QueryTableEntities(tn, contToken, reflect.TypeOf(ce), 2, "") + options := QueryTablesOptions{ + Top: 2, + } + result, err := cli.QueryTables(MinimalMetadata, &options) c.Assert(err, chk.IsNil) - c.Assert(len(entries), chk.Equals, 2) - c.Assert(entries[0].(*CustomEntity), chk.DeepEquals, ceList[2]) - c.Assert(entries[1].(*CustomEntity), chk.DeepEquals, ceList[3]) - c.Assert(contToken, chk.NotNil) + c.Assert(result.Tables, chk.HasLen, 2) + c.Assert(result.NextLink, chk.NotNil) - entries, contToken, err = cli.QueryTableEntities(tn, contToken, reflect.TypeOf(ce), 2, "") + result, err = result.NextResults(nil) c.Assert(err, chk.IsNil) - c.Assert(len(entries), chk.Equals, 1) - c.Assert(entries[0].(*CustomEntity), chk.DeepEquals, ceList[4]) - c.Assert(contToken, chk.IsNil) -} + c.Assert(result.Tables, chk.HasLen, 1) + c.Assert(result.NextLink, chk.IsNil) -func randTable() string { - const alphanum = "abcdefghijklmnopqrstuvwxyz" - var bytes = make([]byte, 32) - rand.Read(bytes) - for i, b := range bytes { - bytes[i] = alphanum[b%byte(len(alphanum))] - } - return string(bytes) + result, err = result.NextResults(nil) + c.Assert(result, chk.IsNil) + c.Assert(err, chk.NotNil) } func appendTablePermission(policies []TableAccessPolicy, ID string, @@ -267,66 +133,77 @@ func appendTablePermission(policies []TableAccessPolicy, ID string, return policies } -func (s *StorageTableSuite) TestSetTablePermissionsSuccessfully(c *chk.C) { +func (s *StorageTableSuite) TestSetPermissionsSuccessfully(c *chk.C) { cli := getTableClient(c) - tn := AzureTable(randTable()) - err := cli.CreateTable(tn) - c.Assert(err, chk.IsNil) - defer cli.DeleteTable(tn) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + table := cli.GetTableReference(tableName(c)) + c.Assert(table.Create(30, EmptyPayload, nil), chk.IsNil) + defer table.Delete(30, nil) policies := []TableAccessPolicy{} - policies = appendTablePermission(policies, "GolangRocksOnAzure", true, true, true, true, now, now.Add(10*time.Hour)) + policies = appendTablePermission(policies, "GolangRocksOnAzure", true, true, true, true, fixedTime, fixedTime.Add(10*time.Hour)) - err = cli.SetTablePermissions(tn, policies, 0) + err := table.SetPermissions(policies, 30, nil) c.Assert(err, chk.IsNil) } -func (s *StorageTableSuite) TestSetTablePermissionsUnsuccessfully(c *chk.C) { +func (s *StorageTableSuite) TestSetPermissionsUnsuccessfully(c *chk.C) { cli := getTableClient(c) - tn := AzureTable("nonexistingtable") + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + table := cli.GetTableReference("nonexistingtable") policies := []TableAccessPolicy{} - policies = appendTablePermission(policies, "GolangRocksOnAzure", true, true, true, true, now, now.Add(10*time.Hour)) + policies = appendTablePermission(policies, "GolangRocksOnAzure", true, true, true, true, fixedTime, fixedTime.Add(10*time.Hour)) - err := cli.SetTablePermissions(tn, policies, 0) + err := table.SetPermissions(policies, 30, nil) c.Assert(err, chk.NotNil) } -func (s *StorageTableSuite) TestSetThenGetTablePermissionsSuccessfully(c *chk.C) { +func (s *StorageTableSuite) TestSetThenGetPermissionsSuccessfully(c *chk.C) { cli := getTableClient(c) - tn := AzureTable(randTable()) - err := cli.CreateTable(tn) - c.Assert(err, chk.IsNil) - defer cli.DeleteTable(tn) + rec := cli.client.appendRecorder(c) + defer rec.Stop() + + table := cli.GetTableReference(tableName(c)) + c.Assert(table.Create(30, EmptyPayload, nil), chk.IsNil) + defer table.Delete(30, nil) policies := []TableAccessPolicy{} - policies = appendTablePermission(policies, "GolangRocksOnAzure", true, true, true, true, now, now.Add(10*time.Hour)) - policies = appendTablePermission(policies, "AutoRestIsSuperCool", true, true, false, true, now.Add(20*time.Hour), now.Add(30*time.Hour)) - err = cli.SetTablePermissions(tn, policies, 0) + policies = appendTablePermission(policies, "GolangRocksOnAzure", true, true, true, true, fixedTime, fixedTime.Add(10*time.Hour)) + policies = appendTablePermission(policies, "AutoRestIsSuperCool", true, true, false, true, fixedTime.Add(20*time.Hour), fixedTime.Add(30*time.Hour)) + + err := table.SetPermissions(policies, 30, nil) c.Assert(err, chk.IsNil) - returnedPolicies, err := cli.GetTablePermissions(tn, 0) + newPolicies, err := table.GetPermissions(30, nil) c.Assert(err, chk.IsNil) - // now check policy set. - c.Assert(returnedPolicies, chk.HasLen, 2) + // fixedTime check policy set. + c.Assert(newPolicies, chk.HasLen, 2) - for i := range policies { - c.Assert(returnedPolicies[i].ID, chk.Equals, policies[i].ID) + for i := range newPolicies { + c.Assert(newPolicies[i].ID, chk.Equals, policies[i].ID) // test timestamps down the second // rounding start/expiry time original perms since the returned perms would have been rounded. // so need rounded vs rounded. - c.Assert(returnedPolicies[i].StartTime.UTC().Round(time.Second).Format(time.RFC1123), + c.Assert(newPolicies[i].StartTime.UTC().Round(time.Second).Format(time.RFC1123), chk.Equals, policies[i].StartTime.UTC().Round(time.Second).Format(time.RFC1123)) - - c.Assert(returnedPolicies[i].ExpiryTime.UTC().Round(time.Second).Format(time.RFC1123), + c.Assert(newPolicies[i].ExpiryTime.UTC().Round(time.Second).Format(time.RFC1123), chk.Equals, policies[i].ExpiryTime.UTC().Round(time.Second).Format(time.RFC1123)) - c.Assert(returnedPolicies[i].CanRead, chk.Equals, policies[i].CanRead) - c.Assert(returnedPolicies[i].CanAppend, chk.Equals, policies[i].CanAppend) - c.Assert(returnedPolicies[i].CanUpdate, chk.Equals, policies[i].CanUpdate) - c.Assert(returnedPolicies[i].CanDelete, chk.Equals, policies[i].CanDelete) - + c.Assert(newPolicies[i].CanRead, chk.Equals, policies[i].CanRead) + c.Assert(newPolicies[i].CanAppend, chk.Equals, policies[i].CanAppend) + c.Assert(newPolicies[i].CanUpdate, chk.Equals, policies[i].CanUpdate) + c.Assert(newPolicies[i].CanDelete, chk.Equals, policies[i].CanDelete) } } + +func tableName(c *chk.C, extras ...string) string { + // 32 is the max len for table names + return nameGenerator(32, "table", alpha, c, extras) +} diff --git a/storage/tableserviceclient.go b/storage/tableserviceclient.go index ee5e0a8671b7..769149648fc9 100644 --- a/storage/tableserviceclient.go +++ b/storage/tableserviceclient.go @@ -1,5 +1,21 @@ package storage +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "strconv" +) + +const ( + headerAccept = "Accept" + headerEtag = "Etag" + headerPrefer = "Prefer" + headerXmsContinuation = "x-ms-Continuation-NextTableName" +) + // TableServiceClient contains operations for Microsoft Azure Table Storage // Service. type TableServiceClient struct { @@ -7,14 +23,168 @@ type TableServiceClient struct { auth authentication } +// TableOptions includes options for some table operations +type TableOptions struct { + RequestID string +} + +func (options *TableOptions) addToHeaders(h map[string]string) map[string]string { + if options != nil { + h = addToHeaders(h, "x-ms-client-request-id", options.RequestID) + } + return h +} + +// QueryNextLink includes information for getting the next page of +// results in query operations +type QueryNextLink struct { + NextLink *string + ml MetadataLevel +} + // GetServiceProperties gets the properties of your storage account's table service. // See: https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-table-service-properties -func (c *TableServiceClient) GetServiceProperties() (*ServiceProperties, error) { - return c.client.getServiceProperties(tableServiceName, c.auth) +func (t *TableServiceClient) GetServiceProperties() (*ServiceProperties, error) { + return t.client.getServiceProperties(tableServiceName, t.auth) } // SetServiceProperties sets the properties of your storage account's table service. // See: https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/set-table-service-properties -func (c *TableServiceClient) SetServiceProperties(props ServiceProperties) error { - return c.client.setServiceProperties(props, tableServiceName, c.auth) +func (t *TableServiceClient) SetServiceProperties(props ServiceProperties) error { + return t.client.setServiceProperties(props, tableServiceName, t.auth) +} + +// GetTableReference returns a Table object for the specified table name. +func (t *TableServiceClient) GetTableReference(name string) Table { + return Table{ + tsc: t, + Name: name, + } +} + +// QueryTablesOptions includes options for some table operations +type QueryTablesOptions struct { + Top uint + Filter string + RequestID string +} + +func (options *QueryTablesOptions) getParameters() (url.Values, map[string]string) { + query := url.Values{} + headers := map[string]string{} + if options != nil { + if options.Top > 0 { + query.Add(OdataTop, strconv.FormatUint(uint64(options.Top), 10)) + } + if options.Filter != "" { + query.Add(OdataFilter, options.Filter) + } + headers = addToHeaders(headers, "x-ms-client-request-id", options.RequestID) + } + return query, headers +} + +// QueryTables returns the tables in the storage account. +// You can use query options defined by the OData Protocol specification. +// +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/query-tables +func (t *TableServiceClient) QueryTables(ml MetadataLevel, options *QueryTablesOptions) (*TableQueryResult, error) { + query, headers := options.getParameters() + uri := t.client.getEndpoint(tableServiceName, tablesURIPath, query) + return t.queryTables(uri, headers, ml) +} + +// NextResults returns the next page of results +// from a QueryTables or a NextResults operation. +// +// See https://docs.microsoft.com/rest/api/storageservices/fileservices/query-tables +// See https://docs.microsoft.com/rest/api/storageservices/fileservices/query-timeout-and-pagination +func (tqr *TableQueryResult) NextResults(options *TableOptions) (*TableQueryResult, error) { + if tqr == nil { + return nil, errNilPreviousResult + } + if tqr.NextLink == nil { + return nil, errNilNextLink + } + headers := options.addToHeaders(map[string]string{}) + + return tqr.tsc.queryTables(*tqr.NextLink, headers, tqr.ml) +} + +// TableQueryResult contains the response from +// QueryTables and QueryTablesNextResults functions. +type TableQueryResult struct { + OdataMetadata string `json:"odata.metadata"` + Tables []Table `json:"value"` + QueryNextLink + tsc *TableServiceClient +} + +func (t *TableServiceClient) queryTables(uri string, headers map[string]string, ml MetadataLevel) (*TableQueryResult, error) { + if ml == EmptyPayload { + return nil, errEmptyPayload + } + headers = mergeHeaders(headers, t.client.getStandardHeaders()) + headers[headerAccept] = string(ml) + + resp, err := t.client.exec(http.MethodGet, uri, headers, nil, t.auth) + if err != nil { + return nil, err + } + defer resp.body.Close() + + if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + return nil, err + } + + respBody, err := ioutil.ReadAll(resp.body) + if err != nil { + return nil, err + } + var out TableQueryResult + err = json.Unmarshal(respBody, &out) + if err != nil { + return nil, err + } + + for i := range out.Tables { + out.Tables[i].tsc = t + } + out.tsc = t + + nextLink := resp.headers.Get(http.CanonicalHeaderKey(headerXmsContinuation)) + if nextLink == "" { + out.NextLink = nil + } else { + originalURI, err := url.Parse(uri) + if err != nil { + return nil, err + } + v := originalURI.Query() + v.Set(nextTableQueryParameter, nextLink) + newURI := t.client.getEndpoint(tableServiceName, tablesURIPath, v) + out.NextLink = &newURI + out.ml = ml + } + + return &out, nil +} + +func addBodyRelatedHeaders(h map[string]string, length int) map[string]string { + h[headerContentType] = "application/json" + h[headerContentLength] = fmt.Sprintf("%v", length) + h[headerAcceptCharset] = "UTF-8" + return h +} + +func addReturnContentHeaders(h map[string]string, ml MetadataLevel) map[string]string { + if ml != EmptyPayload { + h[headerPrefer] = "return-content" + h[headerAccept] = string(ml) + } else { + h[headerPrefer] = "return-no-content" + // From API version 2015-12-11 onwards, Accept header is required + h[headerAccept] = string(NoMetadata) + } + return h } diff --git a/storage/util.go b/storage/util.go index 57ca1b6d937e..8a902be2f05b 100644 --- a/storage/util.go +++ b/storage/util.go @@ -12,9 +12,15 @@ import ( "net/http" "net/url" "reflect" + "strconv" + "strings" "time" ) +var ( + fixedTime = time.Date(2050, time.December, 20, 21, 55, 0, 0, time.FixedZone("GMT", -6)) +) + func (c Client) computeHmac256(message string) string { h := hmac.New(sha256.New, c.accountKey) h.Write([]byte(message)) @@ -76,10 +82,118 @@ func headersFromStruct(v interface{}) map[string]string { value := reflect.ValueOf(v) for i := 0; i < value.NumField(); i++ { key := value.Type().Field(i).Tag.Get("header") - val := value.Field(i).String() - if key != "" && val != "" { - headers[key] = val + if key != "" { + reflectedValue := reflect.Indirect(value.Field(i)) + var val string + if reflectedValue.IsValid() { + switch reflectedValue.Type() { + case reflect.TypeOf(fixedTime): + val = timeRfc1123Formatted(reflectedValue.Interface().(time.Time)) + case reflect.TypeOf(uint64(0)), reflect.TypeOf(uint(0)): + val = strconv.FormatUint(reflectedValue.Uint(), 10) + case reflect.TypeOf(int(0)): + val = strconv.FormatInt(reflectedValue.Int(), 10) + default: + val = reflectedValue.String() + } + } + if val != "" { + headers[key] = val + } } } return headers } + +// merges extraHeaders into headers and returns headers +func mergeHeaders(headers, extraHeaders map[string]string) map[string]string { + for k, v := range extraHeaders { + headers[k] = v + } + return headers +} + +func addToHeaders(h map[string]string, key, value string) map[string]string { + if value != "" { + h[key] = value + } + return h +} + +func addTimeToHeaders(h map[string]string, key string, value *time.Time) map[string]string { + if value != nil { + h = addToHeaders(h, key, timeRfc1123Formatted(*value)) + } + return h +} + +func addTimeout(params url.Values, timeout uint) url.Values { + if timeout > 0 { + params.Add("timeout", fmt.Sprintf("%v", timeout)) + } + return params +} + +func addSnapshot(params url.Values, snapshot *time.Time) url.Values { + if snapshot != nil { + params.Add("snapshot", timeRfc1123Formatted(*snapshot)) + } + return params +} + +func getTimeFromHeaders(h http.Header, key string) (*time.Time, error) { + var out time.Time + var err error + outStr := h.Get(key) + if outStr != "" { + out, err = time.Parse(time.RFC1123, outStr) + if err != nil { + return nil, err + } + } + return &out, nil +} + +// TimeRFC1123 is an alias for time.Time needed for custom Unmarshalling +type TimeRFC1123 time.Time + +// UnmarshalXML is a custom unmarshaller that overrides the default time unmarshal which uses a different time layout. +func (t *TimeRFC1123) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + var value string + d.DecodeElement(&value, &start) + parse, err := time.Parse(time.RFC1123, value) + if err != nil { + return err + } + *t = TimeRFC1123(parse) + return nil +} + +// returns a map of custom metadata values from the specified HTTP header +func getMetadataFromHeaders(header http.Header) map[string]string { + metadata := make(map[string]string) + for k, v := range header { + // Can't trust CanonicalHeaderKey() to munge case + // reliably. "_" is allowed in identifiers: + // https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx + // https://msdn.microsoft.com/library/aa664670(VS.71).aspx + // http://tools.ietf.org/html/rfc7230#section-3.2 + // ...but "_" is considered invalid by + // CanonicalMIMEHeaderKey in + // https://golang.org/src/net/textproto/reader.go?s=14615:14659#L542 + // so k can be "X-Ms-Meta-Lol" or "x-ms-meta-lol_rofl". + k = strings.ToLower(k) + if len(v) == 0 || !strings.HasPrefix(k, strings.ToLower(userDefinedMetadataHeaderPrefix)) { + continue + } + // metadata["lol"] = content of the last X-Ms-Meta-Lol header + k = k[len(userDefinedMetadataHeaderPrefix):] + metadata[k] = v[len(v)-1] + } + + if len(metadata) == 0 { + return nil + } + + return metadata +} diff --git a/storage/util_test.go b/storage/util_test.go index a1817d162428..ec57f5056cd2 100644 --- a/storage/util_test.go +++ b/storage/util_test.go @@ -1,15 +1,83 @@ package storage import ( + "bytes" + "encoding/hex" "encoding/xml" + "fmt" "io/ioutil" "net/url" + "os" + "path/filepath" "strings" + "testing" "time" chk "gopkg.in/check.v1" ) +func TestMain(m *testing.M) { + exitStatus := m.Run() + err := fixRecordings() + if err != nil { + fmt.Fprintf(os.Stderr, "After test run, fixing recordings failed with error: %v\n", err) + exitStatus = 1 + } + os.Exit(exitStatus) +} + +func fixRecordings() error { + err := filepath.Walk(recordingsFolder, func(path string, file os.FileInfo, err error) error { + if strings.ToLower(filepath.Ext(path)) == ".yaml" { + recording, err := ioutil.ReadFile(path) + if err != nil { + fmt.Fprintf(os.Stderr, "Error reading file '%s': %v", path, err) + } + + fixedRecording := replaceStorageAccount(string(recording)) + + err = ioutil.WriteFile(path, []byte(fixedRecording), 0) + if err != nil { + fmt.Fprintf(os.Stderr, "Error writing file '%s': %v", path, err) + } + } + return err + }) + return err +} + +func replaceStorageAccount(recording string) string { + name := os.Getenv("ACCOUNT_NAME") + if name == "" { + // do nothing + return recording + } + + nameHex := getHex(name) + dummyHex := getHex(dummyStorageAccount) + + r := strings.NewReplacer(name, dummyStorageAccount, + nameHex, dummyHex) + + return r.Replace(string(recording)) +} + +func getHex(input string) string { + encoded := strings.ToUpper(hex.EncodeToString([]byte(input))) + formatted := bytes.Buffer{} + for i := 0; i < len(encoded); i += 2 { + formatted.WriteString(`\x`) + formatted.WriteString(encoded[i : i+2]) + } + return formatted.String() +} + +const ( + dummyStorageAccount = "golangrocksonazure" + dummyMiniStorageKey = "YmFy" + recordingsFolder = "recordings" +) + func (s *StorageClientSuite) Test_timeRfc1123Formatted(c *chk.C) { now := time.Now().UTC() expectedLayout := "Mon, 02 Jan 2006 15:04:05 GMT" @@ -35,8 +103,8 @@ func (s *StorageClientSuite) Test_prepareBlockListRequest(c *chk.C) { expected := `` c.Assert(prepareBlockListRequest(empty), chk.DeepEquals, expected) - blocks := []Block{{"foo", BlockStatusLatest}, {"bar", BlockStatusUncommitted}} - expected = `foobar` + blocks := []Block{{"lol", BlockStatusLatest}, {"rofl", BlockStatusUncommitted}} + expected = `lolrofl` c.Assert(prepareBlockListRequest(blocks), chk.DeepEquals, expected) } @@ -70,14 +138,47 @@ func (s *StorageClientSuite) Test_xmlMarshal(c *chk.C) { func (s *StorageClientSuite) Test_headersFromStruct(c *chk.C) { type t struct { - header1 string `header:"HEADER1"` - header2 string `header:"HEADER2"` + Header1 string `header:"HEADER1"` + Header2 string `header:"HEADER2"` + TimePtr *time.Time `header:"ptr-time-header"` + TimeHeader time.Time `header:"time-header"` + UintPtr *uint `header:"ptr-uint-header"` + UintHeader uint `header:"uint-header"` + IntPtr *int `header:"ptr-int-header"` + IntHeader int `header:"int-header"` + StringAliasPtr *BlobType `header:"ptr-string-alias-header"` + StringAlias BlobType `header:"string-alias-header"` + NilPtr *time.Time `header:"nil-ptr"` + EmptyString string `header:"empty-string"` } - h := t{header1: "value1", header2: "value2"} + timeHeader := time.Date(1985, time.February, 23, 10, 0, 0, 0, time.Local) + uintHeader := uint(15) + intHeader := 30 + alias := BlobTypeAppend + h := t{ + Header1: "value1", + Header2: "value2", + TimePtr: &timeHeader, + TimeHeader: timeHeader, + UintPtr: &uintHeader, + UintHeader: uintHeader, + IntPtr: &intHeader, + IntHeader: intHeader, + StringAliasPtr: &alias, + StringAlias: alias, + } expected := map[string]string{ - "HEADER1": "value1", - "HEADER2": "value2", + "HEADER1": "value1", + "HEADER2": "value2", + "ptr-time-header": "Sat, 23 Feb 1985 10:00:00 GMT", + "time-header": "Sat, 23 Feb 1985 10:00:00 GMT", + "ptr-uint-header": "15", + "uint-header": "15", + "ptr-int-header": "30", + "int-header": "30", + "ptr-string-alias-header": "AppendBlob", + "string-alias-header": "AppendBlob", } out := headersFromStruct(h)