Exempt server-injected preferences from strict weighted routing check… - #22571
Conversation
PR Reviewer Guide 🔍(Review updated until commit 2f4bc39)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Latest suggestions up to bf5b882
Previous suggestionsSuggestions up to commit 301879c
|
|
❌ Gradle check result for 301879c: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
301879c to
f165103
Compare
|
Persistent review updated to latest commit f165103 |
f165103 to
bf5b882
Compare
|
Persistent review updated to latest commit bf5b882 |
|
❌ Gradle check result for bf5b882: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
… and scope them per index OperationRouting#searchShards injects a search preference server-side for certain index types when the caller supplies none: _primary for remote snapshot indices and _primary_first for writable warm indices (behind WRITABLE_WARM_INDEX_EXPERIMENTAL_FLAG). This causes two problems: 1. The injected preference is assigned to the caller-supplied preference variable inside the per-shard loop, so in a multi-index search it leaks into every index processed afterwards. A search spanning a remote snapshot (or warm) index and regular indices silently routes the regular indices with _primary/_primary_first as well, defeating replica load-balancing and zone-aware routing for those indices. 2. checkPreferenceBasedRoutingAllowed cannot distinguish the engine's own injected preference from a caller-supplied one. When a restricted preference is injected while strict weighted shard routing is active (WeightedRoutingMetadata present and cluster.routing.weighted.strict), the server rejects its own routing decision with PreferenceBasedSearchNotAllowedException (HTTP 403) and the search fails even though the caller never set a preference. Distributions that restrict PRIMARY_FIRST hit this on every warm-index search on weighted-routing clusters. Fix: compute an effective preference per shard instead of mutating the request-level preference, track whether it was server-injected, and skip the strict weighted routing restriction check for server-injected preferences. The check exists to stop callers from bypassing weighted shard routing; it should not apply to the engine's own routing decisions. Signed-off-by: Piyush Kumar <piykumab@amazon.com>
bf5b882 to
2f4bc39
Compare
|
Persistent review updated to latest commit 2f4bc39 |
|
❌ Gradle check result for 2f4bc39: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
Description
OperationRouting#searchShardsinjects a search preference server-side for certain index types when thecaller supplies none:
_primaryfor remote snapshot indices and_primary_firstfor writable warmindices (behind
WRITABLE_WARM_INDEX_EXPERIMENTAL_FLAG). This causes two problems:Problem 1 — injected preference leaks across indices. The injected preference is assigned to the
caller-supplied preference variable inside the per-shard loop, so in a multi-index search it leaks into
every index processed afterwards. A search spanning a remote snapshot (or warm) index and regular indices
silently routes the regular indices with
_primary/_primary_firstas well, defeating replicaload-balancing and zone-aware routing for those indices. Since
computeTargetedShardsreturns aHashSet, which index "wins" is iteration-order dependent, making routing non-deterministic.Problem 2 — the server rejects its own routing decision.
checkPreferenceBasedRoutingAllowedcannotdistinguish the engine's own injected preference from a caller-supplied one. When a restricted preference
is injected while strict weighted shard routing is active (
WeightedRoutingMetadatapresent andcluster.routing.weighted.strict=true), the server rejects its own routing decision withPreferenceBasedSearchNotAllowedException(HTTP 403) and the search fails even though the caller neverset a preference. Distributions that restrict
PRIMARY_FIRSThit this on every warm-index search onweighted-routing clusters.
Solution
server-injected preferences are scoped to the index they were injected for (fixes Problem 1).
for server-injected preferences (fixes Problem 2). The check exists to stop callers from bypassing
weighted shard routing; it should not apply to the engine's own routing decisions. All three server
injections (
_primaryfor remote snapshot,_primary_firstfor writable warm,_search_replicaforsearch-only replicas) are treated uniformly.
serverInjectedPreference = falseand hit therestriction check exactly as before.
Testing
testServerInjectedPreferenceDoesNotLeakAcrossIndices— reproduces Problem 1; fails onmainwithoutthis fix (
AssertionError: All shard copies should be returned for a regular index), passes with it.testStrictWeightedRoutingExemptsOnlyServerInjectedPreferences— pins both sides of the exemptiondirectly: a caller-supplied restricted preference still throws
PreferenceBasedSearchNotAllowedException; the same preference passes when server-injected.testWarmIndexSearchNotBlockedByStrictWeightedRouting— end-to-end: warm index + zero-weight zone +cluster.routing.weighted.strict=true+ no caller preference succeeds.OperationRoutingTestsandSearchWeightedRoutingITpass;:server:precommitpasses.Note: the earlier gradle-check failure was
Netty4HttpRequestSizeLimitIT.testLimitsInFlightRequests, aknown flaky test (#18875) unrelated to this change.
Related Issues
Flaky test seen in CI on this PR: #18875 (unrelated to this change).
Check List
created, if applicable.
created, if applicable.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0
license.
For more information on following Developer Certificate of Origin and signing off your commits, please
check
[here](https://github.com/opensearch-project/OpenSearch/blob/main/CONTRIBUTING.md#developer-certificate-o
f-origin).