...
ssl.engine.factory.class - This configuration will take class of the below interface's type and will be used to create javax.net.ssl.SSLEngine object.
Default value will be as mentioned below.
Code Block |
---|
final static String SSL_ENGINEFACTORY_CLASS_CONFIG = "ssl.engine.factory.class";
final static String DEFAULT_SSL_ENGINEFACTORY_CLASS = "org.apache.kafka.common.security.ssl.DefaultSslEngineFactory"; |
Interface for SSLEngineFactory
...
Code Block |
---|
package org.apache.kafka.common.security.ssl; import org.apache.kafka.common.network.Mode; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; import java.util.Map; import java.util.Set; public interface SslEngineFactory { /** * Creates SSLContext by providing required key material and {@code java.security.SecureRandom} * * @return The SSLContext. */ SSLContext createSSLContext(); /** * Creates a new SSLEngine object. * * @param mode Whether to use client or server mode. * @param peerHost The peer host to use. This is used in client mode if endpoint validation is enabled. * @param peerPort The peer port to use. This is a hint and not used for validation. * @param endpointIdentification Endpoint identification algorithm for client mode. * @return The new SSLEngine. */ SSLEngine createSSLEngine(Mode mode, String peerHost, int peerPort, String endpointIdentification); /** * Returns the currently used configurations by this engine. * @return */ Map<String, Object> currentConfigs(); /** * Returns the reconfigurable configs used by this engine. * @return */ Set<String> reconfigurableConfigs(); /** * Returns true if this engine needs to be rebuilt. * * @param nextConfigs The configuration we want to use. * @return True only if this builder should be rebuilt. */ boolean shouldBeRebuiltshouldRebuiltFor(Map<String, Object> nextConfigs); } |
...
Default implementation would be along the lines (but not necessarily the same) of - sample code which is copied from current SslEngineBuilder.java.
Which classes will be deleted?
- SslEngineBuilder.java (functionality moved to DefaultSslEngineFactory.java)
Which classes will be added?
- SslEngineFactory.java Interface
- SslEngineFactoryInstantiator.java (as an inner class to SslFactory)
- DefaultSslEngineFactory.java (mostly having code from existing SslEngineBuilder)
Which classes will be modified?
- SslFactory.java
How does configs get to the implementation class?
The configuration of Map will be passed to the implementation class via the constructor. See below example,
Detailed code link: My fork
Code Block |
---|
public DefaultSslEngineFactory(Map<String, ?> configs) {
...
...
} |
These configuration will be passed from SslFactory to the implementation of the SslEngineFactory interface via reflection like below
Code Block |
---|
public class SslFactory implement Reconfigurable {
...
...
sslEngineFactoryClass.getDeclaredConstructor(Map.class).newInstance(configs);
...
} |
Support for reconfiguration of custom configs
By custom configs we mean the configs used by the SslEngineFactory's implementation. Those configs does not have to be part of definition of Kafka configs since only the implementation class knows what are those.
This need to be explored more. We don't have clarity on how this can be achieved.
Other challenge
Currently reconfigurations are pushed from Kafka code base to the reconfigurable classes. However, depending upon SslEngineFactory's implementation we could have some events/changes detected by the implementation first and we would need to trigger reconfiguration on SslFactory in order to get re-initialized!
Probably this could be achieved by passing listener to those implementation changes but this needs to be further explored.
Sequence Diagram of SslFactory instantiating the SslEngineFactory implementation
Sequence diagram for the Reconfiguration flow
Compatibility, Deprecation, and Migration Plan
...
As mentioned in the motivation there are/were several attempts to make various ssl configurations pluggable over time focusing on specific aspect of the SSL configuration. However, this KIP proposes to allow customization at SSLContext/SSLEgnine level hence there are no alternatives applicable in our opinion. However there are couple of implementation alternatives that we rejected and document as below.
Why is SslFactory not the pluggable interface directly
This is because currently SslFactory does certain validations which we want to keep separate and mandate those checks across any possible implementation of pluggable class. Also, once we start writing the reconfigurable classes we realize that we need two classes - 1) Engine factory implementation and 2) Container of the factory implementation.