Skip to content

[Gateway V1/V2]: Enable ReadConsistencyStrategy.#48787

Draft
jeet1995 wants to merge 11 commits intoAzure:mainfrom
jeet1995:squad/48094-readconsistency-header-propagation
Draft

[Gateway V1/V2]: Enable ReadConsistencyStrategy.#48787
jeet1995 wants to merge 11 commits intoAzure:mainfrom
jeet1995:squad/48094-readconsistency-header-propagation

Conversation

@jeet1995
Copy link
Copy Markdown
Member

@jeet1995 jeet1995 commented Apr 12, 2026

Issue

Fixes #48094

Summary

Enable ReadConsistencyStrategy across all connection modes — Direct (already working), Gateway V1 (compute gateway), and Gateway V2 (thin client proxy). Previously, RCS was only supported in Direct mode; Gateway mode warned and ignored the setting.

What changed

RNTBD header encoding — Added ReadConsistencyStrategy RNTBD token (ID 0x00F0, Byte type) so the thin client proxy can read the strategy from the binary request frame. Token values: Eventual=1, Session=2, LatestCommitted=3, GlobalStrong=4. Coordinated with proxy team (ADO PR #2031635).

Dual-header conflict resolution — Compute gateway rejects requests containing both x-ms-consistency-level and x-ms-cosmos-read-consistency-strategy headers. When RCS is non-DEFAULT, the SDK now strips x-ms-consistency-level so only the RCS header is sent. This applies to both client-level and request-level RCS paths.

Gateway store model side-effect fixRxGatewayStoreModel.applySessionToken() called RequestHelper.getReadConsistencyStrategyToUse() which had a side-effect of rewriting x-ms-consistency-level (e.g., LatestCommittedBoundedStaleness). The compute gateway then rejected because BoundedStaleness is stricter than the Session account default. Fixed by using a copy of the headers map for session token determination.

Client-side GLOBAL_STRONG validation — Replaced the Gateway-mode "warn and ignore" with a fail-fast BadRequestException when GLOBAL_STRONG is set on a non-Strong consistency account. Works across all connection modes.

Javadoc updateReadConsistencyStrategy javadoc now reflects support in Direct, Gateway, and thin client modes.

Key design decisions

Decision Rationale
RNTBD token type is Byte (not String) Proxy defines ReadConsistencyStrategy as a C++ enum (int). String type caused proxy to hang on frame deserialization.
Token ID 0x00F0 Next available after HubRegionProcessingOnly (0x00EF). Matches proxy PR #2031635.
NOT added to thinClientHeadersInOrderList Regular unordered RNTBD header — no special ordering needed for proxy.
Strip x-ms-consistency-level when RCS is set Compute gateway rejects dual headers. RCS takes precedence per design (see .NET SDK RequestInvokerHandler test: "ConsistencyLevel header should not be set when ReadConsistencyStrategy is used").
RxGatewayStoreModel uses header map copy Prevents getReadConsistencyStrategyToUse() side-effect from mutating the original request headers that go on the wire.
GLOBAL_STRONG validation is client-side Fail-fast at request time, not after round-trip to server. Same validation as RequestHelper.validateReadConsistencyStrategy() in Direct mode.

Files changed

Area File Change
RNTBD RntbdConstants.java Add RntbdReadConsistencyStrategy enum (Byte values) + ReadConsistencyStrategy header (0x00F0, Byte)
RNTBD RntbdRequestHeaders.java Getter + encoder mapping HTTP header string → RNTBD byte enum
Headers RxDocumentClientImpl.java Strip x-ms-consistency-level when RCS is set; replace warn with GLOBAL_STRONG validation
Headers RxGatewayStoreModel.java Use header map copy to prevent consistency-level rewrite side-effect
Interface IDocumentQueryClient.java Rename validateAndLogNonDefault...validateReadConsistencyStrategy
Callers ChangeFeedQueryImpl.java, DocumentQueryExecutionContextBase.java Update to new validation method
Javadoc ReadConsistencyStrategy.java Update supported modes
Changelog CHANGELOG.md Feature entry
Unit tests RntbdReadConsistencyStrategyHeaderTests.java (new) 10 tests: token encoding, round-trip, header constants
E2E tests ThinClientReadConsistencyStrategyE2ETest.java (new) 10 tests: all request option types through thin client proxy
E2E tests GatewayReadConsistencyStrategyE2ETest.java (new) 11 tests: all request option types through compute gateway

E2E test coverage

All 5 request option surfaces + client-level + validation:

Operation Thin Client (tc=true) Gateway V1
CosmosItemRequestOptions (LC, Eventual, Session) ✅✅✅ ✅✅✅
CosmosQueryRequestOptions (LC, Eventual) ✅✅ ✅✅
CosmosChangeFeedRequestOptions (LC)
CosmosReadManyRequestOptions (LC)
CosmosClientBuilder client-level (LC)
Write with RCS (forced to DEFAULT)
Both ConsistencyLevel + RCS (RCS wins)
GLOBAL_STRONG on Session account (rejected)

21/21 pass against swkrish-session (test4, Session, North Europe, serverless, thin-client-enabled federation cdb-ms-test4-northeurope1-fe1).

.NET SDK reference

PR #5685 — .NET SDK ReadConsistencyStrategy implementation. HTTP header name and enum values match. .NET test confirms: "ConsistencyLevel header should not be set when ReadConsistencyStrategy is used".

Proxy coordination

ADO PR #2031635 — "Add ReadConsistencyStrategy for Proxy". Merged and deployed to test4 federations. RNTBD header ID 0x00F0 and Byte enum values are aligned.


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.

Testing Guidelines

  • Pull request includes test coverage for the included changes.

…n modes (Azure#48094)

- Add ReadConsistencyStrategy RNTBD header (0x00F0, String) to RntbdConstants
  and RntbdRequestHeaders for thin client proxy propagation
- Replace Gateway-mode warn+ignore with client-side GLOBAL_STRONG validation
  that works across all modes (direct, gateway, thin client)
- Update ReadConsistencyStrategy javadoc to reflect all-modes support
- Add unit tests for RNTBD token encoding and round-trip
- Add E2E tests for thin client and compute gateway ReadConsistencyStrategy

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jeet1995 jeet1995 force-pushed the squad/48094-readconsistency-header-propagation branch from a3d4c0f to 26648a7 Compare April 16, 2026 00:36
jeet1995 and others added 6 commits April 15, 2026 21:33
…is set (Azure#48094)

RxGatewayStoreModel.applySessionToken() called RequestHelper.getReadConsistencyStrategyToUse()
which had a side-effect of rewriting x-ms-consistency-level header (e.g., LATEST_COMMITTED
mapped to BoundedStaleness). The compute gateway rejected this because BoundedStaleness is
stricter than the Session account default.

Fix: Use a copy of the headers map so the original x-ms-consistency-level is preserved.
Gateway/proxy now sees:
- x-ms-consistency-level: Session (original, unchanged)
- x-ms-cosmos-read-consistency-strategy: LatestCommitted (RCS intent)

Verified E2E: LATEST_COMMITTED, EVENTUAL, SESSION, client-level RCS all return 200.
GLOBAL_STRONG correctly throws BadRequestException on Session account.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…Azure#48094)

Compute gateway rejects requests containing both x-ms-consistency-level and
x-ms-cosmos-read-consistency-strategy headers. When RCS is non-DEFAULT, remove
the consistency-level header — RCS takes precedence.

Applied to both client-level and request-options-level RCS paths in
RxDocumentClientImpl.getRequestHeaders().

Verified E2E against test4 compute gateway (swkrish-session, Session account):
LATEST_COMMITTED, EVENTUAL, SESSION, client-level RCS all return 200.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…yte (Azure#48094)

The proxy expects ReadConsistencyStrategy as a Byte enum, not a String:
  Eventual=1, Session=2, LatestCommitted=3, GlobalStrong=4

With String type, the proxy couldn't parse the RNTBD frame and hung.
With Byte type, thin client reads work correctly through the proxy.

Added RntbdReadConsistencyStrategy enum to RntbdConstants matching
the proxy's ReadConsistencyStrategy.h enum values.

Verified E2E against test4 thin client proxy (swkrish-session):
SESSION, EVENTUAL, LATEST_COMMITTED all return 200 with tc=true.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…urations (Azure#48094)

Removed hardcoded database/container names. Tests now:
- Create a unique database and container in @BeforeClass
- Clean up in @afterclass
- Use TestConfigurations.HOST/MASTER_KEY from cosmos-v4.properties
- Use /pk as partition key path

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…zure#48094)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…t option types (Azure#48094)

Cover all 5 surfaces: ItemRequestOptions, QueryRequestOptions,
ChangeFeedRequestOptions, ReadManyRequestOptions, CosmosClientBuilder (client-level).
Plus write-ignored, GLOBAL_STRONG validation, and CL+RCS precedence tests.

Tests use dynamic database/container creation, TestConfigurations, serverless-safe.
Follows ThinClientTestBase pattern from PR Azure#47759.

Verified E2E: 21/21 PASS (10 thin client + 11 gateway V1) against
swkrish-session (test4, Session, North Europe).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jeet1995 jeet1995 changed the title [Cosmos] Validate ReadConsistencyStrategy header propagation in thin client mode (#48094) [Cosmos] Enable ReadConsistencyStrategy for Gateway V1 and thin client (Gateway V2) modes (#48094) Apr 16, 2026
@jeet1995 jeet1995 changed the title [Cosmos] Enable ReadConsistencyStrategy for Gateway V1 and thin client (Gateway V2) modes (#48094) [Gateway V1/V2]: Enable ReadConsistencyStrategy. Apr 16, 2026
Copy link
Copy Markdown
Member

@FabianMeiswinkel FabianMeiswinkel left a comment

Choose a reason for hiding this comment

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

LGTM

The Cosmos DB RP now rejects API version 2022-08-15 for accounts
with EnableNoSQLVectorSearch capability, requiring 2023-04-15 or later.

Error: 'Please use api version 2022-02-15-preview or 2023-04-15 or later'
ActivityId: 3e0f30d8-548a-408f-9827-09c3b81a7166

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jeet1995
Copy link
Copy Markdown
Member Author

/azp run java - cosmos - tests

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

Verifying that the API version rejection was caused by EnableNoSQLVectorSearch.
This commit will be reverted after pipeline verification.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jeet1995
Copy link
Copy Markdown
Member Author

/azp run java - cosmos - tests

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

jeet1995 and others added 2 commits April 16, 2026 12:30
…QLVectorSearch (Azure#48094)

Cosmos DB RP now requires API version 2023-04-15+ for accounts with
EnableNoSQLVectorSearch capability. Confirmed by testing:
- 2022-08-15 + EnableNoSQLVectorSearch = 400 BadRequest
- 2022-08-15 without EnableNoSQLVectorSearch = passes
- 2023-04-15 + EnableNoSQLVectorSearch = passes

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

[FEATURE REQ] [Thin Client] Validate ReadConsistencyStrategy header propagation in thin client mode

2 participants