task(ContentletIndexAPIImpl Abstraction layers) Refs: #34938#35103
task(ContentletIndexAPIImpl Abstraction layers) Refs: #34938#35103
Conversation
|
Claude finished @fabrizzio-dotCMS's task in 2m 58s —— View job PR Review
Issues Found1. Partial dual-write on first-provider failure — All write methods iterate providers in order and call sequentially. If ES throws, OS never executes (or vice versa in phase 3 rollback scenarios). During phases 1/2 this silently diverges the two indexes with no compensation or rollback: public void writeChecked(final ThrowingConsumer<T> action) throws Exception {
for (final T impl : writeProviders()) {
action.accept(impl); // exception here skips remaining providers
}
}Same applies to 2. ES uses QueryStringQuery.of(qs -> qs.query("contenttype:" + structureName.toLowerCase()))
3. final CreateIndexStatus status = osIndexAPI.createIndex(indexName, settings, shards);
int i = 0;
while (!status.acknowledged()) { // status is immutable; never changes
DateUtil.sleep(100);
if (i++ > 300) {
throw new IOException("OS index creation timed out for: " + indexName);
}
}If 4. The ES 5. private static final ObjectMapper MAPPER = new ObjectMapper(); // line 46
6. if (response.errors()) {
Logger.error(this,
"OS bulk putToIndex: errors in response for "
+ osReq.operations.size() + " operations");
}ES version ( 7.
8. Settings failure is caught and logged; the mapping load is not: try {
settings = JsonUtil.getJsonFileContentAsString(OS_SETTINGS_FILE);
} catch (Exception e) { Logger.error(...); } // guarded
final String mapping = JsonUtil.getJsonFileContentAsString(CONTENT_MAPPING_FILE); // unguardedIf |
wezell
left a comment
There was a problem hiding this comment.
Looks great. I added nit-picking comments that you can respond to or not depending on how you feel. Good stuff.
Summary
Introduces the vendor-neutral write-side abstraction layer for the ES → OpenSearch migration. Extracts all bulk-write and mapping operations from
ContentletIndexAPIImplinto provider-specific implementations behind a genericPhaseRouter<T>, completing the dual-write infrastructure needed for migration phases 1–3.Changes
New abstractions (vendor-neutral contracts)
ContentletIndexOperations— write-side interface: bulk requests, bulk processor, index lifecycle, delete-by-content-typeIndexBulkRequest,IndexBulkProcessor,IndexBulkListener,IndexBulkItemResult— DTOs replacing ES/OS vendor types in public APIsIndexMappingRestOperations— mapping REST contract (putMapping,getMapping,getFieldMappingAsMap)PhaseRouter<T>— generic, phase-aware dual-write router withread(),write(),writeBoolean(),writeReturning()and checked-exception variantsElasticsearch implementation
ContentletIndexOperationsES— wrapsBulkRequest/BulkProcessorbehindContentletIndexOperationsMappingOperationsES— wraps ESRestHighLevelClientmapping calls behindIndexMappingRestOperationsOpenSearch implementation
ContentletIndexOperationsOS—opensearch-java3.x bulk write implementation with manualOSIndexBulkProcessor(no built-in BulkProcessor in that SDK)MappingOperationsOS— OpenSearch mapping REST callsMinor changes
ContentMappingAPI— expanded withputMapping,getMapping,toJson,toMap,toJsonStringmethods@IndexRouter.access— changed from single enum value to array ({IndexAccess.READ},{IndexAccess.READ, IndexAccess.WRITE})IndexConfigHelper— addedisMigrationStarted()convenience predicateTesting
ContentletIndexOperationsOSIntegrationTest(480 lines) added toOpenSearchUpgradeSuite./mvnw verify -pl :dotcms-integration -Dcoreit.test.skip=false -Dit.test=ContentletIndexOperationsOSIntegrationTestThis PR fixes: #34938
This PR fixes: #34938