task(IndexAPI) Migrate IndexAPI to OpenSearch Part2 Refs #34728#34916
task(IndexAPI) Migrate IndexAPI to OpenSearch Part2 Refs #34728#34916fabrizzio-dotCMS wants to merge 17 commits intomainfrom
Conversation
|
@claude review this PR |
| public class VersionedIndicesAPIImpl implements VersionedIndicesAPI { | ||
|
|
||
| private static final SimpleDateFormat TIMESTAMP_FORMATTER = new SimpleDateFormat("yyyyMMddHHmmss"); | ||
| final SimpleDateFormat timestampFormatter = new SimpleDateFormat("yyyyMMddHHmmss"); |
There was a problem hiding this comment.
SimpleDateFormat is not thread safe in use. This is a single bean that could be called by separate threads. Use DateTimeFormatter.ofPattern("yyyyMMddHHmmss") instead.
| "OpenSearch Connection Attempt #" + (i + 1) + ": " + e.getMessage()); | ||
| } | ||
| DateUtil.sleep(Config.getIntProperty("OS_CONNECTION_TIMEOUT", 5) * 1000); | ||
| DateUtil.sleep(IndexConfigHelper.getInt(OSIndexProperty.CONNECTION_TIMEOUT, 5) * 1000); |
There was a problem hiding this comment.
OSIndexProperty.CONNECTION_TIMEOUT has conflicting semantics. In the provider it means "HTTP timeout in ms" (default 10000). In waitUtilIndexReady() it means "retry sleep in seconds" (default 5, multiplied by ×1000). If someone sets OS_CONNECTION_TIMEOUT=30000, the retry loop sleeps 8.3 hours.
Fix: Create a separate CONNECTION_RETRY_SLEEP_SECONDS property.
| * on the active feature flags:</p> | ||
| * <ul> | ||
| * <li><strong>Read operations</strong> — routed to {@link OSIndexAPIImpl} when | ||
| * {@code FEATURE_FLAG_OPEN_SEARCH_READ} is enabled, otherwise to {@link ESIndexAPI}.</li> |
There was a problem hiding this comment.
Make sure Javadoc is updated with changes. Let claude verify the changes are in sync.
Summary
Replaces the two binary feature flags (
FEATURE_FLAG_OPEN_SEARCH_WRITE/FEATURE_FLAG_OPEN_SEARCH_READ) with a single integer phase flag (FEATURE_FLAG_OPEN_SEARCH_PHASE, ordinal 0–3) that models the full ES → OpenSearch migration lifecycle. Implements the real routing logic inIndexAPIImplandESContentFactoryImplso read/write operations are dispatched to the correct backend based on the active phase, with ES remaining authoritative until phase 3.Changes
Config & Feature Flags
FEATURE_FLAG_OPEN_SEARCH_PHASE(int 0–3)IndexConfigHelper— central phase-decision helper exposingisMigrationNotStarted(),isDualWrite(),isReadEnabled(),isMigrationComplete()OSIndexPropertyenum — single source of truth for OS config keys with automatic ES fallback resolutionRouting
IndexAPIImpl: implemented full phase-aware routing — reads go to OS at phase 2+, writes dual-write at phases 1–2, OS-only at phase 3ESContentFactoryImpl: content search operations (indexSearch,indexCount,indexSearchScroll,createScrollQuery,findContentletsByHost) now routed throughindexOperationsDelegate()based on active phaseAnnotation cleanup
@IndexMetadata→@IndexRouter; removedIndexEngineenum andcurrentlySupports()attribute (replaced by phase-based routing)Structural cleanup
removeClusterIdFromNamepromoted todefaultmethod onIndexAPIinterface; removed fromESIndexAPIIndexSourceHelperdeletedContentletIndexAPIImpl: de-static'dqueueApi/esIndexApifields; madeobjectMapperfinalTests
MigrationPhaseTest— covers all four phases, boundary conditions (missing flag, out-of-range ordinals), and static helpers onIndexConfigHelperOpenSearchUpgradeSuiteTesting
FEATURE_FLAG_OPEN_SEARCH_PHASE=0→ all traffic goes to ES (default behavior, no regression)FEATURE_FLAG_OPEN_SEARCH_PHASE=1→ writes go to both ES and OS; reads still from ESFEATURE_FLAG_OPEN_SEARCH_PHASE=2→ writes go to both; reads from OSFEATURE_FLAG_OPEN_SEARCH_PHASE=3→ all traffic to OS onlyMigrationPhaseTestvia./mvnw verify -pl :dotcms-integration -Dcoreit.test.skip=false -Dit.test=MigrationPhaseTest