Skip to content

Commit

Permalink
Copy Blob from URL/Put Blob from URL copy source tags (#21128)
Browse files Browse the repository at this point in the history
* Regenerating AzBlob to STG 85/86 (#20724)

* Regenerating azblob to stg 85/86

* Updating CopyFromURL

* minor change

* minor fixes

* undo some minor fixes

* Updating Go code generator

* Fixing calls to pipeline

* Adding custom UnmarshalXML for BlobItem and BlobPrefix

* Updating constructor method for AppendBlobClient

* Updating Client constructors

* Undoing minor fixes to blob examples

* Fixing authpolicy

* Updating azcore version

* Fixing client strings

* Const for service client

* Minor fix

* fixing go mod files

* Shared constants client name

* Addressing comments

* [Feature STG 85/86] Cold Tier  (#21032)

* Adding Cold Tier + tests

* Recorded tests

* Updated CHANGELOG.md

* Fixing linting issues

* Updating Cold tier test and recording

* Addressing commits

* Adding CopySourceBlobTags

* Fixing enum variable name, adding default test, changelog update

* Cleaning up constants

* Moving const to constants.go

* Small change
  • Loading branch information
siminsavani-msft authored Jul 17, 2023
1 parent d7511d1 commit 9403f85
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 1 deletion.
1 change: 1 addition & 0 deletions sdk/storage/azblob/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Features Added
* Added support for [Cold tier](https://learn.microsoft.com/azure/storage/blobs/access-tiers-overview?tabs=azure-portal).
* Added CopySourceTag option for UploadBlobFromURLOptions

### Breaking Changes

Expand Down
117 changes: 116 additions & 1 deletion sdk/storage/azblob/blockblob/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -851,7 +851,7 @@ func setUpPutBlobFromURLTest(testName string, _require *require.Assertions, svcC
sasQueryParams, err := sas.AccountSignatureValues{
Protocol: sas.ProtocolHTTPS,
ExpiryTime: expiryTime,
Permissions: to.Ptr(sas.AccountPermissions{Read: true, List: true}).String(),
Permissions: to.Ptr(sas.AccountPermissions{Read: true, List: true, Tag: true}).String(),
ResourceTypes: to.Ptr(sas.AccountResourceTypes{Container: true, Object: true}).String(),
}.SignWithSharedKey(credential)
_require.Nil(err)
Expand Down Expand Up @@ -884,6 +884,121 @@ func (s *BlockBlobUnrecordedTestsSuite) TestPutBlobFromURL() {
_require.Equal(destBuffer, sourceData)
}

func (s *BlockBlobUnrecordedTestsSuite) TestPutBlobFromURLWithCopySourceTagsDefault() {
_require := require.New(s.T())
testName := s.T().Name()
svcClient, err := testcommon.GetServiceClient(s.T(), testcommon.TestAccountDefault, nil)
_require.NoError(err)

containerClient, srcBlob, destBlob, srcBlobURLWithSAS, _ := setUpPutBlobFromURLTest(testName, _require, svcClient)
defer testcommon.DeleteContainer(context.Background(), _require, containerClient)

// Set tags to source
srcBlobTagsMap := map[string]string{
"source": "tags",
}
_, err = srcBlob.SetTags(context.Background(), srcBlobTagsMap, nil)
_require.NoError(err)

// Dest tags
destBlobTagsMap := map[string]string{
"dest": "tags",
}

// By default, the CopySourceTag header is Replace
options := blockblob.UploadBlobFromURLOptions{
Tags: destBlobTagsMap,
}

// Invoke UploadBlobFromURL
pbResp, err := destBlob.UploadBlobFromURL(context.Background(), srcBlobURLWithSAS, &options)
_require.NotNil(pbResp)
_require.NoError(err)

// Get tags from dest and check if tags got replaced with dest tags
resp, err := destBlob.GetTags(context.Background(), nil)
_require.NoError(err)
_require.Equal(*resp.BlobTagSet[0].Key, "dest")
_require.Equal(*resp.BlobTagSet[0].Value, "tags")
}

func (s *BlockBlobUnrecordedTestsSuite) TestPutBlobFromURLWithCopySourceTagsReplace() {
_require := require.New(s.T())
testName := s.T().Name()
svcClient, err := testcommon.GetServiceClient(s.T(), testcommon.TestAccountDefault, nil)
_require.NoError(err)

containerClient, srcBlob, destBlob, srcBlobURLWithSAS, _ := setUpPutBlobFromURLTest(testName, _require, svcClient)
defer testcommon.DeleteContainer(context.Background(), _require, containerClient)

// Set tags to source
srcBlobTagsMap := map[string]string{
"source": "tags",
}
_, err = srcBlob.SetTags(context.Background(), srcBlobTagsMap, nil)
_require.NoError(err)

// Dest tags
destBlobTagsMap := map[string]string{
"dest": "tags",
}

options := blockblob.UploadBlobFromURLOptions{
Tags: destBlobTagsMap,
CopySourceTags: to.Ptr(blockblob.BlobCopySourceTagsReplace),
}

// Invoke UploadBlobFromURL
pbResp, err := destBlob.UploadBlobFromURL(context.Background(), srcBlobURLWithSAS, &options)
_require.NotNil(pbResp)
_require.NoError(err)

// Get tags from dest and check if tags got replaced with dest tags
resp, err := destBlob.GetTags(context.Background(), nil)
_require.NoError(err)
_require.Equal(*resp.BlobTagSet[0].Key, "dest")
_require.Equal(*resp.BlobTagSet[0].Value, "tags")
}

func (s *BlockBlobUnrecordedTestsSuite) TestPutBlobFromURLWithCopySourceTagsCopy() {
_require := require.New(s.T())
testName := s.T().Name()
svcClient, err := testcommon.GetServiceClient(s.T(), testcommon.TestAccountDefault, nil)
_require.NoError(err)

containerClient, srcBlob, destBlob, srcBlobURLWithSAS, _ := setUpPutBlobFromURLTest(testName, _require, svcClient)
defer testcommon.DeleteContainer(context.Background(), _require, containerClient)

// Set tags to source
srcBlobTagsMap := map[string]string{
"source": "tags",
}
_, err = srcBlob.SetTags(context.Background(), srcBlobTagsMap, nil)
_require.NoError(err)

// Set tags to dest to ensure that COPY works
destBlobTagsMap := map[string]string{
"dest": "tags",
}
_, err = destBlob.SetTags(context.Background(), destBlobTagsMap, nil)
_require.NoError(err)

options := blockblob.UploadBlobFromURLOptions{
CopySourceTags: to.Ptr(blockblob.BlobCopySourceTagsCopy),
}

// Invoke UploadBlobFromURL
pbResp, err := destBlob.UploadBlobFromURL(context.Background(), srcBlobURLWithSAS, &options)
_require.NotNil(pbResp)
_require.NoError(err)

// Get tags from dest and check if it matches source tags
resp, err := destBlob.GetTags(context.Background(), nil)
_require.NoError(err)
_require.Equal(*resp.BlobTagSet[0].Key, "source")
_require.Equal(*resp.BlobTagSet[0].Value, "tags")
}

func (s *BlockBlobUnrecordedTestsSuite) TestPutBlobFromURLNegative() {
_require := require.New(s.T())
testName := s.T().Name()
Expand Down
8 changes: 8 additions & 0 deletions sdk/storage/azblob/blockblob/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,11 @@ const (
func PossibleBlockListTypeValues() []BlockListType {
return generated.PossibleBlockListTypeValues()
}

// BlobCopySourceTags - can be 'COPY' or 'REPLACE'
type BlobCopySourceTags = generated.BlobCopySourceTags

const (
BlobCopySourceTagsCopy = generated.BlobCopySourceTagsCOPY
BlobCopySourceTagsReplace = generated.BlobCopySourceTagsREPLACE
)
4 changes: 4 additions & 0 deletions sdk/storage/azblob/blockblob/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ type UploadBlobFromURLOptions struct {
// Optional, default is true. Indicates if properties from the source blob should be copied.
CopySourceBlobProperties *bool

// Optional, default 'replace'. Indicates if source tags should be copied or replaced with the tags specified by x-ms-tags.
CopySourceTags *BlobCopySourceTags

// Optional. Specifies a user-defined name-value pair associated with the blob.
Metadata map[string]*string

Expand Down Expand Up @@ -113,6 +116,7 @@ func (o *UploadBlobFromURLOptions) format() (*generated.BlockBlobClientPutBlobFr
BlobTagsString: shared.SerializeBlobTagsToStrPtr(o.Tags),
CopySourceAuthorization: o.CopySourceAuthorization,
CopySourceBlobProperties: o.CopySourceBlobProperties,
CopySourceTags: o.CopySourceTags,
Metadata: o.Metadata,
SourceContentMD5: o.SourceContentMD5,
Tier: o.Tier,
Expand Down

0 comments on commit 9403f85

Please sign in to comment.