Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b97fc2e
generate new api based on swaggerfile
browndav-msft Mar 12, 2026
b29e9ec
create base test for new api
browndav-msft Mar 12, 2026
50b152e
switch to premiumstorageaccount for smart-tier
browndav-msft Mar 12, 2026
e8aa8ed
recording for setblobaccesstiersmart
browndav-msft Mar 12, 2026
216e1a7
rerecording for setblobaccesstiersmart
browndav-msft Mar 12, 2026
7b2cc60
updating assets
ibrandes Mar 12, 2026
85b2860
add SMART access tier in enum, accessTierInferred and smartAcessTier …
browndav-msft Mar 12, 2026
2836cba
create basic test for smart tier in datalake
browndav-msft Mar 12, 2026
2cb8e5c
fix linting in PathProperties
browndav-msft Mar 12, 2026
00fb711
fixed broken deps for FileApiTest#getInferredTierWhenAssignedSmart
browndav-msft Mar 12, 2026
3c5fb20
changed boolean to Boolean to allow for null
browndav-msft Mar 13, 2026
89e946e
add premiumDataLakeServiceClient for smart tier
browndav-msft Mar 13, 2026
48425f7
remove code to test access tier smart on get props for datalake
browndav-msft Mar 13, 2026
9a5344a
add params for smartAccessTier to javadocs
browndav-msft Mar 13, 2026
0e3d4db
Merge branch 'feature/storage/stg102base' of https://github.com/Azure…
ibrandes Mar 15, 2026
eba47d8
Merge branch 'stg102/ObjectLevelSmartAccess' of https://github.com/br…
ibrandes Mar 15, 2026
3be7588
removing breaking changes
ibrandes Mar 15, 2026
c3e54cc
Merge branch 'stg102/ObjectLevelSmartAccess' of https://github.com/br…
browndav-msft Mar 15, 2026
85a4da1
removing datalake breaking changes
ibrandes Mar 15, 2026
03c31d9
add recordings for BlobBaseApiTests
browndav-msft Mar 15, 2026
17de56d
Merge branch 'stg102/ObjectLevelSmartAccess' of https://github.com/br…
browndav-msft Mar 15, 2026
8f04fa2
add recordings for BlobApiTests#uploadStreamAccessTierSmart
browndav-msft Mar 15, 2026
1c6909f
add recordings for BlobAsyncApiTests#uploadStreamAccessTierSmart
browndav-msft Mar 15, 2026
8e5a135
add recordings for BlobAsyncApiTests#uploadStreamAccessTierSmart
browndav-msft Mar 15, 2026
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
2 changes: 1 addition & 1 deletion sdk/storage/azure-storage-blob-batch/assets.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"AssetsRepo": "Azure/azure-sdk-assets",
"AssetsRepoPrefixPath": "java",
"TagPrefix": "java/storage/azure-storage-blob-batch",
"Tag": "java/storage/azure-storage-blob-batch_1951fdc3fd"
"Tag": "java/storage/azure-storage-blob-batch_45e14073e7"
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,33 @@ public void setTierAllSucceed() {
.upload(DATA.getDefaultInputStream(), DATA.getDefaultDataSize());

Response<Void> response1 = batch.setBlobAccessTier(containerName, blobName1, AccessTier.HOT);
Response<Void> response2 = batch.setBlobAccessTier(containerName, blobName2, AccessTier.COOL);
// Response<Void> response2 = batch.setBlobAccessTier(containerName, blobName2, AccessTier.COOL);
batchClient.submitBatch(batch);

assertEquals(200, response1.getStatusCode());
// assertEquals(200, response2.getStatusCode());
}

@Test
@RequiredServiceVersion(clazz = BlobServiceVersion.class, min = "2026-02-06")
public void setBlobAccessTierSmart() {
String containerName = generateContainerName();
String blobName1 = generateBlobName();
String blobName2 = generateBlobName();
BlobBatchClient premiumBatchClient = new BlobBatchClientBuilder(premiumStorageBlobServiceClient).buildClient();
BlobBatch batch = premiumBatchClient.getBlobBatch();
BlobContainerClient containerClient = premiumStorageBlobServiceClient.createBlobContainer(containerName);
containerClient.getBlobClient(blobName1)
.getBlockBlobClient()
.upload(DATA.getDefaultInputStream(), DATA.getDefaultDataSize());
containerClient.getBlobClient(blobName2)
.getBlockBlobClient()
.upload(DATA.getDefaultInputStream(), DATA.getDefaultDataSize());

Response<Void> response1 = batch.setBlobAccessTier(containerName, blobName1, AccessTier.SMART);
Response<Void> response2 = batch.setBlobAccessTier(containerName, blobName2, AccessTier.SMART);
premiumBatchClient.submitBatch(batch);

assertEquals(200, response1.getStatusCode());
assertEquals(200, response2.getStatusCode());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public class BlobBatchTestBase extends TestProxyTestBase {
protected BlobServiceClient primaryBlobServiceClient;
protected BlobServiceAsyncClient primaryBlobServiceAsyncClient;
protected BlobServiceClient versionedBlobServiceClient;
protected BlobServiceClient premiumStorageBlobServiceClient;

@Override
public void beforeTest() {
Expand All @@ -64,6 +65,7 @@ public void beforeTest() {
primaryBlobServiceClient = getServiceClient(ENVIRONMENT.getPrimaryAccount());
primaryBlobServiceAsyncClient = getServiceAsyncClient(ENVIRONMENT.getPrimaryAccount());
versionedBlobServiceClient = getServiceClient(ENVIRONMENT.getPrimaryAccount());
premiumStorageBlobServiceClient = getServiceClient(ENVIRONMENT.getPremiumFileAccount());
}

/**
Expand Down
2 changes: 1 addition & 1 deletion sdk/storage/azure-storage-blob/assets.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"AssetsRepo": "Azure/azure-sdk-assets",
"AssetsRepoPrefixPath": "java",
"TagPrefix": "java/storage/azure-storage-blob",
"Tag": "java/storage/azure-storage-blob_4ab10936db"
"Tag": "java/storage/azure-storage-blob_0f8f4263e8"
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public interface BlobPropertiesConstructorAccessor {
}

/**
* The method called from the static initializer of {@link BlobProperties} to set it's accessor.
* The method called from the static initializer of {@link BlobProperties} to set its accessor.
*
* @param accessor The {@link BlobProperties} accessor.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,12 @@ public final class BlobItemPropertiesInternal implements XmlSerializable<BlobIte
@Generated
private ArchiveStatus archiveStatus;

/*
* The SmartAccessTier property.
*/
@Generated
private AccessTier smartAccessTier;

/*
* The CustomerProvidedKeySha256 property.
*/
Expand Down Expand Up @@ -945,6 +951,28 @@ public BlobItemPropertiesInternal setArchiveStatus(ArchiveStatus archiveStatus)
return this;
}

/**
* Get the smartAccessTier property: The SmartAccessTier property.
*
* @return the smartAccessTier value.
*/
@Generated
public AccessTier getSmartAccessTier() {
return this.smartAccessTier;
}

/**
* Set the smartAccessTier property: The SmartAccessTier property.
*
* @param smartAccessTier the smartAccessTier value to set.
* @return the BlobItemPropertiesInternal object itself.
*/
@Generated
public BlobItemPropertiesInternal setSmartAccessTier(AccessTier smartAccessTier) {
this.smartAccessTier = smartAccessTier;
return this;
}

/**
* Get the customerProvidedKeySha256 property: The CustomerProvidedKeySha256 property.
*
Expand Down Expand Up @@ -1259,6 +1287,8 @@ public XmlWriter toXml(XmlWriter xmlWriter, String rootElementName) throws XMLSt
xmlWriter.writeBooleanElement("AccessTierInferred", this.accessTierInferred);
xmlWriter.writeStringElement("ArchiveStatus",
this.archiveStatus == null ? null : this.archiveStatus.toString());
xmlWriter.writeStringElement("SmartAccessTier",
this.smartAccessTier == null ? null : this.smartAccessTier.toString());
xmlWriter.writeStringElement("CustomerProvidedKeySha256", this.customerProvidedKeySha256);
xmlWriter.writeStringElement("EncryptionScope", this.encryptionScope);
xmlWriter.writeStringElement("AccessTierChangeTime", Objects.toString(this.accessTierChangeTime, null));
Expand Down Expand Up @@ -1382,6 +1412,9 @@ public static BlobItemPropertiesInternal fromXml(XmlReader xmlReader, String roo
} else if ("ArchiveStatus".equals(elementName.getLocalPart())) {
deserializedBlobItemPropertiesInternal.archiveStatus
= ArchiveStatus.fromString(reader.getStringElement());
} else if ("SmartAccessTier".equals(elementName.getLocalPart())) {
deserializedBlobItemPropertiesInternal.smartAccessTier
= AccessTier.fromString(reader.getStringElement());
} else if ("CustomerProvidedKeySha256".equals(elementName.getLocalPart())) {
deserializedBlobItemPropertiesInternal.customerProvidedKeySha256 = reader.getStringElement();
} else if ("EncryptionScope".equals(elementName.getLocalPart())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,12 @@ public interface BlobPropertiesInternal {
*/
Boolean isAccessTierInferred();

/**
* @return the tier of the blob. This is only set for Page blobs on a premium storage account or for Block blobs on
* blob storage or general purpose V2 account.
*/
AccessTier getSmartAccessTier();

/**
* @return the archive status of the blob. This is only for blobs on a blob storage and general purpose v2 account.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,11 @@ public Boolean isAccessTierInferred() {
return isAccessTierInferred;
}

@Override
public AccessTier getSmartAccessTier() {
return null;
}

Comment on lines +427 to +431
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks weird without context - maybe we should add a comment that says something like "Null because this property is set through BlobPropertiesConstructorProxy"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ibrandes I had to trace this, but this should return smartAccessTier. It took me a while to figure it out, but I'm going to make the change to the code. The public API remains unchanged, but the service returns smartAccessTier, so this should return a value.

@Override
public ArchiveStatus getArchiveStatus() {
return archiveStatus;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,11 @@ public Boolean isAccessTierInferred() {
return null;
}

@Override
public AccessTier getSmartAccessTier() {
return null;
}

@Override
public ArchiveStatus getArchiveStatus() {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ public Boolean isAccessTierInferred() {
return headers.isXMsAccessTierInferred();
}

@Override
public AccessTier getSmartAccessTier() {
return AccessTier.fromString(headers.getXMsSmartAccessTier());
}

@Override
public ArchiveStatus getArchiveStatus() {
return ArchiveStatus.fromString(headers.getXMsArchiveStatus());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,12 @@ public final class BlobsGetPropertiesHeaders {
@Generated
private String xMsEncryptionScope;

/*
* The x-ms-smart-access-tier property.
*/
@Generated
private String xMsSmartAccessTier;

/*
* The x-ms-tag-count property.
*/
Expand Down Expand Up @@ -366,6 +372,8 @@ public final class BlobsGetPropertiesHeaders {

private static final HttpHeaderName X_MS_ENCRYPTION_SCOPE = HttpHeaderName.fromString("x-ms-encryption-scope");

private static final HttpHeaderName X_MS_SMART_ACCESS_TIER = HttpHeaderName.fromString("x-ms-smart-access-tier");

private static final HttpHeaderName X_MS_TAG_COUNT = HttpHeaderName.fromString("x-ms-tag-count");

private static final HttpHeaderName X_MS_ACCESS_TIER_INFERRED
Expand Down Expand Up @@ -502,6 +510,7 @@ public BlobsGetPropertiesHeaders(HttpHeaders rawHeaders) {
this.contentLanguage = rawHeaders.getValue(HttpHeaderName.CONTENT_LANGUAGE);
this.xMsClientRequestId = rawHeaders.getValue(HttpHeaderName.X_MS_CLIENT_REQUEST_ID);
this.xMsEncryptionScope = rawHeaders.getValue(X_MS_ENCRYPTION_SCOPE);
this.xMsSmartAccessTier = rawHeaders.getValue(X_MS_SMART_ACCESS_TIER);
String xMsTagCount = rawHeaders.getValue(X_MS_TAG_COUNT);
if (xMsTagCount != null) {
this.xMsTagCount = Long.parseLong(xMsTagCount);
Expand Down Expand Up @@ -1231,6 +1240,28 @@ public BlobsGetPropertiesHeaders setXMsEncryptionScope(String xMsEncryptionScope
return this;
}

/**
* Get the xMsSmartAccessTier property: The x-ms-smart-access-tier property.
*
* @return the xMsSmartAccessTier value.
*/
@Generated
public String getXMsSmartAccessTier() {
return this.xMsSmartAccessTier;
}

/**
* Set the xMsSmartAccessTier property: The x-ms-smart-access-tier property.
*
* @param xMsSmartAccessTier the xMsSmartAccessTier value to set.
* @return the BlobsGetPropertiesHeaders object itself.
*/
@Generated
public BlobsGetPropertiesHeaders setXMsSmartAccessTier(String xMsSmartAccessTier) {
this.xMsSmartAccessTier = xMsSmartAccessTier;
return this;
}

/**
* Get the xMsTagCount property: The x-ms-tag-count property.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ public final class AccessTier extends ExpandableStringEnum<AccessTier> {
@Generated
public static final AccessTier COLD = fromString("Cold");

/**
* Static value Smart for AccessTier.
*/
@Generated
public static final AccessTier SMART = fromString("Smart");

/**
* Creates a new instance of AccessTier value.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ public final class ArchiveStatus extends ExpandableStringEnum<ArchiveStatus> {
@Generated
public static final ArchiveStatus REHYDRATE_PENDING_TO_COLD = fromString("rehydrate-pending-to-cold");

/**
* Static value rehydrate-pending-to-smart for ArchiveStatus.
*/
@Generated
public static final ArchiveStatus REHYDRATE_PENDING_TO_SMART = fromString("rehydrate-pending-to-smart");

/**
* Creates a new instance of ArchiveStatus value.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,26 @@ public BlobItemProperties setAccessTierInferred(Boolean accessTierInferred) {
return this;
}

/**
* Get the smartAccessTier property: The smartAccessTier property.
*
* @return the smartAccessTier value.
*/
public AccessTier getSmartAccessTier() {
return internalProperties.getSmartAccessTier();
}

/**
* Set the smartAccessTier property: The smartAccessTier property.
*
* @param smartAccessTier the smartAccessTier value to set.
* @return the BlobItemProperties object itself.
*/
public BlobItemProperties setSmartAccessTier(AccessTier smartAccessTier) {
internalProperties.setSmartAccessTier(smartAccessTier);
return this;
}

/**
* Get the archiveStatus property: Possible values include: 'rehydrate-pending-to-hot',
* 'rehydrate-pending-to-cool'.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,7 @@ public final class BlobProperties {
private final BlobPropertiesInternal internalProperties;

static {
BlobPropertiesConstructorProxy
.setAccessor(new BlobPropertiesConstructorProxy.BlobPropertiesConstructorAccessor() {
@Override
public BlobProperties create(BlobPropertiesInternal internalProperties) {
return new BlobProperties(internalProperties);
}
});
BlobPropertiesConstructorProxy.setAccessor(BlobProperties::new);
}

private BlobProperties(BlobPropertiesInternal internalProperties) {
Expand Down Expand Up @@ -67,6 +61,7 @@ private BlobProperties(BlobPropertiesInternal internalProperties) {
* @param accessTier Access tier of the blob.
* @param isAccessTierInferred Flag indicating if the access tier of the blob was inferred from properties of the
* blob.
* @param smartAccessTier The inferred smart access tier of the blob.
* @param archiveStatus Archive status of the blob.
* @param encryptionKeySha256 SHA256 of the customer provided encryption key used to encrypt the blob on the
* server.
Expand Down Expand Up @@ -125,6 +120,7 @@ public BlobProperties(final OffsetDateTime creationTime, final OffsetDateTime la
* @param accessTier Access tier of the blob.
* @param isAccessTierInferred Flag indicating if the access tier of the blob was inferred from properties of the
* blob.
* @param smartAccessTier The inferred smart access tier of the blob.
* @param archiveStatus Archive status of the blob.
* @param encryptionKeySha256 SHA256 of the customer provided encryption key used to encrypt the blob on the
* server.
Expand Down Expand Up @@ -193,6 +189,7 @@ public BlobProperties(final OffsetDateTime creationTime, final OffsetDateTime la
* @param accessTier Access tier of the blob.
* @param isAccessTierInferred Flag indicating if the access tier of the blob was inferred from properties of the
* blob.
* @param smartAccessTier The inferred smart access tier of the blob.
* @param archiveStatus Archive status of the blob.
* @param encryptionKeySha256 SHA256 of the customer provided encryption key used to encrypt the blob on the
* server.
Expand Down Expand Up @@ -259,6 +256,7 @@ public BlobProperties(final OffsetDateTime creationTime, final OffsetDateTime la
* @param accessTier Access tier of the blob.
* @param isAccessTierInferred Flag indicating if the access tier of the blob was inferred from properties of the
* blob.
* @param smartAccessTier The inferred smart access tier of the blob.
* @param archiveStatus Archive status of the blob.
* @param encryptionKeySha256 SHA256 of the customer provided encryption key used to encrypt the blob on the
* server.
Expand Down Expand Up @@ -331,6 +329,7 @@ public BlobProperties(final OffsetDateTime creationTime, final OffsetDateTime la
* @param accessTier Access tier of the blob.
* @param isAccessTierInferred Flag indicating if the access tier of the blob was inferred from properties of the
* blob.
* @param smartAccessTier The inferred smart access tier of the blob.
* @param archiveStatus Archive status of the blob.
* @param encryptionKeySha256 SHA256 of the customer provided encryption key used to encrypt the blob on the
* server.
Expand Down Expand Up @@ -697,6 +696,16 @@ public Boolean isAccessTierInferred() {
return internalProperties.isAccessTierInferred();
}

/**
* Gets the smart access tier of the blob.
*
* @return the tier of the blob. This is only set for Page blobs on a premium storage account or for Block blobs on
* blob storage or general purpose V2 account.
*/
public AccessTier getSmartAccessTier() {
return internalProperties.getSmartAccessTier();
}

/**
* Gets the archive status of the blob.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3225,4 +3225,18 @@ void containerNameEncodingOnGetBlobUrl() {
assertTrue(blobClient.getBlobUrl().contains(expectedEncodedContainerName));
}

@RequiredServiceVersion(clazz = BlobServiceVersion.class, min = "2026-02-06")
@Test
public void uploadStreamAccessTierSmart() {
bc = cc.getBlobClient(generateBlobName());
InputStream data = new ByteArrayInputStream(getRandomByteArray(Constants.KB));

BlobParallelUploadOptions options = new BlobParallelUploadOptions(data).setTier(AccessTier.SMART);
bc.uploadWithResponse(options, null, Context.NONE);

Response<BlobProperties> response = bc.getPropertiesWithResponse(null, null, Context.NONE);
assertEquals(AccessTier.SMART, response.getValue().getAccessTier());
assertNotNull(response.getValue().getSmartAccessTier());
}

}
Loading
Loading