Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
1d0324b
Regenerate azure-storage-blob from updated swagger spec for STG105 Da…
browndav-msft Jul 10, 2026
f621d73
Implement Data Locality getLayout API for STG105 in azure-storage-blob
browndav-msft Jul 13, 2026
d75a76d
Add tests for getLayout API in azure-storage-blob (STG105)
browndav-msft Jul 13, 2026
5fc7ad8
Add implementation notes for STG105 Data Locality getLayout API
browndav-msft Jul 13, 2026
ec7526c
Fix BlobLayoutInfo missing blob-content fields and async test bug
browndav-msft Jul 13, 2026
f1723e8
Fix BlobTestBase afterTest cleanup client ignoring AZURE_LIVE_TEST_SE…
browndav-msft Jul 13, 2026
1f98d73
Update azure-storage-blob assets tag for STG105 getLayout recordings
browndav-msft Jul 13, 2026
1c5ccb2
Add generic AutoRefreshingCache to azure-storage-common (STG105)
browndav-msft Jul 14, 2026
ac33c76
Add tests for AutoRefreshingCache (STG105)
browndav-msft Jul 14, 2026
f5a85c5
Add DataLocalityPolicy to azure-storage-common (STG105)
browndav-msft Jul 14, 2026
8ec4109
Add tests for DataLocalityPolicy (STG105)
browndav-msft Jul 14, 2026
f506a07
Add enableDataLocality option to BlobDownloadToFileOptions and BlobIn…
browndav-msft Jul 14, 2026
ecc2e05
Add BlobLayoutCacheValue and BlobLayoutRangeResolver for data localit…
browndav-msft Jul 14, 2026
ca147a9
Add tests for BlobLayoutCacheValue and BlobLayoutRangeResolver
browndav-msft Jul 14, 2026
86b51ef
Wire DataLocalityPolicy and layout cache into Blob download paths
browndav-msft Jul 14, 2026
96ad0aa
Add getLayout and data locality wiring for DataLake file client
browndav-msft Jul 14, 2026
bdc049f
Add end-to-end tests for data locality download/stream wiring
browndav-msft Jul 14, 2026
db17b6c
Add CHANGELOG entries for STG105 data locality feature
browndav-msft Jul 14, 2026
1f3a54e
Update STG105 data locality implementation notes for full feature
browndav-msft Jul 14, 2026
7ad1e35
Add tests for DataLake getLayout and data locality wiring
browndav-msft Jul 14, 2026
8bf20d5
Consolidate STG105 tests into shared per-client test classes
browndav-msft Jul 14, 2026
70eb208
Add wiring-level E2E test proving real per-chunk endpoint routing
browndav-msft Jul 14, 2026
bc25ab4
Close remaining .NET getLayout test-matrix gaps
browndav-msft Jul 14, 2026
8795bc6
Close remaining .NET DataLake getLayout test-matrix gaps
browndav-msft Jul 14, 2026
7c24954
Finish STG105 range-assertion fixes, close discoverability gap, run S…
browndav-msft Jul 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
6 changes: 6 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,12 @@
## 12.36.0-beta.1 (Unreleased)

### Features Added
- Added support for service version 2027-03-07.
- Added data locality support: `BlobClientBase`/`BlobAsyncClientBase.getLayout` returns a blob's layout (byte-range
to endpoint mapping), and a new `enableDataLocality` option on `BlobDownloadToFileOptions`/`BlobInputStreamOptions`
opts `downloadToFileWithResponse`/`openInputStream` into routing range downloads to the optimal endpoint for the
chunk being read, based on the blob's layout. This is a performance optimization only; the bytes returned are
identical whether or not it is enabled, and it is a no-op unless the service indicates a layout is available.

### Breaking Changes

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_447cc62a15"
"Tag": "java/storage/azure-storage-blob_dfdc202e2d"
}

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) AutoRest Code Generator.

package com.azure.storage.blob.implementation.models;

import com.azure.core.annotation.Fluent;
import com.azure.core.annotation.Generated;
import com.azure.xml.XmlReader;
import com.azure.xml.XmlSerializable;
import com.azure.xml.XmlToken;
import com.azure.xml.XmlWriter;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;

/**
* The BlobLayout model.
*/
@Fluent
public final class BlobLayout implements XmlSerializable<BlobLayout> {
/*
* The Ranges property.
*/
@Generated
private BlobLayoutRanges ranges;

/*
* The Endpoints property.
*/
@Generated
private BlobLayoutEndpoints endpoints;

/*
* The continuation marker used for this request.
*/
@Generated
private String marker;

/*
* If the number of ranges exceeds MaxResults, a NextMarker is returned for use in subsequent requests to continue
* listing.
*/
@Generated
private String nextMarker;

/*
* The maximum number of ranges to return per request.
*/
@Generated
private Integer maxResults;

/**
* Creates an instance of BlobLayout class.
*/
@Generated
public BlobLayout() {
}

/**
* Get the ranges property: The Ranges property.
*
* @return the ranges value.
*/
@Generated
public BlobLayoutRanges getRanges() {
return this.ranges;
}

/**
* Set the ranges property: The Ranges property.
*
* @param ranges the ranges value to set.
* @return the BlobLayout object itself.
*/
@Generated
public BlobLayout setRanges(BlobLayoutRanges ranges) {
this.ranges = ranges;
return this;
}

/**
* Get the endpoints property: The Endpoints property.
*
* @return the endpoints value.
*/
@Generated
public BlobLayoutEndpoints getEndpoints() {
return this.endpoints;
}

/**
* Set the endpoints property: The Endpoints property.
*
* @param endpoints the endpoints value to set.
* @return the BlobLayout object itself.
*/
@Generated
public BlobLayout setEndpoints(BlobLayoutEndpoints endpoints) {
this.endpoints = endpoints;
return this;
}

/**
* Get the marker property: The continuation marker used for this request.
*
* @return the marker value.
*/
@Generated
public String getMarker() {
return this.marker;
}

/**
* Set the marker property: The continuation marker used for this request.
*
* @param marker the marker value to set.
* @return the BlobLayout object itself.
*/
@Generated
public BlobLayout setMarker(String marker) {
this.marker = marker;
return this;
}

/**
* Get the nextMarker property: If the number of ranges exceeds MaxResults, a NextMarker is returned for use in
* subsequent requests to continue listing.
*
* @return the nextMarker value.
*/
@Generated
public String getNextMarker() {
return this.nextMarker;
}

/**
* Set the nextMarker property: If the number of ranges exceeds MaxResults, a NextMarker is returned for use in
* subsequent requests to continue listing.
*
* @param nextMarker the nextMarker value to set.
* @return the BlobLayout object itself.
*/
@Generated
public BlobLayout setNextMarker(String nextMarker) {
this.nextMarker = nextMarker;
return this;
}

/**
* Get the maxResults property: The maximum number of ranges to return per request.
*
* @return the maxResults value.
*/
@Generated
public Integer getMaxResults() {
return this.maxResults;
}

/**
* Set the maxResults property: The maximum number of ranges to return per request.
*
* @param maxResults the maxResults value to set.
* @return the BlobLayout object itself.
*/
@Generated
public BlobLayout setMaxResults(Integer maxResults) {
this.maxResults = maxResults;
return this;
}

@Generated
@Override
public XmlWriter toXml(XmlWriter xmlWriter) throws XMLStreamException {
return toXml(xmlWriter, null);
}

@Generated
@Override
public XmlWriter toXml(XmlWriter xmlWriter, String rootElementName) throws XMLStreamException {
rootElementName = rootElementName == null || rootElementName.isEmpty() ? "BlobLayout" : rootElementName;
xmlWriter.writeStartElement(rootElementName);
xmlWriter.writeXml(this.ranges, "Ranges");
xmlWriter.writeXml(this.endpoints, "Endpoints");
xmlWriter.writeStringElement("Marker", this.marker);
xmlWriter.writeStringElement("NextMarker", this.nextMarker);
xmlWriter.writeNumberElement("MaxResults", this.maxResults);
return xmlWriter.writeEndElement();
}

/**
* Reads an instance of BlobLayout from the XmlReader.
*
* @param xmlReader The XmlReader being read.
* @return An instance of BlobLayout if the XmlReader was pointing to an instance of it, or null if it was pointing
* to XML null.
* @throws XMLStreamException If an error occurs while reading the BlobLayout.
*/
@Generated
public static BlobLayout fromXml(XmlReader xmlReader) throws XMLStreamException {
return fromXml(xmlReader, null);
}

/**
* Reads an instance of BlobLayout from the XmlReader.
*
* @param xmlReader The XmlReader being read.
* @param rootElementName Optional root element name to override the default defined by the model. Used to support
* cases where the model can deserialize from different root element names.
* @return An instance of BlobLayout if the XmlReader was pointing to an instance of it, or null if it was pointing
* to XML null.
* @throws XMLStreamException If an error occurs while reading the BlobLayout.
*/
@Generated
public static BlobLayout fromXml(XmlReader xmlReader, String rootElementName) throws XMLStreamException {
String finalRootElementName
= rootElementName == null || rootElementName.isEmpty() ? "BlobLayout" : rootElementName;
return xmlReader.readObject(finalRootElementName, reader -> {
BlobLayout deserializedBlobLayout = new BlobLayout();
while (reader.nextElement() != XmlToken.END_ELEMENT) {
QName elementName = reader.getElementName();

if ("Ranges".equals(elementName.getLocalPart())) {
deserializedBlobLayout.ranges = BlobLayoutRanges.fromXml(reader, "Ranges");
} else if ("Endpoints".equals(elementName.getLocalPart())) {
deserializedBlobLayout.endpoints = BlobLayoutEndpoints.fromXml(reader, "Endpoints");
} else if ("Marker".equals(elementName.getLocalPart())) {
deserializedBlobLayout.marker = reader.getStringElement();
} else if ("NextMarker".equals(elementName.getLocalPart())) {
deserializedBlobLayout.nextMarker = reader.getStringElement();
} else if ("MaxResults".equals(elementName.getLocalPart())) {
deserializedBlobLayout.maxResults = reader.getNullableElement(Integer::parseInt);
} else {
reader.skipElement();
}
}

return deserializedBlobLayout;
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) AutoRest Code Generator.

package com.azure.storage.blob.implementation.models;

import com.azure.core.annotation.Fluent;
import com.azure.core.annotation.Generated;
import com.azure.xml.XmlReader;
import com.azure.xml.XmlSerializable;
import com.azure.xml.XmlToken;
import com.azure.xml.XmlWriter;
import java.util.ArrayList;
import java.util.List;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;

/**
* The BlobLayoutEndpoints model.
*/
@Fluent
public final class BlobLayoutEndpoints implements XmlSerializable<BlobLayoutEndpoints> {
/*
* The Endpoint property.
*/
@Generated
private List<BlobLayoutEndpointsEndpointItem> endpoint = new ArrayList<>();

/**
* Creates an instance of BlobLayoutEndpoints class.
*/
@Generated
public BlobLayoutEndpoints() {
}

/**
* Get the endpoint property: The Endpoint property.
*
* @return the endpoint value.
*/
@Generated
public List<BlobLayoutEndpointsEndpointItem> getEndpoint() {
return this.endpoint;
}

/**
* Set the endpoint property: The Endpoint property.
*
* @param endpoint the endpoint value to set.
* @return the BlobLayoutEndpoints object itself.
*/
@Generated
public BlobLayoutEndpoints setEndpoint(List<BlobLayoutEndpointsEndpointItem> endpoint) {
this.endpoint = endpoint;
return this;
}

@Generated
@Override
public XmlWriter toXml(XmlWriter xmlWriter) throws XMLStreamException {
return toXml(xmlWriter, null);
}

@Generated
@Override
public XmlWriter toXml(XmlWriter xmlWriter, String rootElementName) throws XMLStreamException {
rootElementName = rootElementName == null || rootElementName.isEmpty() ? "Endpoints" : rootElementName;
xmlWriter.writeStartElement(rootElementName);
if (this.endpoint != null) {
for (BlobLayoutEndpointsEndpointItem element : this.endpoint) {
xmlWriter.writeXml(element, "Endpoint");
}
}
return xmlWriter.writeEndElement();
}

/**
* Reads an instance of BlobLayoutEndpoints from the XmlReader.
*
* @param xmlReader The XmlReader being read.
* @return An instance of BlobLayoutEndpoints if the XmlReader was pointing to an instance of it, or null if it was
* pointing to XML null.
* @throws XMLStreamException If an error occurs while reading the BlobLayoutEndpoints.
*/
@Generated
public static BlobLayoutEndpoints fromXml(XmlReader xmlReader) throws XMLStreamException {
return fromXml(xmlReader, null);
}

/**
* Reads an instance of BlobLayoutEndpoints from the XmlReader.
*
* @param xmlReader The XmlReader being read.
* @param rootElementName Optional root element name to override the default defined by the model. Used to support
* cases where the model can deserialize from different root element names.
* @return An instance of BlobLayoutEndpoints if the XmlReader was pointing to an instance of it, or null if it was
* pointing to XML null.
* @throws XMLStreamException If an error occurs while reading the BlobLayoutEndpoints.
*/
@Generated
public static BlobLayoutEndpoints fromXml(XmlReader xmlReader, String rootElementName) throws XMLStreamException {
String finalRootElementName
= rootElementName == null || rootElementName.isEmpty() ? "Endpoints" : rootElementName;
return xmlReader.readObject(finalRootElementName, reader -> {
BlobLayoutEndpoints deserializedBlobLayoutEndpoints = new BlobLayoutEndpoints();
while (reader.nextElement() != XmlToken.END_ELEMENT) {
QName elementName = reader.getElementName();

if ("Endpoint".equals(elementName.getLocalPart())) {
deserializedBlobLayoutEndpoints.endpoint
.add(BlobLayoutEndpointsEndpointItem.fromXml(reader, "Endpoint"));
} else {
reader.skipElement();
}
}

return deserializedBlobLayoutEndpoints;
});
}
}
Loading
Loading