From f079a75ad584812b414f4452359dddc0c8ebfb8c Mon Sep 17 00:00:00 2001 From: Debdatta Kunda Date: Thu, 23 Apr 2026 22:27:34 -0700 Subject: [PATCH 1/5] Add SDK supported capabilities. --- .../SDKSupportedCapabilitiesTest.java | 74 +++++++++++++++++++ .../cosmos/implementation/HttpConstants.java | 15 ++-- 2 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/SDKSupportedCapabilitiesTest.java diff --git a/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/SDKSupportedCapabilitiesTest.java b/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/SDKSupportedCapabilitiesTest.java new file mode 100644 index 000000000000..cbee68c0b2d2 --- /dev/null +++ b/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/SDKSupportedCapabilitiesTest.java @@ -0,0 +1,74 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.cosmos.implementation; + +import org.testng.annotations.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class SDKSupportedCapabilitiesTest { + + @Test(groups = {"unit"}) + public void capabilityBitValues() { + assertThat(HttpConstants.SDKSupportedCapabilities.NONE).isEqualTo(0L); + assertThat(HttpConstants.SDKSupportedCapabilities.PARTITION_MERGE).isEqualTo(1L); + assertThat(HttpConstants.SDKSupportedCapabilities.CHANGE_FEED_WITH_START_TIME_POST_MERGE).isEqualTo(2L); + assertThat(HttpConstants.SDKSupportedCapabilities.THROUGHPUT_BUCKETING).isEqualTo(4L); + assertThat(HttpConstants.SDKSupportedCapabilities.IGNORE_UNKNOWN_RNTBD_TOKENS).isEqualTo(8L); + assertThat(HttpConstants.SDKSupportedCapabilities.CHANGE_FEED_TOKEN_WITH_GCN).isEqualTo(16L); + } + + @Test(groups = {"unit"}) + public void capabilityBitsDoNotOverlap() { + long[] capabilities = { + HttpConstants.SDKSupportedCapabilities.PARTITION_MERGE, + HttpConstants.SDKSupportedCapabilities.CHANGE_FEED_WITH_START_TIME_POST_MERGE, + HttpConstants.SDKSupportedCapabilities.THROUGHPUT_BUCKETING, + HttpConstants.SDKSupportedCapabilities.IGNORE_UNKNOWN_RNTBD_TOKENS, + HttpConstants.SDKSupportedCapabilities.CHANGE_FEED_TOKEN_WITH_GCN + }; + + long combined = 0; + for (long cap : capabilities) { + // Verify no overlap with previously combined flags + assertThat(combined & cap) + .as("Capability value %d overlaps with previously seen capabilities", cap) + .isEqualTo(0L); + combined |= cap; + } + } + + @Test(groups = {"unit"}) + public void supportedCapabilitiesIncludesExpectedFlags() { + long expected = + HttpConstants.SDKSupportedCapabilities.PARTITION_MERGE + | HttpConstants.SDKSupportedCapabilities.CHANGE_FEED_WITH_START_TIME_POST_MERGE + | HttpConstants.SDKSupportedCapabilities.IGNORE_UNKNOWN_RNTBD_TOKENS; + + assertThat(HttpConstants.SDKSupportedCapabilities.SUPPORTED_CAPABILITIES) + .isEqualTo(String.valueOf(expected)); + } + + @Test(groups = {"unit"}) + public void supportedCapabilitiesNone() { + assertThat(HttpConstants.SDKSupportedCapabilities.SUPPORTED_CAPABILITIES_NONE) + .isEqualTo(String.valueOf(HttpConstants.SDKSupportedCapabilities.NONE)); + assertThat(HttpConstants.SDKSupportedCapabilities.SUPPORTED_CAPABILITIES_NONE) + .isEqualTo("0"); + } + + @Test(groups = {"unit"}) + public void supportedCapabilitiesNumericValue() { + // PARTITION_MERGE (1) | CHANGE_FEED_WITH_START_TIME_POST_MERGE (2) | IGNORE_UNKNOWN_RNTBD_TOKENS (8) = 11 + assertThat(HttpConstants.SDKSupportedCapabilities.SUPPORTED_CAPABILITIES).isEqualTo("11"); + } + + @Test(groups = {"unit"}) + public void supportedCapabilitiesContainsIgnoreUnknownRntbdTokens() { + long value = Long.parseLong(HttpConstants.SDKSupportedCapabilities.SUPPORTED_CAPABILITIES); + assertThat(value & HttpConstants.SDKSupportedCapabilities.IGNORE_UNKNOWN_RNTBD_TOKENS) + .as("SUPPORTED_CAPABILITIES should include IGNORE_UNKNOWN_RNTBD_TOKENS flag") + .isNotEqualTo(0L); + } +} diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/HttpConstants.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/HttpConstants.java index 7eef40c6f689..346a0c490c22 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/HttpConstants.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/HttpConstants.java @@ -308,15 +308,20 @@ public static class A_IMHeaderValues { } public static class SDKSupportedCapabilities { - private static final long NONE = 0; // 0 - private static final long PARTITION_MERGE = 1; // 1 << 0 - - private static final long CHANGE_FEED_WITH_START_TIME_POST_MERGE = 2; // 1 << 1 + static final long NONE = 0; // 0 + static final long PARTITION_MERGE = 1; // 1 << 0 + static final long CHANGE_FEED_WITH_START_TIME_POST_MERGE = 1 << 1; + static final long THROUGHPUT_BUCKETING = 1 << 2; + static final long IGNORE_UNKNOWN_RNTBD_TOKENS = 1 << 3; + static final long CHANGE_FEED_TOKEN_WITH_GCN = 1 << 4; public static final String SUPPORTED_CAPABILITIES; public static final String SUPPORTED_CAPABILITIES_NONE; static { - SUPPORTED_CAPABILITIES = String.valueOf(PARTITION_MERGE | CHANGE_FEED_WITH_START_TIME_POST_MERGE); + SUPPORTED_CAPABILITIES = String.valueOf( + PARTITION_MERGE + | CHANGE_FEED_WITH_START_TIME_POST_MERGE + | IGNORE_UNKNOWN_RNTBD_TOKENS); SUPPORTED_CAPABILITIES_NONE = String.valueOf(NONE); } } From ae6f0e973f367a1f68b660e14e37431e5b23f161 Mon Sep 17 00:00:00 2001 From: Debdatta Kunda <87335885+kundadebdatta@users.noreply.github.com> Date: Tue, 28 Apr 2026 14:24:01 -0700 Subject: [PATCH 2/5] Code changes to plug in the sdk supported capabilities with the barrier requests. --- .../directconnectivity/BarrierRequestHelperTest.java | 2 ++ .../directconnectivity/BarrierRequestHelper.java | 3 +++ 2 files changed, 5 insertions(+) diff --git a/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/directconnectivity/BarrierRequestHelperTest.java b/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/directconnectivity/BarrierRequestHelperTest.java index 40d0350c7192..4aadc4b18e72 100644 --- a/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/directconnectivity/BarrierRequestHelperTest.java +++ b/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/directconnectivity/BarrierRequestHelperTest.java @@ -130,6 +130,8 @@ public void barrierDocumentReadNameBasedRequest() { assertThat(getTargetGlobalLsn(barrierRequest)).isEqualTo(10l); assertThat(getTargetLsn(barrierRequest)).isEqualTo(11l); assertThat(barrierRequest.getIsNameBased()).isEqualTo(true); + assertThat(getHeaderValue(barrierRequest, HttpConstants.HttpHeaders.SDK_SUPPORTED_CAPABILITIES)) + .isEqualTo(HttpConstants.SDKSupportedCapabilities.SUPPORTED_CAPABILITIES); } diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/BarrierRequestHelper.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/BarrierRequestHelper.java index 55a3534eeec1..038e8677b62d 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/BarrierRequestHelper.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/directconnectivity/BarrierRequestHelper.java @@ -81,6 +81,9 @@ public static Mono createAsync( } barrierLsnRequest.getHeaders().put(HttpConstants.HttpHeaders.X_DATE, Utils.nowAsRFC1123()); + barrierLsnRequest.getHeaders().put( + HttpConstants.HttpHeaders.SDK_SUPPORTED_CAPABILITIES, + HttpConstants.SDKSupportedCapabilities.SUPPORTED_CAPABILITIES); if (targetLsn != null && targetLsn > 0) { barrierLsnRequest.getHeaders().put(HttpConstants.HttpHeaders.TARGET_LSN, targetLsn.toString()); From 8c12ef0d8ef16849e69f0ce2700f93a23e3c1e26 Mon Sep 17 00:00:00 2001 From: Debdatta Kunda <87335885+kundadebdatta@users.noreply.github.com> Date: Tue, 28 Apr 2026 17:29:59 -0700 Subject: [PATCH 3/5] Improve SDKSupportedCapabilities documentation and consistency - Add '// Visible for testing' comment on package-private constants - Use 1 << 0 for PARTITION_MERGE for consistency with other bit flags - Add doc comment on IGNORE_UNKNOWN_RNTBD_TOKENS explaining its purpose Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../com/azure/cosmos/implementation/HttpConstants.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/HttpConstants.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/HttpConstants.java index 346a0c490c22..a1d311bdd089 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/HttpConstants.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/HttpConstants.java @@ -308,10 +308,14 @@ public static class A_IMHeaderValues { } public static class SDKSupportedCapabilities { - static final long NONE = 0; // 0 - static final long PARTITION_MERGE = 1; // 1 << 0 + // Visible for testing + static final long NONE = 0; + static final long PARTITION_MERGE = 1 << 0; static final long CHANGE_FEED_WITH_START_TIME_POST_MERGE = 1 << 1; static final long THROUGHPUT_BUCKETING = 1 << 2; + // Signals the backend that the SDK can safely handle unrecognized RNTBD transport tokens. + // Required for N-Region Synchronous Commit, where the backend returns new response tokens + // (e.g., GlobalNRegionCommittedGLSN) that older SDK versions would not recognize. static final long IGNORE_UNKNOWN_RNTBD_TOKENS = 1 << 3; static final long CHANGE_FEED_TOKEN_WITH_GCN = 1 << 4; From c9cc7d48c78c5e7fa84415d3e16d5724e851b11c Mon Sep 17 00:00:00 2001 From: Debdatta Kunda <87335885+kundadebdatta@users.noreply.github.com> Date: Tue, 28 Apr 2026 17:35:51 -0700 Subject: [PATCH 4/5] Add CHANGELOG entry for SDK supported capabilities propagation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- sdk/cosmos/azure-cosmos/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/cosmos/azure-cosmos/CHANGELOG.md b/sdk/cosmos/azure-cosmos/CHANGELOG.md index 89a22c2d1288..050068eb5336 100644 --- a/sdk/cosmos/azure-cosmos/CHANGELOG.md +++ b/sdk/cosmos/azure-cosmos/CHANGELOG.md @@ -3,6 +3,7 @@ ### 4.80.0-beta.1 (Unreleased) #### Features Added +* Added `IGNORE_UNKNOWN_RNTBD_TOKENS` SDK capability flag and propagated SDK supported capabilities to barrier requests, enabling N-Region Synchronous Commit to function correctly with backends that return new RNTBD response tokens. - See [PR 48965](https://github.com/Azure/azure-sdk-for-java/pull/48965) * Added support for change feed with `startFrom` point-in-time on merged partitions by enabling the `CHANGE_FEED_WITH_START_TIME_POST_MERGE` SDK capability. - See [PR 48752](https://github.com/Azure/azure-sdk-for-java/pull/48752) * Added new `readManyByPartitionKeys` API on `CosmosAsyncContainer` / `CosmosContainer` to bulk-query all documents matching a list of partition key values with better efficiency than issuing individual queries. See [PR 48801](https://github.com/Azure/azure-sdk-for-java/pull/48801) * Added `CosmosReadManyByPartitionKeysRequestOptions` - a dedicated request-options type for `readManyByPartitionKeys` that exposes `setContinuationToken(String)` for resuming previous invocations and `setMaxConcurrentBatchPrefetch(int)` to bound per-call prefetch parallelism. See [PR 48801](https://github.com/Azure/azure-sdk-for-java/pull/48801) From 73459912fceb5c422ae37c0e4c6b4560f5f7cf57 Mon Sep 17 00:00:00 2001 From: Debdatta Kunda <87335885+kundadebdatta@users.noreply.github.com> Date: Tue, 28 Apr 2026 22:03:35 -0700 Subject: [PATCH 5/5] Code changes to address review comments part-1. --- .../azure/cosmos/implementation/HttpConstants.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/HttpConstants.java b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/HttpConstants.java index a1d311bdd089..3a3dda5be6d0 100644 --- a/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/HttpConstants.java +++ b/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/HttpConstants.java @@ -309,15 +309,15 @@ public static class A_IMHeaderValues { public static class SDKSupportedCapabilities { // Visible for testing - static final long NONE = 0; - static final long PARTITION_MERGE = 1 << 0; - static final long CHANGE_FEED_WITH_START_TIME_POST_MERGE = 1 << 1; - static final long THROUGHPUT_BUCKETING = 1 << 2; + static final long NONE = 0L; + static final long PARTITION_MERGE = 1L << 0; + static final long CHANGE_FEED_WITH_START_TIME_POST_MERGE = 1L << 1; + static final long THROUGHPUT_BUCKETING = 1L << 2; // Signals the backend that the SDK can safely handle unrecognized RNTBD transport tokens. // Required for N-Region Synchronous Commit, where the backend returns new response tokens // (e.g., GlobalNRegionCommittedGLSN) that older SDK versions would not recognize. - static final long IGNORE_UNKNOWN_RNTBD_TOKENS = 1 << 3; - static final long CHANGE_FEED_TOKEN_WITH_GCN = 1 << 4; + static final long IGNORE_UNKNOWN_RNTBD_TOKENS = 1L << 3; + static final long CHANGE_FEED_TOKEN_WITH_GCN = 1L << 4; public static final String SUPPORTED_CAPABILITIES; public static final String SUPPORTED_CAPABILITIES_NONE;