[OpenSearch Migration] Phase 3: inferIndexToHit throws when VersionedIndices is unpopulated; write vs read/count paths resolve the index from divergent sources
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 970
- Forks
- 486
- Avg merge
- 3d 33m
- Merged PRs (30d)
- 170
Description
Summary
Surfaced while working on PR #36027 (#36026 VTL aggregation regression). In Phase 3 (OS-only, FEATURE_FLAG_OPEN_SEARCH_PHASE=3) the OpenSearch read/count path throws when the new VersionedIndices (OPENSEARCH_3X) rows are not populated, even though content was written successfully — because the write path and the read/count path resolve the target index from different sources.
Evidence
ContentFactoryIndexOperationsOS.inferIndexToHit (dotCMS/src/main/java/com/dotcms/content/index/opensearch/ContentFactoryIndexOperationsOS.java:360-385):
final Optional<VersionedIndices> optional = Try.of(() ->
APILocator.getVersionedIndicesAPI().loadDefaultVersionedIndices()).getOrElse(Optional.empty());
if (optional.isEmpty()){
throw new DotRuntimeException("Unable to load default versioned indices, falling back to default index");
}
Two problems:
-
Misleading message / no fallback. The message says "falling back to default index" but the code throws — it never falls back.
-
Divergent index resolution in Phase 3. Observed in an integration run (Phase 3):
- Write path (
addContentToIndex→ publish) resolved and wrote to the bootstrap content indexlive_<timestamp>(via the legacyIndiciesInfo/IndiciesAPI) — succeeded. - Read/count path (
isInodeIndexed→ESContentletAPIImpl.indexCount→ContentFactoryIndexOperationsOS.inferIndexToHit) usedVersionedIndicesAPI.loadDefaultVersionedIndices()(OPENSEARCH_3X), which was empty → threwDotRuntimeException: Unable to load default versioned indices, falling back to default index.
Stack:
ContentFactoryIndexOperationsOS.inferIndexToHit(ContentFactoryIndexOperationsOS.java:365) ContentFactoryIndexOperationsOS.getCountRequest(...:400) ContentFactoryIndexOperationsOS.indexCount(...:392) ESContentFactoryImpl.indexCount(ESContentFactoryImpl.java:1580) ESContentletAPIImpl.isInodeIndexed(ESContentletAPIImpl.java:9829) - Write path (
Nothing in the opensearch-upgrade test environment's bootstrap populates the OS VersionedIndices for the default content indices, so any Phase-3 read/count that flows through inferIndexToHit fails.
Impact
- Any Phase-3 code path that goes through
inferIndexToHit(e.g.isInodeIndexed, index counts) throws if OSVersionedIndiceshaven't been registered, while writes silently use a different (legacy) resolution source. This write/read divergence is a latent correctness/robustness gap for Phase 3.
Suggested direction
- Make
inferIndexToHitactually fall back (and/or unify index resolution so write and read/count paths use the same source), or ensure the bootstrap/activation flow populates OSVersionedIndiceswhenever content indices are created in Phase 3. Fix the misleading exception message regardless. - Likely related to the OS index-naming work on
fix/issue-35820-os-index-naming-suffix.
How it was found
Adding ContentSearchToolTest to OpenSearchUpgradeSuite (PR #36027) drove the full Phase-3 content lifecycle end-to-end and exposed this. That test has since been moved to the standard ES suite (MainSuite1b); OS-3.x aggregation coverage remains via OSSearchAPIImplIntegrationTest.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in dotCMS/src/main/java/com/dotcms/content/index/opensearch/ContentFactoryIndexOperationsOS.java, especially inferIndexToHit, and trace addContentToIndex alongside getCountRequest and indexCount. Run the OpenSearchUpgradeSuite or the cited ContentSearchToolTest flow to reproduce Phase 3 with unpopulated VersionedIndices. Done means read/count resolution no longer throws or diverges from writes, and the misleading fallback message is corrected.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend, search
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100