Skip to content

feat(extension): add SPI-based enterprise API routing#3246

Merged
Gezi-lzq merged 15 commits into
1.6from
feat/enterprise-api-spi-1.6
Mar 10, 2026
Merged

feat(extension): add SPI-based enterprise API routing#3246
Gezi-lzq merged 15 commits into
1.6from
feat/enterprise-api-spi-1.6

Conversation

@Gezi-lzq
Copy link
Copy Markdown
Contributor

@Gezi-lzq Gezi-lzq commented Mar 9, 2026

No description provided.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces an SPI (Service Provider Interface) mechanism for routing enterprise/extension API requests to pluggable handlers, both on the broker and controller sides. Extension APIs are identified by API key IDs in the [10000, 19999] range. The PR adds request/response parsing extensions via RequestResponseExtensionProvider, broker-side dispatch via BrokerExtensionHandleDispatcher, and controller-side routing via the existing Controller.handleExtensionRequest.

Changes:

  • Added isExtensionApi to ApiKeys and SPI-based RequestResponseExtensionProvider/RequestResponseExtensions for parsing extension API requests/responses, replacing hard-coded AssertionError fallbacks in AbstractRequest/AbstractResponse.
  • Introduced BrokerExtensionHandle, BrokerExtensionHandleProvider, BrokerExtensionContext, and BrokerExtensionHandleDispatcher SPI mechanism in ElasticKafkaApis for broker-side extension API routing.
  • Added extension API routing in ElasticControllerApis to delegate unrecognized extension APIs to Controller.handleExtensionRequest.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
clients/src/main/java/org/apache/kafka/common/protocol/ApiKeys.java Added isExtensionApi() static method to identify extension APIs by ID range
clients/src/main/java/org/apache/kafka/common/requests/RequestResponseExtensionProvider.java New SPI interface for extension request/response parsing
clients/src/main/java/org/apache/kafka/common/requests/RequestResponseExtensions.java SPI loader and facade for extension parsing
clients/src/main/java/org/apache/kafka/common/requests/AbstractRequest.java Default case now delegates to extension provider instead of throwing
clients/src/main/java/org/apache/kafka/common/requests/AbstractResponse.java Default case now delegates to extension provider instead of throwing
core/src/main/scala/kafka/server/streamaspect/extension/BrokerExtensionHandle.scala New traits: BrokerExtensionHandle, BrokerExtensionHandleProvider, BrokerExtensionContext, BrokerExtensionHandleDispatcher
core/src/main/scala/kafka/server/streamaspect/ElasticKafkaApis.scala Integrates BrokerExtensionHandleDispatcher for broker-side extension API routing
core/src/main/scala/kafka/server/streamaspect/ElasticControllerApis.scala Routes extension APIs to Controller.handleExtensionRequest
clients/src/test/java/org/apache/kafka/common/protocol/ApiKeysTest.java Tests for isExtensionApi
clients/src/test/java/org/apache/kafka/common/requests/RequestResponseTest.java Skip set for stream/enterprise APIs + extension provider tests
clients/src/test/java/org/apache/kafka/common/requests/TestRequestResponseExtensionProvider.java Test SPI provider implementation
clients/src/test/resources/META-INF/services/org.apache.kafka.common.requests.RequestResponseExtensionProvider SPI registration for test provider
core/src/test/scala/.../BrokerExtensionHandleDispatcherTest.scala Unit tests for dispatcher behavior
core/src/test/scala/.../BrokerExtensionHandleContractsTest.scala Contract tests for handle/provider traits
core/src/test/scala/.../ElasticKafkaApisTest.scala Integration tests for broker extension routing
core/src/test/scala/.../ElasticControllerApisTest.scala Integration tests for controller extension routing

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread core/src/main/scala/kafka/server/streamaspect/ElasticControllerApis.scala Outdated
@Gezi-lzq Gezi-lzq marked this pull request as ready for review March 10, 2026 03:30
Comment thread core/src/main/scala/kafka/server/streamaspect/ElasticKafkaApis.scala Outdated
@Gezi-lzq Gezi-lzq enabled auto-merge (squash) March 10, 2026 09:34
@Gezi-lzq Gezi-lzq merged commit c3bf2cd into 1.6 Mar 10, 2026
6 checks passed
@Gezi-lzq Gezi-lzq deleted the feat/enterprise-api-spi-1.6 branch March 10, 2026 09:40
Gezi-lzq added a commit that referenced this pull request May 13, 2026
* feat(protocol): add enterprise request/response extension routing

* feat(core): add broker extension handle SPI contracts

* feat(core): add broker extension handle dispatcher

* feat(core): route extension APIs via broker handle SPI

* test(clients): skip enterprise stream APIs in generic serialization sweep

* fix(clients): reject multiple request/response extension providers

* refactor(core): consolidate broker extension SPI definitions

* style: align extension no-handler exception with KafkaApis

* refactor(core): route extension API fallback directly in controller handle

* refactor(core): rename BrokerHandleOps to BrokerExtensionContext

* docs(core): clarify broker extension SPI roles

* fix(extension): align controller fallback and provider arg order

* chore: add AutoMQ copyright headers

* refactor: extract broker extension context

* style: move broker extension context to class end

(cherry picked from commit c3bf2cd)
Gezi-lzq added a commit that referenced this pull request May 13, 2026
## Summary
- cherry-pick #3246 to main: SPI-based enterprise API routing
prerequisite
- cherry-pick #3248 to main: fetch listener callbacks and
InterBrokerAsyncSender support
- cherry-pick #3359 to main: harden InterBrokerAsyncSender validation

## Context
#3359 was merged to 1.7, but main did not yet contain its prerequisites.
#3248 depends on #3246, so this PR now carries the full dependency
order: #3246 -> #3248 -> #3359.

Conflict adaptation: #3248 conflicted in UnifiedLog because main keeps
the 4-argument LocalLog.append signature. The resolution preserves
main's append call and adds the latest-append-state update from #3248.

## Tests
- ./gradlew :server-common:spotlessJavaCheck :server-common:test --tests
org.apache.kafka.server.util.InterBrokerAsyncSenderTest
:core:compileScala :core:compileTestScala
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants