Skip to content

Conversation

@mbhaskar
Copy link
Member

Introduction

To support sharding for SQLx, Dedicatedgateway team introduced a new request option called “ShardKey”. This should be enabled in the existing “DedicatedGatewayRequestOptions”. This will allow the customer to optionally specify a shard key to use the new sharding feature.

Specifying the shard key will help route the request to an instance that has cached data for this shard or bypass the SQLx cache if correlated instance is down. If the shard key is not specified, it will fall back to the default behavior, which is randomly selecting an instance to serve the request.

Changes

Added string field shardKey to DedicatedGatewayRequestOptions

validation:
Max Size = 72 bytes (size of GUID) or 36 characters (length of GUID)
Character Set Limitations: accepts alphanumeric and hyphen(-) charaters

This field will be passed as the header “x-ms-dedicatedgateway-shard-key” to the service.

Testing

  • Added tests to make sure this option is passed in header when provided
  • Manually Tested on a live sqlx account with sharding enabled

Note:
HTTP2 is required for the sharding feature. If HTTP1 and shard key are both set, shard key will be ignored.

Please add an informative description that covers that changes made by the pull request and link all relevant issues.

If an SDK is being regenerated based on a new swagger spec, a link to the pull request containing these swagger spec changes has been included above.

All SDK Contribution checklist:

  • The pull request does not introduce [breaking changes]
  • CHANGELOG is updated for new features, bug fixes or other significant changes.
  • I have read the contribution guidelines.

General Guidelines and Best Practices

  • Title of the pull request is clear and informative.
  • There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, see this page.

Testing Guidelines

  • Pull request includes test coverage for the included changes.

Copilot AI review requested due to automatic review settings January 23, 2026 22:04
@mbhaskar mbhaskar requested review from a team as code owners January 23, 2026 22:04
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request adds support for the sharding feature in the Dedicated Gateway by introducing a new shardKey field to DedicatedGatewayRequestOptions. This optional field allows customers to specify a shard key to route requests to instances with cached data for that shard, or bypass the SQLx cache if the correlated instance is down. Without a shard key, the request falls back to random instance selection.

Changes:

  • Added a shardKey string field to DedicatedGatewayRequestOptions with validation for alphanumeric characters and hyphens
  • Added the HTTP header constant DEDICATED_GATEWAY_PER_REQUEST_SHARD_KEY for propagating the shard key to the service
  • Updated request header logic in DocumentQueryExecutionContextBase and RxDocumentClientImpl to include the shard key header when specified
  • Added integration tests to verify the shard key header is correctly propagated for both query and read item operations

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/models/DedicatedGatewayRequestOptions.java Added shardKey field with getter/setter and validation logic for character set constraints
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/HttpConstants.java Added new HTTP header constant for dedicated gateway shard key
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/query/DocumentQueryExecutionContextBase.java Updated query request header creation to include shard key when present
sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/RxDocumentClientImpl.java Updated request header creation to include shard key when present
sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/RequestHeadersSpyWireTest.java Added tests for shard key header propagation and updated validation method to support both query and read item operations

requestHeaders.put(HttpConstants.HttpHeaders.DEDICATED_GATEWAY_PER_REQUEST_BYPASS_CACHE,
String.valueOf(cosmosQueryRequestOptions.getDedicatedGatewayRequestOptions().isIntegratedCacheBypassed()));
}
if(cosmosQueryRequestOptions.getDedicatedGatewayRequestOptions().getShardKey() != null) {
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

Missing space after the 'if' keyword. The codebase consistently uses 'if (' with a space (e.g., lines 276, 280 in this file, and lines 2014, 2018 in RxDocumentClientImpl.java). This should be 'if (' instead of 'if('.

Suggested change
if(cosmosQueryRequestOptions.getDedicatedGatewayRequestOptions().getShardKey() != null) {
if (cosmosQueryRequestOptions.getDedicatedGatewayRequestOptions().getShardKey() != null) {

Copilot uses AI. Check for mistakes.
headers.put(HttpConstants.HttpHeaders.DEDICATED_GATEWAY_PER_REQUEST_BYPASS_CACHE,
String.valueOf(options.getDedicatedGatewayRequestOptions().isIntegratedCacheBypassed()));
}
if(options.getDedicatedGatewayRequestOptions().getShardKey() != null) {
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

Missing space after the 'if' keyword. The codebase consistently uses 'if (' with a space (e.g., lines 2014, 2018 in this file, and lines 276, 280 in DocumentQueryExecutionContextBase.java). This should be 'if (' instead of 'if('.

Suggested change
if(options.getDedicatedGatewayRequestOptions().getShardKey() != null) {
if (options.getDedicatedGatewayRequestOptions().getShardKey() != null) {

Copilot uses AI. Check for mistakes.
DedicatedGatewayRequestOptions options) {
Map<String, String> headers = httpRequest.headers().toMap();
if (headers.get(HttpConstants.HttpHeaders.IS_QUERY) != null) {
if (headers.get(HttpConstants.HttpHeaders.IS_QUERY) != null || headers.get(HttpConstants.HttpHeaders.CONSISTENCY_LEVEL) != null) {
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

There are two spaces between CONSISTENCY_LEVEL and the comparison operator. This should be a single space for consistency with the rest of the codebase.

Suggested change
if (headers.get(HttpConstants.HttpHeaders.IS_QUERY) != null || headers.get(HttpConstants.HttpHeaders.CONSISTENCY_LEVEL) != null) {
if (headers.get(HttpConstants.HttpHeaders.IS_QUERY) != null || headers.get(HttpConstants.HttpHeaders.CONSISTENCY_LEVEL) != null) {

Copilot uses AI. Check for mistakes.
Comment on lines +349 to 367
@Test(groups = { "fast" }, timeOut = TIMEOUT)
public void readItemWithDedicatedGatewayShardKeyHeader() {
DedicatedGatewayRequestOptions dedicatedOptions = new DedicatedGatewayRequestOptions();
dedicatedOptions.setMaxIntegratedCacheStaleness(Duration.ofMinutes(1));
dedicatedOptions.setIntegratedCacheBypassed(true);
dedicatedOptions.setShardKey("shard-456");
CosmosItemRequestOptions cosmosItemRequestOptions = new CosmosItemRequestOptions();
cosmosItemRequestOptions.setDedicatedGatewayRequestOptions(dedicatedOptions);
cosmosItemRequestOptions.setCustomItemSerializer(CosmosItemSerializer.DEFAULT_SERIALIZER);
String documentLink = getDocumentLink();
client.clearCapturedRequests();
RequestOptions requestOptions = itemOptionsAccessor.toRequestOptions(cosmosItemRequestOptions);
requestOptions.setPartitionKey(new PartitionKey(DOCUMENT_ID));
client.readDocument(documentLink, requestOptions).block();
List<HttpRequest> requests = client.getCapturedRequests();
for (HttpRequest httpRequest : requests) {
validateRequestHasDedicatedGatewayHeaders(httpRequest, cosmosItemRequestOptions.getDedicatedGatewayRequestOptions());
}
}
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

Test coverage is needed for the validation logic in setShardKey. Consider adding tests for edge cases such as: null or empty string (should throw IllegalArgumentException), invalid characters (e.g., special characters, spaces), and maximum length validation (if the 36 character/72 byte limit mentioned in the PR description is implemented). This follows the pattern seen in the existing test file where validation tests exist for other fields (e.g., readItemWithMaxIntegratedCacheStalenessInNegative).

Copilot uses AI. Check for mistakes.
import java.time.Duration;

import static com.azure.cosmos.implementation.guava25.base.Preconditions.checkArgument;
import static com.azure.cosmos.implementation.guava25.base.Preconditions.checkNotNull;
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

The import checkNotNull is not used anywhere in this file. Consider removing this unused import to keep the code clean.

Suggested change
import static com.azure.cosmos.implementation.guava25.base.Preconditions.checkNotNull;

Copilot uses AI. Check for mistakes.
Comment on lines +115 to +119
public DedicatedGatewayRequestOptions setShardKey(String shardKey) {
checkArgument(StringUtils.isNotEmpty(shardKey), "shardKey must not be null or empty");
checkArgument(validateShardKey(shardKey), "shardKey contains invalid characters. Only alphanumeric and hyphen (-) are allowed.");
this.shardKey = shardKey;
return this;
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

The PR description mentions a size validation requirement: "Max Size = 72 bytes (size of GUID) or 36 characters (length of GUID)". However, the implementation only validates the character set but does not enforce the maximum length constraint. Consider adding a length check to ensure the shardKey does not exceed 36 characters or 72 bytes.

Copilot uses AI. Check for mistakes.
return this;
}

private boolean validateShardKey(String shardKey){
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

Missing space after the 'if' keyword. The codebase consistently uses 'if (' with a space, as seen throughout the file and in similar code (e.g., lines 276, 280 in DocumentQueryExecutionContextBase.java, and lines 2014, 2018 in RxDocumentClientImpl.java). This should be 'if (' instead of 'if('.

Suggested change
private boolean validateShardKey(String shardKey){
private boolean validateShardKey(String shardKey) {

Copilot uses AI. Check for mistakes.
Comment on lines +98 to +114
/**
* Gets the shard key value associated with the request in the Azure CosmosDB service to optionally specify a shard key
* to use the new sharding feature in dedicated gateway.
*
* @return shard key value
*/
public String getShardKey() {
return shardKey;
}

/**
* Sets the shard key value associated with the request in the Azure CosmosDB service to optionally specify a shard key
* to use the new sharding feature in dedicated gateway.
*
* @param shardKey shard key value
* @return this DedicatedGatewayRequestOptions
*/
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

The JavaDoc for the getter and setter methods should include a default value section, consistent with the pattern used for other methods in this class. For example, getMaxIntegratedCacheStaleness() and setMaxIntegratedCacheStaleness() both include "<p>Default value is null</p>". The shardKey field should follow the same pattern.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Contributor

API Change Check

APIView identified API level changes in this PR and created the following API reviews

com.azure:azure-cosmos

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants