Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions sdk/storage/azure-storage-blob/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
## 12.8.0-beta.2 (Unreleased)
- Fixed a bug that, when the data length parameter did not match the actual length of the data in BlobClient.upload, caused a zero length blob to be uploaded rather than throwing an exception.
- Fixed a bug that ignored the customer's specified block size when determining buffer sizes in BlobClient.upload
- Added support for Object Replication Service on listBlobs and getProperties.
- Added support for blob tags. Added tagsConditions to BlobRequestConditions that allow a user to specify a SQL statement for the blob's tags to satisfy.
- Added support for setting tags and filterTags operations on SAS by adding to AccountSASPermissions, BlobSASPermissions, and BlobContainerSASPermissions.
- Added support for setting and getting the StaticWebsite.DefaultIndexDocumentPath property on the service client.
- Added RehydratePriority to BlobProperties and BlobItemProperties.
- Fixed bug where Query Input Stream would throw when a ByteBuffer of length 0 was encountered.

## 12.8.0-beta.1 (2020-07-07)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ public static BlobItemProperties populateBlobItemProperties(BlobItemPropertiesIn
blobItemProperties.setEncryptionScope(blobItemPropertiesInternal.getEncryptionScope());
blobItemProperties.setAccessTierChangeTime(blobItemPropertiesInternal.getAccessTierChangeTime());
blobItemProperties.setTagCount(blobItemPropertiesInternal.getTagCount());
blobItemProperties.setRehydratePriority(blobItemPropertiesInternal.getRehydratePriority());

return blobItemProperties;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,12 @@ public final class BlobItemProperties {
@JsonProperty(value = "TagCount")
private Integer tagCount;

/*
* Possible values include: 'High', 'Standard'
*/
@JsonProperty(value = "RehydratePriority")
private RehydratePriority rehydratePriority;

/**
* Get the creationTime property: The creationTime property.
*
Expand Down Expand Up @@ -904,4 +910,26 @@ public BlobItemProperties setTagCount(Integer tagCount) {
this.tagCount = tagCount;
return this;
}

/**
* Get the rehydratePriority property: Possible values include: 'High',
* 'Standard'.
*
* @return the rehydratePriority value.
*/
public RehydratePriority getRehydratePriority() {
return this.rehydratePriority;
}

/**
* Set the rehydratePriority property: Possible values include: 'High',
* 'Standard'.
*
* @param rehydratePriority the rehydratePriority value to set.
* @return the BlobItemProperties object itself.
*/
public BlobItemProperties setRehydratePriority(RehydratePriority rehydratePriority) {
this.rehydratePriority = rehydratePriority;
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public final class BlobProperties {
private final Boolean isCurrentVersion;
private final List<ObjectReplicationPolicy> objectReplicationSourcePolicies;
private final String objectReplicationDestinationPolicyId;
private final RehydratePriority rehydratePriority;

/**
* Constructs a {@link BlobProperties}.
Expand Down Expand Up @@ -109,8 +110,8 @@ public BlobProperties(final OffsetDateTime creationTime, final OffsetDateTime la
contentLanguage, cacheControl, blobSequenceNumber, blobType, leaseStatus, leaseState, leaseDuration,
copyId, copyStatus, copySource, copyProgress, copyCompletionTime, copyStatusDescription, isServerEncrypted,
isIncrementalCopy, copyDestinationSnapshot, accessTier, isAccessTierInferred, archiveStatus,
encryptionKeySha256, null, accessTierChangeTime, metadata, committedBlockCount, null, null,
null, null, null);
encryptionKeySha256, null, accessTierChangeTime, metadata, committedBlockCount, (Long) null,
null, null, null, null);
}

/**
Expand Down Expand Up @@ -155,6 +156,7 @@ public BlobProperties(final OffsetDateTime creationTime, final OffsetDateTime la
* @param isCurrentVersion Flag indicating if version identifier points to current version of the blob.
* @param tagCount Number of tags associated with the blob.
* @param objectReplicationStatus The object replication status map to parse.
* @param rehydratePriority The rehydrate priority
*/
public BlobProperties(final OffsetDateTime creationTime, final OffsetDateTime lastModified, final String eTag,
final long blobSize, final String contentType, final byte[] contentMd5, final String contentEncoding,
Expand All @@ -167,7 +169,7 @@ public BlobProperties(final OffsetDateTime creationTime, final OffsetDateTime la
final Boolean isAccessTierInferred, final ArchiveStatus archiveStatus, final String encryptionKeySha256,
final String encryptionScope, final OffsetDateTime accessTierChangeTime, final Map<String, String> metadata,
final Integer committedBlockCount, final String versionId, final Boolean isCurrentVersion,
final Long tagCount, Map<String, String> objectReplicationStatus) {
final Long tagCount, Map<String, String> objectReplicationStatus, String rehydratePriority) {
this.creationTime = creationTime;
this.lastModified = lastModified;
this.eTag = eTag;
Expand Down Expand Up @@ -224,6 +226,7 @@ public BlobProperties(final OffsetDateTime creationTime, final OffsetDateTime la
for (Map.Entry<String, List<ObjectReplicationRule>> entry : internalSourcePolicies.entrySet()) {
this.objectReplicationSourcePolicies.add(new ObjectReplicationPolicy(entry.getKey(), entry.getValue()));
}
this.rehydratePriority = RehydratePriority.fromString(rehydratePriority);
}


Expand Down Expand Up @@ -322,6 +325,7 @@ public BlobProperties(final OffsetDateTime creationTime, final OffsetDateTime la
this.isCurrentVersion = isCurrentVersion;
this.objectReplicationSourcePolicies = objectReplicationSourcePolicies;
this.objectReplicationDestinationPolicyId = objectReplicationDestinationPolicyId;
this.rehydratePriority = null;
}

/**
Expand Down Expand Up @@ -596,4 +600,11 @@ public List<ObjectReplicationPolicy> getObjectReplicationSourcePolicies() {
public String getObjectReplicationDestinationPolicyId() {
return this.objectReplicationDestinationPolicyId;
}

/**
* @return The {@link RehydratePriority} of the blob if it is in RehydratePending state.
*/
public RehydratePriority getRehydratePriority() {
return this.rehydratePriority;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1215,7 +1215,7 @@ Mono<Response<BlobProperties>> getPropertiesWithResponse(BlobRequestConditions r
hd.isAccessTierInferred(), ArchiveStatus.fromString(hd.getArchiveStatus()),
hd.getEncryptionKeySha256(), hd.getEncryptionScope(), hd.getAccessTierChangeTime(),
hd.getMetadata(), hd.getBlobCommittedBlockCount(), hd.getVersionId(), hd.isCurrentVersion(),
hd.getTagCount(), hd.getObjectReplicationRules());
hd.getTagCount(), hd.getObjectReplicationRules(), hd.getRehydratePriority());
return new SimpleResponse<>(rb, properties);
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,7 @@ class BlobAPITest extends APISpec {
properties.getArchiveStatus() == null
properties.getCreationTime() != null
properties.getTagCount() == 1
properties.getRehydratePriority() == null // tested in setTier rehydrate priority
}

def "Get properties min"() {
Expand Down Expand Up @@ -2346,10 +2347,33 @@ class BlobAPITest extends APISpec {
cc.listBlobs().iterator().next().getProperties().getArchiveStatus() == status

where:
sourceTier | destTier | priority | status
AccessTier.ARCHIVE | AccessTier.COOL | RehydratePriority.STANDARD | ArchiveStatus.REHYDRATE_PENDING_TO_COOL
AccessTier.ARCHIVE | AccessTier.HOT | RehydratePriority.STANDARD | ArchiveStatus.REHYDRATE_PENDING_TO_HOT
AccessTier.ARCHIVE | AccessTier.HOT | RehydratePriority.HIGH | ArchiveStatus.REHYDRATE_PENDING_TO_HOT
sourceTier | destTier || status
AccessTier.ARCHIVE | AccessTier.COOL || ArchiveStatus.REHYDRATE_PENDING_TO_COOL
AccessTier.ARCHIVE | AccessTier.HOT || ArchiveStatus.REHYDRATE_PENDING_TO_HOT
AccessTier.ARCHIVE | AccessTier.HOT || ArchiveStatus.REHYDRATE_PENDING_TO_HOT
}

@Unroll
def "Set tier rehydrate priority"() {
setup:
if (rehydratePriority != null) {
bc.setAccessTier(AccessTier.ARCHIVE)

bc.setAccessTierWithResponse(new BlobSetAccessTierOptions(AccessTier.HOT).setPriority(rehydratePriority), null, null)
}

when:
def resp = bc.getPropertiesWithResponse(null, null, null)

then:
resp.getStatusCode() == 200
resp.getValue().getRehydratePriority() == rehydratePriority

where:
rehydratePriority || _
null || _
RehydratePriority.STANDARD || _
RehydratePriority.HIGH || _
}

def "Set tier error"() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import com.azure.storage.blob.models.LeaseStatusType
import com.azure.storage.blob.models.ListBlobsOptions
import com.azure.storage.blob.models.ObjectReplicationPolicy
import com.azure.storage.blob.models.ObjectReplicationStatus
import com.azure.storage.blob.models.RehydratePriority
import com.azure.storage.blob.options.BlobSetAccessTierOptions
import com.azure.storage.blob.options.PageBlobCreateOptions
import com.azure.storage.blob.models.PublicAccessType
import com.azure.storage.blob.specialized.AppendBlobClient
Expand Down Expand Up @@ -937,6 +939,32 @@ class ContainerAPITest extends APISpec {
pagedResponse2.getContinuationToken() == null
}

@Unroll
def "List blobs flat rehydrate priority"() {
setup:
def name = generateBlobName()
def bc = cc.getBlobClient(name).getBlockBlobClient()
bc.upload(defaultInputStream.get(), 7)

if (rehydratePriority != null) {
bc.setAccessTier(AccessTier.ARCHIVE)

bc.setAccessTierWithResponse(new BlobSetAccessTierOptions(AccessTier.HOT).setPriority(rehydratePriority), null, null)
}

when:
def item = cc.listBlobs().iterator().next()

then:
item.getProperties().getRehydratePriority() == rehydratePriority

where:
rehydratePriority || _
null || _
RehydratePriority.STANDARD || _
RehydratePriority.HIGH || _
}

def "List blobs flat error"() {
setup:
cc = primaryBlobServiceClient.getBlobContainerClient(generateContainerName())
Expand Down Expand Up @@ -1317,6 +1345,32 @@ class ContainerAPITest extends APISpec {
cc.listBlobs(new ListBlobsOptions().setMaxResultsPerPage(PAGE_SIZE), null).stream().count() == NUM_BLOBS
}

@Unroll
def "List blobs hier rehydrate priority"() {
setup:
def name = generateBlobName()
def bc = cc.getBlobClient(name).getBlockBlobClient()
bc.upload(defaultInputStream.get(), 7)

if (rehydratePriority != null) {
bc.setAccessTier(AccessTier.ARCHIVE)

bc.setAccessTierWithResponse(new BlobSetAccessTierOptions(AccessTier.HOT).setPriority(rehydratePriority), null, null)
}

when:
def item = cc.listBlobsByHierarchy(null).iterator().next()

then:
item.getProperties().getRehydratePriority() == rehydratePriority

where:
rehydratePriority || _
null || _
RehydratePriority.STANDARD || _
RehydratePriority.HIGH || _
}

def "List blobs hier error"() {
setup:
cc = primaryBlobServiceClient.getBlobContainerClient(generateContainerName())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
{
"networkCallRecords" : [ {
"Method" : "PUT",
"Uri" : "https://REDACTED.blob.core.windows.net/jtcsettierrehydratepriority0655036b64db747b264d7?restype=container",
"Headers" : {
"x-ms-version" : "2019-12-12",
"User-Agent" : "azsdk-java-azure-storage-blob/12.8.0-beta.2 (11.0.7; Windows 10; 10.0)",
"x-ms-client-request-id" : "bccb2f6c-a2b0-4275-a784-38ef355ba125"
},
"Response" : {
"x-ms-version" : "2019-12-12",
"Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
"ETag" : "0x8D82A71BD01DCB6",
"Last-Modified" : "Fri, 17 Jul 2020 16:52:06 GMT",
"retry-after" : "0",
"Content-Length" : "0",
"StatusCode" : "201",
"x-ms-request-id" : "27c6d086-a01e-0055-6c5a-5c8109000000",
"Date" : "Fri, 17 Jul 2020 16:52:05 GMT",
"x-ms-client-request-id" : "bccb2f6c-a2b0-4275-a784-38ef355ba125"
},
"Exception" : null
}, {
"Method" : "PUT",
"Uri" : "https://REDACTED.blob.core.windows.net/jtcsettierrehydratepriority0655036b64db747b264d7/javablobsettierrehydratepriority120642b8037355bfdf",
"Headers" : {
"x-ms-version" : "2019-12-12",
"User-Agent" : "azsdk-java-azure-storage-blob/12.8.0-beta.2 (11.0.7; Windows 10; 10.0)",
"x-ms-client-request-id" : "24c6562c-5698-4551-92d8-4b2c08a0139c",
"Content-Type" : "application/octet-stream"
},
"Response" : {
"x-ms-version" : "2019-12-12",
"Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
"x-ms-content-crc64" : "6RYQPwaVsyQ=",
"x-ms-version-id" : "2020-07-17T16:52:07.0300485Z",
"Last-Modified" : "Fri, 17 Jul 2020 16:52:07 GMT",
"retry-after" : "0",
"StatusCode" : "201",
"x-ms-request-server-encrypted" : "true",
"Date" : "Fri, 17 Jul 2020 16:52:06 GMT",
"Content-MD5" : "wh+Wm18D0z1D4E+PE252gg==",
"ETag" : "0x8D82A71BD67EB45",
"Content-Length" : "0",
"x-ms-request-id" : "c8a72cc7-c01e-0031-7c5a-5c7091000000",
"x-ms-client-request-id" : "24c6562c-5698-4551-92d8-4b2c08a0139c"
},
"Exception" : null
}, {
"Method" : "HEAD",
"Uri" : "https://REDACTED.blob.core.windows.net/jtcsettierrehydratepriority0655036b64db747b264d7/javablobsettierrehydratepriority120642b8037355bfdf",
"Headers" : {
"x-ms-version" : "2019-12-12",
"User-Agent" : "azsdk-java-azure-storage-blob/12.8.0-beta.2 (11.0.7; Windows 10; 10.0)",
"x-ms-client-request-id" : "c4e3ed2d-af6a-41d7-9999-5a85470c5494"
},
"Response" : {
"x-ms-is-current-version" : "true",
"x-ms-version" : "2019-12-12",
"x-ms-lease-status" : "unlocked",
"Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
"x-ms-lease-state" : "available",
"x-ms-version-id" : "2020-07-17T16:52:07.0300485Z",
"Last-Modified" : "Fri, 17 Jul 2020 16:52:07 GMT",
"retry-after" : "0",
"StatusCode" : "200",
"Date" : "Fri, 17 Jul 2020 16:52:06 GMT",
"x-ms-blob-type" : "BlockBlob",
"Content-MD5" : "wh+Wm18D0z1D4E+PE252gg==",
"Accept-Ranges" : "bytes",
"x-ms-server-encrypted" : "true",
"x-ms-access-tier-inferred" : "true",
"x-ms-access-tier" : "Hot",
"ETag" : "0x8D82A71BD67EB45",
"x-ms-creation-time" : "Fri, 17 Jul 2020 16:52:07 GMT",
"Content-Length" : "7",
"x-ms-request-id" : "a59445d5-801e-001f-7d5a-5c2286000000",
"x-ms-client-request-id" : "c4e3ed2d-af6a-41d7-9999-5a85470c5494",
"Content-Type" : "application/octet-stream"
},
"Exception" : null
}, {
"Method" : "GET",
"Uri" : "https://REDACTED.blob.core.windows.net?prefix=jtcsettierrehydratepriority&comp=list",
"Headers" : {
"x-ms-version" : "2019-12-12",
"User-Agent" : "azsdk-java-azure-storage-blob/12.8.0-beta.2 (11.0.7; Windows 10; 10.0)",
"x-ms-client-request-id" : "04e1de65-d520-4c46-9d46-c41462abe824"
},
"Response" : {
"Transfer-Encoding" : "chunked",
"x-ms-version" : "2019-12-12",
"Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
"retry-after" : "0",
"StatusCode" : "200",
"x-ms-request-id" : "42d0e68a-e01e-0054-395a-5cded5000000",
"Body" : "<?xml version=\"1.0\" encoding=\"utf-8\"?><EnumerationResults ServiceEndpoint=\"https://seanmccprodca.blob.core.windows.net/\"><Prefix>jtcsettierrehydratepriority</Prefix><Containers><Container><Name>jtcsettierrehydratepriority0655036b64db747b264d7</Name><Properties><Last-Modified>Fri, 17 Jul 2020 16:52:06 GMT</Last-Modified><Etag>\"0x8D82A71BD01DCB6\"</Etag><LeaseStatus>unlocked</LeaseStatus><LeaseState>available</LeaseState><DefaultEncryptionScope>$account-encryption-key</DefaultEncryptionScope><DenyEncryptionScopeOverride>false</DenyEncryptionScopeOverride><HasImmutabilityPolicy>false</HasImmutabilityPolicy><HasLegalHold>false</HasLegalHold></Properties></Container></Containers><NextMarker /></EnumerationResults>",
"Date" : "Fri, 17 Jul 2020 16:52:07 GMT",
"x-ms-client-request-id" : "04e1de65-d520-4c46-9d46-c41462abe824",
"Content-Type" : "application/xml"
},
"Exception" : null
}, {
"Method" : "DELETE",
"Uri" : "https://REDACTED.blob.core.windows.net/jtcsettierrehydratepriority0655036b64db747b264d7?restype=container",
"Headers" : {
"x-ms-version" : "2019-12-12",
"User-Agent" : "azsdk-java-azure-storage-blob/12.8.0-beta.2 (11.0.7; Windows 10; 10.0)",
"x-ms-client-request-id" : "0f426077-2c51-496a-8c67-2b23d1111838"
},
"Response" : {
"x-ms-version" : "2019-12-12",
"Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
"retry-after" : "0",
"Content-Length" : "0",
"StatusCode" : "202",
"x-ms-request-id" : "6f3a7ab3-801e-000f-045a-5ce7ee000000",
"Date" : "Fri, 17 Jul 2020 16:52:08 GMT",
"x-ms-client-request-id" : "0f426077-2c51-496a-8c67-2b23d1111838"
},
"Exception" : null
} ],
"variables" : [ "jtcsettierrehydratepriority0655036b64db747b264d7", "javablobsettierrehydratepriority120642b8037355bfdf" ]
}
Loading