Add AnalyticsFrontEndExtension SPI + AnalyticsServices bundle for analytics-engine frontend integration - #21449
Conversation
PR Reviewer Guide 🔍(Review updated until commit 07ecf84)Here are some key observations to aid the review process:
|
0e1c142 to
bda1e46
Compare
bda1e46 to
91a6d1f
Compare
|
Persistent review updated to latest commit bda1e46 |
|
Persistent review updated to latest commit 91a6d1f |
Adds an SPI interface in analytics-framework that lets frontend plugins (e.g., opensearch-sql) consume analytics-engine services without taking a hard install-time dependency on analytics-engine. Mirrors the JobSchedulerExtension pattern from opensearch-job-scheduler: the frontend plugin declares its capability via AnalyticsFrontEndExtension; the publishing plugin (analytics-engine) discovers consumers via ExtensiblePlugin#loadExtensions and pushes an AnalyticsServices bundle to each consumer once Guice has constructed them. Bundled services (rather than separate setters) so analytics-engine can add new services in the future without changing the SPI signature. Initial bundle: - QueryPlanExecutor<RelNode, Iterable<Object[]>> - SchemaProvider Lifecycle (documented on the interface): setAnalyticsServices is called exactly once per consumer per node, after every plugin's createComponents returns and before the first analytics query is dispatched. This PR adds only the contract. The producer-side wiring in AnalyticsPlugin (loadExtensions + Guice listener + push) and the opensearch-sql consumer-side implementation will follow. Signed-off-by: Kai Huang <ahkcs@amazon.com>
91a6d1f to
07ecf84
Compare
|
Persistent review updated to latest commit 07ecf84 |
PR Code Suggestions ✨Explore these optional code suggestions:
|
|
❌ Gradle check result for 07ecf84: 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? |
Per Peter's review on opensearch-project#5400: flag the three new httpcore5/httpclient5 exclusions (and ideally the entire bundlePlugin exclusion block) for removal once analytics-engine becomes an optional dependency via the AnalyticsFrontEndExtension SPI in opensearch-project/OpenSearch#21449. Signed-off-by: Kai Huang <ahkcs@amazon.com>
Summary
Adds an SPI interface and a services bundle in
analytics-frameworkthat let frontend plugins (e.g.,opensearch-sql) integrate withanalytics-enginewithout taking a hard install-time dependency on it.Mirrors the
JobSchedulerExtensionpattern fromopensearch-job-scheduler: the frontend plugin declares its capability viaAnalyticsFrontEndExtension; the publishing plugin (analytics-engine) discovers consumers viaExtensiblePlugin#loadExtensionsand pushes anAnalyticsServicesbundle to each consumer once Guice has constructed them.Why
Today,
opensearch-sqldeclaresextendedPlugins = [..., 'analytics-engine']as a HARD dependency. This causes the SQL plugin install to fail on stock OpenSearch distros that don't shipanalytics-engine(Missing plugin [analytics-engine], dependency of [opensearch-sql]). Marking it;optional=trueis necessary but not sufficient —TransportPPLQueryActionGuice-injectsQueryPlanExecutor, and Guice cannot satisfy that binding when the providing plugin is absent.The SPI inverts the dependency. Frontend plugins implement
AnalyticsFrontEndExtensionto receive analytics-engine's services through a push lifecycle; analytics-engine never imports the frontend.What's in this PR
Two new files in
sandbox/libs/analytics-framework/src/main/java/org/opensearch/analytics/spi/:AnalyticsFrontEndExtension— the SPI interface. Single method:AnalyticsServices— the services bundle (record). Initial fields:QueryPlanExecutor<RelNode, Iterable<Object[]>> queryPlanExecutorSchemaProvider schemaProvider(already exists inanalytics-framework)Bundled rather than separate setters so future analytics-engine services can be added without changing the SPI signature — frontends that don't consume the new service simply ignore the new accessor.
JavaDoc on the interface spells out the lifecycle (discovery via
ExtensiblePlugin#loadExtensions, push after Guice builds the node injector, exactly once per consumer per node, before first analytics query).What's NOT in this PR
AnalyticsPlugin(loadExtensionscollection + Guice listener forDefaultPlanExecutor+ push to consumers). That's a follow-up by the analytics-engine team.Related
Coordination thread: opensearch-project/sql#5398 — the SQL-side draft of this same interface, which gets deleted once this PR merges and a new
analytics-frameworkJAR is vendored into opensearch-sql.Test plan
./gradlew :sandbox:libs:analytics-framework:compileJava -Dsandbox.enabled=true— passes.The interface has no implementations or callers in this PR, so there are no behavioral tests.