Interface Router
Router implementations use the RouterContext to send requests
down named routes and to deliver a response back to the client. A single
incoming request may result in multiple outgoing requests to different
routes (e.g. fan-out), with the router composing the final response.
Observability guidelines for router implementations
The runtime automatically logs and measures the following on behalf of all router implementations:
- Which route each request was sent to (at TRACE level, with
routekey) - Request/response correlation
- Per-route request counts, error counts, and latency (as Micrometer metrics)
- Error conditions such as unknown routes and router failures
Router implementations should not duplicate the above. Instead, implementations should log:
- Routing rationale at DEBUG: explain why a
particular route was chosen when the logic is non-trivial. Always
include
RouterContext.sessionId()for correlation with runtime logs. - Configuration at INFO during initialisation: log once
from
RouterFactory.createRouter(io.kroxylicious.proxy.router.RouterFactoryContext, I)to describe the router's configuration. - Response mutation at DEBUG: if the router modifies
responses (e.g. version capping in
API_VERSIONS), log the modification since it changes protocol behaviour visible to clients. - Recovered errors at WARN: if the router catches exceptions internally and recovers, log them with conditional stack traces (include the full stack trace only when DEBUG is enabled).
Router implementations must not:
- Log Kafka message content (may contain sensitive data).
- Log at INFO or above on every request (reserve INFO+ for lifecycle events; per-request logging at that level causes excessive volume in production).
-
Method Summary
Modifier and TypeMethodDescriptiondefault voidclose()Called by the runtime when the client connection is torn down.onRequest(org.apache.kafka.common.protocol.ApiKeys apiKey, short apiVersion, org.apache.kafka.common.message.RequestHeaderData header, org.apache.kafka.common.protocol.ApiMessage request, RouterContext context) Called for each incoming client request that is dynamically routed.Declares API keys that are always forwarded to a fixed named route without deserialisation.
-
Method Details
-
onRequest
CompletionStage<RouterResponse> onRequest(org.apache.kafka.common.protocol.ApiKeys apiKey, short apiVersion, org.apache.kafka.common.message.RequestHeaderData header, org.apache.kafka.common.protocol.ApiMessage request, RouterContext context) Called for each incoming client request that is dynamically routed.The implementation inspects the request, sends one or more requests via
RouterContext.sendRequest(io.kroxylicious.proxy.topology.VirtualNode, org.apache.kafka.common.message.RequestHeaderData, org.apache.kafka.common.protocol.ApiMessage), and returns aRouterResponseencoding the outcome. Use the builder methods onRouterContextto construct results:respondWithto deliver a response,respondWithoutReplyfor acks=0Producerequests, orrespondWithErrorto generate an error response.Threading model
All invocations of this method, all calls to
RouterContext.sendRequest(io.kroxylicious.proxy.topology.VirtualNode, org.apache.kafka.common.message.RequestHeaderData, org.apache.kafka.common.protocol.ApiMessage), and allCompletionStagecallbacks chained on the futures returned bysendRequest, execute on the same Netty event loop thread. Router implementations do not need to synchronise access to their own state.- Parameters:
apiKey- the API key identifying the request typeapiVersion- the API version of the requestheader- the request headerrequest- the request bodycontext- the router context for sending requests- Returns:
- a stage that completes with the routing outcome
-
close
default void close()Called by the runtime when the client connection is torn down.Implementations should release any per-connection resources (e.g. reclaim cache slots).
Guaranteed to be called on the same event loop thread as
onRequest(org.apache.kafka.common.protocol.ApiKeys, short, org.apache.kafka.common.message.RequestHeaderData, org.apache.kafka.common.protocol.ApiMessage, io.kroxylicious.proxy.router.RouterContext). Called at most once per router instance. -
staticRoutes
Declares API keys that are always forwarded to a fixed named route without deserialisation. For these API keys the runtime forwards frames directly (opaque or decoded) without calling
onRequest(org.apache.kafka.common.protocol.ApiKeys, short, org.apache.kafka.common.message.RequestHeaderData, org.apache.kafka.common.protocol.ApiMessage, io.kroxylicious.proxy.router.RouterContext). API keys absent from this map are considered dynamically routed and will be decoded so thatonRequestcan inspect them.This method may only be called once in the lifetime of a Router. The runtime is free to call it once and cache the result.
- Returns:
- a map from API key to route name; empty means all API keys are dynamically routed (the default)
-