Class EndpointRegistry
java.lang.Object
io.kroxylicious.proxy.internal.net.EndpointRegistry
- All Implemented Interfaces:
EndpointBindingResolver,EndpointReconciler,AutoCloseable
public class EndpointRegistry
extends Object
implements EndpointReconciler, EndpointBindingResolver, AutoCloseable
The endpoint registry is responsible for associating network endpoints with broker/bootstrap addresses of virtual clusters.
Pictorially the registry looks like this:
Registry
├─ Endpoint (tls 9092)
│ ╰───┬──→ cluster1.kafka.com ──→ Virtual Cluster A bootstrap
│ ├──→ broker1-cluster1.kafka.com ──→ Virtual Cluster A broker node 1
│ ╰──→ broker2-cluster1.kafka.com ──→ Virtual Cluster A broker node 2
├─ Endpoint (plain 19092)
│ ╰───→ (null) ──→ Virtual Cluster B bootstrap
├─ Endpoint (plain 19093)
│ ╰───→ (null) ──→ Virtual Cluster B broker 1
╰─ Endpoint (plain 12094)
╰───→ (null) ──→ Virtual Cluster B broker 2
Key points about the implementation:
- The registry does not take direct responsibility for binding and unbinding network sockets. Instead, it emits
network binding operations
NetworkBindingOperationwhich are processed by aNetworkBindingOperationProcessor. - The registry exposes methods for the registration
registerVirtualCluster(EndpointGateway)and deregistrationderegisterVirtualCluster(EndpointGateway)of virtual clusters. The registry emits the required network binding operations to expose the virtual cluster to the network. These API calls return futures that will complete once the underlying network operations are completed. - The registry provides an
EndpointBindingResolver. TheEndpointBindingResolver.resolve(Endpoint, String)method accepts connection metadata (port, SNI etc) and resolves this to a @BootstrapEndpointBinding. This allows Kroxylicious to determine the destination of any incoming connection. - The registry provides a
EndpointReconciler. TheEndpointReconciler.reconcile(EndpointGateway, Map)method accepts a map describing the target cluster's broker topology. The job of the reconciler is to make adjustments to the network bindings (binding/unbinding ports) to fully expose the brokers of the target cluster through the virtual cluster.
- virtual cluster registration uses java.util.concurrent features to ensure registration is single threaded.
- virtual cluster de-registration uses java.util.concurrent.atomic to ensure de-registration is single threaded.
- virtual cluster reconciliation uses java.util.concurrent.atomic to ensure reconciliation is single threaded.
- updates to the binding mapping (attached to channel) are made only whilst holding an intrinsic lock on the
EndpointRegistry.ListeningChannelRecord. - updates to the binding mapping are published safely to readers (i.e. threads calling
EndpointBindingResolver.resolve(Endpoint, String)). This relies the fact that the binding map uses concurrency safe data structures (ConcurrentHashMapand the exclusive use of immutable objects within it.
-
Field Summary
FieldsModifier and TypeFieldDescriptionprotected static final io.netty.util.AttributeKey<Map<io.kroxylicious.proxy.internal.net.EndpointRegistry.RoutingKey, EndpointBinding>> static final Stringstatic final intSentinel port value meaning "let the OS assign a free port at bind time".static final String -
Constructor Summary
ConstructorsConstructorDescriptionEndpointRegistry(NetworkBindingOperationProcessor bindingOperationProcessor) -
Method Summary
Modifier and TypeMethodDescriptionvoidclose()deregisterVirtualCluster(EndpointGateway virtualClusterModel) De-registers a virtual cluster from the registry, removing all existing endpoint bindings, and closing any listening sockets that are no longer required.intlocalPortFor(Endpoint endpoint) reconcile(EndpointGateway virtualClusterModel, Map<Integer, HostPort> upstreamNodes) Reconciles the current set of bindings for this virtual cluster against those required by the current set of nodes.registerVirtualCluster(EndpointGateway virtualClusterModel) Registers a virtual cluster with the registry.Uses channel metadata (port, SNI name etc.) from the incoming connection to resolve aBootstrapEndpointBinding.shutdown()Signals that the registry should be shut down.upstreamAddress(EndpointGateway gateway, int upstreamNodeId) Returns the upstream address for the given upstream node ID (note this may be a physical node id, or a virtual node id if routing enabled), as last reconciled for the virtual cluster identified bygateway.
-
Field Details
-
NO_CHANNEL_BINDINGS_MESSAGE
- See Also:
-
VIRTUAL_CLUSTER_CANNOT_BE_NULL_MESSAGE
- See Also:
-
OS_ASSIGNED_PORT
public static final int OS_ASSIGNED_PORTSentinel port value meaning "let the OS assign a free port at bind time". Use withKafkaProxy.listeningPort(String, int)to discover the actual port after startup.- See Also:
-
CHANNEL_BINDINGS
protected static final io.netty.util.AttributeKey<Map<io.kroxylicious.proxy.internal.net.EndpointRegistry.RoutingKey,EndpointBinding>> CHANNEL_BINDINGS
-
-
Constructor Details
-
EndpointRegistry
-
-
Method Details
-
registerVirtualCluster
Registers a virtual cluster with the registry. The registry refers to the endpoint configuration of the virtual cluster to understand its port requirements, binding new listening ports as necessary. This operation returns aCompletionStage<Endpoint>. The completion stage will complete once all necessary network bind operations are completed. The returnedEndpointrefers to the bootstrap endpoint of the virtual cluster.- Parameters:
virtualClusterModel- virtual cluster to be registered.- Returns:
- completion stage that will complete after registration is finished.
-
deregisterVirtualCluster
De-registers a virtual cluster from the registry, removing all existing endpoint bindings, and closing any listening sockets that are no longer required. This operation returns aCompletionStage<Endpoint>. The completion stage will complete once any necessary network unbind operations are completed.- Parameters:
virtualClusterModel- virtual cluster to be deregistered.- Returns:
- completion stage that will complete after registration is finished.
-
reconcile
public CompletionStage<Void> reconcile(EndpointGateway virtualClusterModel, Map<Integer, HostPort> upstreamNodes) Reconciles the current set of bindings for this virtual cluster against those required by the current set of nodes.- Specified by:
reconcilein interfaceEndpointReconciler- Parameters:
virtualClusterModel- virtual clusterupstreamNodes- current map of node id to upstream host ports- Returns:
- CompletionStage yielding true if binding alterations were made, or false otherwise.
-
upstreamAddress
Description copied from interface:EndpointReconcilerReturns the upstream address for the given upstream node ID (note this may be a physical node id, or a virtual node id if routing enabled), as last reconciled for the virtual cluster identified bygateway. Returns empty if the address is not yet known.- Specified by:
upstreamAddressin interfaceEndpointReconciler- Parameters:
gateway- the virtual cluster's endpoint gatewayupstreamNodeId- the upstream node ID- Returns:
- the upstream host and port, or empty if not yet known
-
localPortFor
-
resolve
Uses channel metadata (port, SNI name etc.) from the incoming connection to resolve aBootstrapEndpointBinding.- Specified by:
resolvein interfaceEndpointBindingResolver- Parameters:
endpoint- endpoint being resolvedsniHostname- SNI hostname, may be null.- Returns:
- completion stage yielding the
BootstrapEndpointBindingor exceptionally a EndpointResolutionException.
-
shutdown
Signals that the registry should be shut down. The operation returns aCompletionStagethat will complete once shutdown is complete (endpoints unbound).- Returns:
- CompletionStage that completes once shut-down is complete.
-
close
- Specified by:
closein interfaceAutoCloseable- Throws:
Exception
-