lhotari commented on code in PR #22016:
URL: https://github.com/apache/pulsar/pull/22016#discussion_r1486474263


##########
pip/pip-333.md:
##########
@@ -0,0 +1,387 @@
+# PIP-337: SSL Factory Plugin to customize SSLContext/SSLEngine generation
+
+# Background knowledge
+Apache Pulsar supports TLS encrypted communication between the clients and 
servers. The TLS encryption setup requires
+loading the TLS certificates and its respective passwords to generate the SSL 
Context. Pulsar supports loading these 
+certificates and passwords via the filesystem. It supports both Java based 
Keystores/Truststores and TLS information in 
+".crt", ".pem" & ".key" formats. This information is refreshed based on a 
configurable interval.
+ 
+Apache Pulsar internally uses 3 different frameworks for connection management:
+
+- Netty: Connection management for Pulsar server and client that understands 
Pulsar binary protocol.
+- Jetty: HTTP Server creation for Pulsar Admin and websocket. Jetty Client is 
used by proxy for admin client calls.
+- AsyncHttpClient: HTTP Client creation for Admin client and HTTP Lookup
+
+Each of the above frameworks supports customizing the generation of the SSL 
Context and SSL Engine. Currently, Pulsar 
+uses these features to feed the SSL Context via its internal security tools 
after loading the file based certificates.
+One of the issues of using these features is that pulsar tries to bootstrap 
the SSL Context in multiple ways to suit
+each framework and file type.
+
+```mermaid
+flowchart TB
+    Proxy.DirectProxyHandler --> NettyClientSslContextRefresher
+    Proxy.DirectProxyHandler --> NettySSLContextAutoRefreshBuilder
+    Proxy.AdminProxyHandler --> KeyStoreSSLContext
+    Proxy.AdminProxyHandler --> SecurityUtility
+    Proxy.ServiceChannelInitializer --> NettySSLContextAutoRefreshBuilder
+    Proxy.ServiceChannelInitializer --> NettyServerSslContextBuilder
+    Broker.PulsarChannelInitializer --> NettyServerSslContextBuilder
+    Broker.PulsarChannelInitializer --> NettySSLContextAutoRefreshBuilder
+    Client.PulsarChannelInitializer --> NettySSLContextAutoRefreshBuilder
+    Client.PulsarChannelInitializer --> SecurityUtility
+    Broker.WebService --> JettySSlContextFactory
+    Proxy.WebServer --> JettySSlContextFactory
+    PulsarAdmin --> AsyncHttpConnector
+    AsyncHttpConnector --> KeyStoreSSLContext
+    AsyncHttpConnector --> SecurityUtility
+    JettySSlContextFactory --> NetSslContextBuilder
+    JettySSlContextFactory --> DefaultSslContextBuilder
+    NettyClientSslContextRefresher -.-> SslContextAutoRefreshBuilder
+    NettySSLContextAutoRefreshBuilder -.-> SslContextAutoRefreshBuilder
+    NettyServerSslContextBuilder -.-> SslContextAutoRefreshBuilder
+    NetSslContextBuilder -.-> SslContextAutoRefreshBuilder
+    DefaultSslContextBuilder -.-> SslContextAutoRefreshBuilder
+    Client.HttpLookup.HttpClient --> KeyStoreSSLContext
+    Client.HttpLookup.HttpClient --> SecurityUtility
+    SecurityUtility -.-> KeyManagerProxy
+    SecurityUtility -.-> TrustManagerProxy
+```
+The above diagram is an example of the complexity of the TLS encryption setup 
within Pulsar. The above diagram only
+contains the basic components of Pulsar excluding Websockets, Functions, etc.
+
+Pulsar uses 2 base classes to load the TLS information.
+
+- `SecurityUtility`: It loads files of type ".crt", ".pem" and ".key" and 
converts it into SSL Context. This SSL Context
+can be of type `io.netty.handler.ssl.SslContext` or `javax.net.ssl.SSLContext` 
based on the caller. Security Utility 
+can be used to create SSL Context that internally has KeyManager and 
Trustmanager proxies that load cert changes 
+dynamically.
+- `KeyStoreSSLContext`: It loads files of type Java Keystore/Truststore and 
converts it into SSL Context. This SSL
+Context will be of type `javax.net.ssl.SSLContext`. This is always used to 
create the SSL Engine.
+
+Each of the above classes are either directly used by Pulsar Clients or used 
via implementations of the abstract class 
+`SslContextAutoRefreshBuilder`.
+
+- `SslContextAutoRefreshBuilder` - This abstract class is used to refresh 
certificates at a configurable interval. It 
+internally provides a public API to return the SSL Context.
+
+There are several implementations of the above abstract class to suit the 
needs of each of the framework and the
+respective TLS certificate files:
+
+- `NettyClientSslContextRefresher` - It internally creates the 
`io.netty.handler.ssl.SslContext` using the ".crt", 
+".pem" and ".key" files for the proxy client.
+- `NettySSLContextAutoRefreshBuilder` - It internally creates the 
`KeyStoreSSLContext` using the Java Keystores.
+- `NettyServerSslContextBuilder` - It internally creates the 
`io.netty.handler.ssl.SslContext` using the ".crt",
+  ".pem" and ".key" files for the server.
+- `NetSslContextBuilder` - It internally creates the 
`javax.net.ssl.SSLContext` using the Java Keystores for the web 
+server.
+- `DefaultSslContextBuilder` - It internally creates the 
`javax.net.ssl.SSLContext` using the ".crt", ".pem" and ".key"
+files for the web server.
+
+# Motivation
+Apache Pulsar's TLS encryption configuration is not pluggable. It only 
supports file-based certificates. This makes 
+Pulsar difficult to adopt for organizations that require loading TLS 
certificates by other mechanisms.
+
+# Goals
+The purpose of this PIP is to introduce the following:
+
+- Provide a mechanism to plugin a custom SSL Factory that can generate SSL 
Context and SSL Engine. 
+- Simplify the Pulsar code base to universally use `javax.net.ssl.SSLContext` 
and reduce the amount of code required to
+build and configure the SSL context taking into consideration backwards 
compatibility.
+
+## In Scope
+
+- Creation of a new abstract class `SSLFactory` that can generate a SSL 
Context, Client SSL Engine and Server SSL 
+Engine. It should support refreshing the certificates at a configurable 
interval.
+- Creation of a default implementation of `SSLFactory` that supports loading 
the SSL Context and SSL Engine via
+file-based certificates. Internally it will use the SecurityUtility and 
KeyStoreSSLContext.
+- Modify the Pulsar Components to support the `SSLFactory` instead of the 
SslContextAutoRefreshBuilder, SecurityUtility
+and KeyStoreSSLContext.
+- Remove the SslContextAutoRefreshBuilder and all its implementations.
+
+# High Level Design
+```mermaid
+flowchart TB
+    Proxy.DirectProxyHandler --> Sslfactory
+    Proxy.AdminProxyHandler --> Sslfactory
+    Proxy.ServiceChannelInitializer --> Sslfactory
+    Broker.PulsarChannelInitializer --> Sslfactory
+    Client.PulsarChannelInitializer --> Sslfactory
+    Broker.WebService --> JettySSlContextFactory
+    Proxy.WebServer --> JettySSlContextFactory
+    PulsarAdmin --> AsyncHttpConnector
+    AsyncHttpConnector --> Sslfactory
+    JettySSlContextFactory --> Sslfactory
+    Client.HttpLookup.HttpClient --> Sslfactory
+    Sslfactory -.-> DefaultSslFactory
+    Sslfactory -.-> CustomSslFactory
+```
+
+# Detailed Design
+
+## Design and Implementation Details
+
+### Pulsar Common Changes
+
+A new abstract class called `SslFactory` that provides public methods to 
create a SSL Context, Client SSL Engine and
+Server SSL Engine. The SSL Context class returned will be of type 
`javax.net.ssl.SSLContext`. This class will refresh 
+the SSL Context at the configured interval. This refresh behavior is the same 
as the 
+current `SslContextAutoRefreshBuilder`.
+
+```java
+public abstract class SslFactory {

Review Comment:
   I guess we could make this a Java `interface` so that it would be easier to 
evolve later. The name could be Pulsar specific so that it's clear that it's an 
interface for Pulsar.



##########
pip/pip-333.md:
##########
@@ -0,0 +1,387 @@
+# PIP-337: SSL Factory Plugin to customize SSLContext/SSLEngine generation
+
+# Background knowledge
+Apache Pulsar supports TLS encrypted communication between the clients and 
servers. The TLS encryption setup requires
+loading the TLS certificates and its respective passwords to generate the SSL 
Context. Pulsar supports loading these 
+certificates and passwords via the filesystem. It supports both Java based 
Keystores/Truststores and TLS information in 
+".crt", ".pem" & ".key" formats. This information is refreshed based on a 
configurable interval.
+ 
+Apache Pulsar internally uses 3 different frameworks for connection management:
+
+- Netty: Connection management for Pulsar server and client that understands 
Pulsar binary protocol.
+- Jetty: HTTP Server creation for Pulsar Admin and websocket. Jetty Client is 
used by proxy for admin client calls.
+- AsyncHttpClient: HTTP Client creation for Admin client and HTTP Lookup
+
+Each of the above frameworks supports customizing the generation of the SSL 
Context and SSL Engine. Currently, Pulsar 
+uses these features to feed the SSL Context via its internal security tools 
after loading the file based certificates.
+One of the issues of using these features is that pulsar tries to bootstrap 
the SSL Context in multiple ways to suit
+each framework and file type.
+
+```mermaid
+flowchart TB
+    Proxy.DirectProxyHandler --> NettyClientSslContextRefresher
+    Proxy.DirectProxyHandler --> NettySSLContextAutoRefreshBuilder
+    Proxy.AdminProxyHandler --> KeyStoreSSLContext
+    Proxy.AdminProxyHandler --> SecurityUtility
+    Proxy.ServiceChannelInitializer --> NettySSLContextAutoRefreshBuilder
+    Proxy.ServiceChannelInitializer --> NettyServerSslContextBuilder
+    Broker.PulsarChannelInitializer --> NettyServerSslContextBuilder
+    Broker.PulsarChannelInitializer --> NettySSLContextAutoRefreshBuilder
+    Client.PulsarChannelInitializer --> NettySSLContextAutoRefreshBuilder
+    Client.PulsarChannelInitializer --> SecurityUtility
+    Broker.WebService --> JettySSlContextFactory
+    Proxy.WebServer --> JettySSlContextFactory
+    PulsarAdmin --> AsyncHttpConnector
+    AsyncHttpConnector --> KeyStoreSSLContext
+    AsyncHttpConnector --> SecurityUtility
+    JettySSlContextFactory --> NetSslContextBuilder
+    JettySSlContextFactory --> DefaultSslContextBuilder
+    NettyClientSslContextRefresher -.-> SslContextAutoRefreshBuilder
+    NettySSLContextAutoRefreshBuilder -.-> SslContextAutoRefreshBuilder
+    NettyServerSslContextBuilder -.-> SslContextAutoRefreshBuilder
+    NetSslContextBuilder -.-> SslContextAutoRefreshBuilder
+    DefaultSslContextBuilder -.-> SslContextAutoRefreshBuilder
+    Client.HttpLookup.HttpClient --> KeyStoreSSLContext
+    Client.HttpLookup.HttpClient --> SecurityUtility
+    SecurityUtility -.-> KeyManagerProxy
+    SecurityUtility -.-> TrustManagerProxy
+```
+The above diagram is an example of the complexity of the TLS encryption setup 
within Pulsar. The above diagram only
+contains the basic components of Pulsar excluding Websockets, Functions, etc.
+
+Pulsar uses 2 base classes to load the TLS information.
+
+- `SecurityUtility`: It loads files of type ".crt", ".pem" and ".key" and 
converts it into SSL Context. This SSL Context
+can be of type `io.netty.handler.ssl.SslContext` or `javax.net.ssl.SSLContext` 
based on the caller. Security Utility 
+can be used to create SSL Context that internally has KeyManager and 
Trustmanager proxies that load cert changes 
+dynamically.
+- `KeyStoreSSLContext`: It loads files of type Java Keystore/Truststore and 
converts it into SSL Context. This SSL
+Context will be of type `javax.net.ssl.SSLContext`. This is always used to 
create the SSL Engine.
+
+Each of the above classes are either directly used by Pulsar Clients or used 
via implementations of the abstract class 
+`SslContextAutoRefreshBuilder`.
+
+- `SslContextAutoRefreshBuilder` - This abstract class is used to refresh 
certificates at a configurable interval. It 
+internally provides a public API to return the SSL Context.
+
+There are several implementations of the above abstract class to suit the 
needs of each of the framework and the
+respective TLS certificate files:
+
+- `NettyClientSslContextRefresher` - It internally creates the 
`io.netty.handler.ssl.SslContext` using the ".crt", 
+".pem" and ".key" files for the proxy client.
+- `NettySSLContextAutoRefreshBuilder` - It internally creates the 
`KeyStoreSSLContext` using the Java Keystores.
+- `NettyServerSslContextBuilder` - It internally creates the 
`io.netty.handler.ssl.SslContext` using the ".crt",
+  ".pem" and ".key" files for the server.
+- `NetSslContextBuilder` - It internally creates the 
`javax.net.ssl.SSLContext` using the Java Keystores for the web 
+server.
+- `DefaultSslContextBuilder` - It internally creates the 
`javax.net.ssl.SSLContext` using the ".crt", ".pem" and ".key"
+files for the web server.
+
+# Motivation
+Apache Pulsar's TLS encryption configuration is not pluggable. It only 
supports file-based certificates. This makes 
+Pulsar difficult to adopt for organizations that require loading TLS 
certificates by other mechanisms.
+
+# Goals
+The purpose of this PIP is to introduce the following:
+
+- Provide a mechanism to plugin a custom SSL Factory that can generate SSL 
Context and SSL Engine. 
+- Simplify the Pulsar code base to universally use `javax.net.ssl.SSLContext` 
and reduce the amount of code required to
+build and configure the SSL context taking into consideration backwards 
compatibility.
+
+## In Scope
+
+- Creation of a new abstract class `SSLFactory` that can generate a SSL 
Context, Client SSL Engine and Server SSL 
+Engine. It should support refreshing the certificates at a configurable 
interval.
+- Creation of a default implementation of `SSLFactory` that supports loading 
the SSL Context and SSL Engine via
+file-based certificates. Internally it will use the SecurityUtility and 
KeyStoreSSLContext.
+- Modify the Pulsar Components to support the `SSLFactory` instead of the 
SslContextAutoRefreshBuilder, SecurityUtility
+and KeyStoreSSLContext.
+- Remove the SslContextAutoRefreshBuilder and all its implementations.
+
+# High Level Design
+```mermaid
+flowchart TB
+    Proxy.DirectProxyHandler --> Sslfactory
+    Proxy.AdminProxyHandler --> Sslfactory
+    Proxy.ServiceChannelInitializer --> Sslfactory
+    Broker.PulsarChannelInitializer --> Sslfactory
+    Client.PulsarChannelInitializer --> Sslfactory
+    Broker.WebService --> JettySSlContextFactory
+    Proxy.WebServer --> JettySSlContextFactory
+    PulsarAdmin --> AsyncHttpConnector
+    AsyncHttpConnector --> Sslfactory
+    JettySSlContextFactory --> Sslfactory
+    Client.HttpLookup.HttpClient --> Sslfactory
+    Sslfactory -.-> DefaultSslFactory
+    Sslfactory -.-> CustomSslFactory
+```
+
+# Detailed Design
+
+## Design and Implementation Details
+
+### Pulsar Common Changes
+
+A new abstract class called `SslFactory` that provides public methods to 
create a SSL Context, Client SSL Engine and
+Server SSL Engine. The SSL Context class returned will be of type 
`javax.net.ssl.SSLContext`. This class will refresh 
+the SSL Context at the configured interval. This refresh behavior is the same 
as the 
+current `SslContextAutoRefreshBuilder`.
+
+```java
+public abstract class SslFactory {
+    public SslFactory(long certRefreshInSec);
+    public abstract SSLEngine getClientSslEngine(String peerHost, int 
peerPort);
+    public abstract SSLEngine getServerSslEngine() throws 
GeneralSecurityException, IOException;

Review Comment:
   If these create new instances, these could be called `create`* instead of 
`get`*.



##########
pip/pip-333.md:
##########
@@ -0,0 +1,387 @@
+# PIP-337: SSL Factory Plugin to customize SSLContext/SSLEngine generation
+
+# Background knowledge
+Apache Pulsar supports TLS encrypted communication between the clients and 
servers. The TLS encryption setup requires
+loading the TLS certificates and its respective passwords to generate the SSL 
Context. Pulsar supports loading these 
+certificates and passwords via the filesystem. It supports both Java based 
Keystores/Truststores and TLS information in 
+".crt", ".pem" & ".key" formats. This information is refreshed based on a 
configurable interval.
+ 
+Apache Pulsar internally uses 3 different frameworks for connection management:
+
+- Netty: Connection management for Pulsar server and client that understands 
Pulsar binary protocol.
+- Jetty: HTTP Server creation for Pulsar Admin and websocket. Jetty Client is 
used by proxy for admin client calls.
+- AsyncHttpClient: HTTP Client creation for Admin client and HTTP Lookup
+
+Each of the above frameworks supports customizing the generation of the SSL 
Context and SSL Engine. Currently, Pulsar 
+uses these features to feed the SSL Context via its internal security tools 
after loading the file based certificates.
+One of the issues of using these features is that pulsar tries to bootstrap 
the SSL Context in multiple ways to suit
+each framework and file type.
+
+```mermaid
+flowchart TB
+    Proxy.DirectProxyHandler --> NettyClientSslContextRefresher
+    Proxy.DirectProxyHandler --> NettySSLContextAutoRefreshBuilder
+    Proxy.AdminProxyHandler --> KeyStoreSSLContext
+    Proxy.AdminProxyHandler --> SecurityUtility
+    Proxy.ServiceChannelInitializer --> NettySSLContextAutoRefreshBuilder
+    Proxy.ServiceChannelInitializer --> NettyServerSslContextBuilder
+    Broker.PulsarChannelInitializer --> NettyServerSslContextBuilder
+    Broker.PulsarChannelInitializer --> NettySSLContextAutoRefreshBuilder
+    Client.PulsarChannelInitializer --> NettySSLContextAutoRefreshBuilder
+    Client.PulsarChannelInitializer --> SecurityUtility
+    Broker.WebService --> JettySSlContextFactory
+    Proxy.WebServer --> JettySSlContextFactory
+    PulsarAdmin --> AsyncHttpConnector
+    AsyncHttpConnector --> KeyStoreSSLContext
+    AsyncHttpConnector --> SecurityUtility
+    JettySSlContextFactory --> NetSslContextBuilder
+    JettySSlContextFactory --> DefaultSslContextBuilder
+    NettyClientSslContextRefresher -.-> SslContextAutoRefreshBuilder
+    NettySSLContextAutoRefreshBuilder -.-> SslContextAutoRefreshBuilder
+    NettyServerSslContextBuilder -.-> SslContextAutoRefreshBuilder
+    NetSslContextBuilder -.-> SslContextAutoRefreshBuilder
+    DefaultSslContextBuilder -.-> SslContextAutoRefreshBuilder
+    Client.HttpLookup.HttpClient --> KeyStoreSSLContext
+    Client.HttpLookup.HttpClient --> SecurityUtility
+    SecurityUtility -.-> KeyManagerProxy
+    SecurityUtility -.-> TrustManagerProxy
+```
+The above diagram is an example of the complexity of the TLS encryption setup 
within Pulsar. The above diagram only
+contains the basic components of Pulsar excluding Websockets, Functions, etc.
+
+Pulsar uses 2 base classes to load the TLS information.
+
+- `SecurityUtility`: It loads files of type ".crt", ".pem" and ".key" and 
converts it into SSL Context. This SSL Context
+can be of type `io.netty.handler.ssl.SslContext` or `javax.net.ssl.SSLContext` 
based on the caller. Security Utility 
+can be used to create SSL Context that internally has KeyManager and 
Trustmanager proxies that load cert changes 
+dynamically.
+- `KeyStoreSSLContext`: It loads files of type Java Keystore/Truststore and 
converts it into SSL Context. This SSL
+Context will be of type `javax.net.ssl.SSLContext`. This is always used to 
create the SSL Engine.
+
+Each of the above classes are either directly used by Pulsar Clients or used 
via implementations of the abstract class 
+`SslContextAutoRefreshBuilder`.
+
+- `SslContextAutoRefreshBuilder` - This abstract class is used to refresh 
certificates at a configurable interval. It 
+internally provides a public API to return the SSL Context.
+
+There are several implementations of the above abstract class to suit the 
needs of each of the framework and the
+respective TLS certificate files:
+
+- `NettyClientSslContextRefresher` - It internally creates the 
`io.netty.handler.ssl.SslContext` using the ".crt", 
+".pem" and ".key" files for the proxy client.
+- `NettySSLContextAutoRefreshBuilder` - It internally creates the 
`KeyStoreSSLContext` using the Java Keystores.
+- `NettyServerSslContextBuilder` - It internally creates the 
`io.netty.handler.ssl.SslContext` using the ".crt",
+  ".pem" and ".key" files for the server.
+- `NetSslContextBuilder` - It internally creates the 
`javax.net.ssl.SSLContext` using the Java Keystores for the web 
+server.
+- `DefaultSslContextBuilder` - It internally creates the 
`javax.net.ssl.SSLContext` using the ".crt", ".pem" and ".key"
+files for the web server.
+
+# Motivation
+Apache Pulsar's TLS encryption configuration is not pluggable. It only 
supports file-based certificates. This makes 
+Pulsar difficult to adopt for organizations that require loading TLS 
certificates by other mechanisms.
+
+# Goals
+The purpose of this PIP is to introduce the following:
+
+- Provide a mechanism to plugin a custom SSL Factory that can generate SSL 
Context and SSL Engine. 
+- Simplify the Pulsar code base to universally use `javax.net.ssl.SSLContext` 
and reduce the amount of code required to
+build and configure the SSL context taking into consideration backwards 
compatibility.
+
+## In Scope
+
+- Creation of a new abstract class `SSLFactory` that can generate a SSL 
Context, Client SSL Engine and Server SSL 
+Engine. It should support refreshing the certificates at a configurable 
interval.
+- Creation of a default implementation of `SSLFactory` that supports loading 
the SSL Context and SSL Engine via
+file-based certificates. Internally it will use the SecurityUtility and 
KeyStoreSSLContext.
+- Modify the Pulsar Components to support the `SSLFactory` instead of the 
SslContextAutoRefreshBuilder, SecurityUtility
+and KeyStoreSSLContext.
+- Remove the SslContextAutoRefreshBuilder and all its implementations.
+
+# High Level Design
+```mermaid
+flowchart TB
+    Proxy.DirectProxyHandler --> Sslfactory
+    Proxy.AdminProxyHandler --> Sslfactory
+    Proxy.ServiceChannelInitializer --> Sslfactory
+    Broker.PulsarChannelInitializer --> Sslfactory
+    Client.PulsarChannelInitializer --> Sslfactory
+    Broker.WebService --> JettySSlContextFactory
+    Proxy.WebServer --> JettySSlContextFactory
+    PulsarAdmin --> AsyncHttpConnector
+    AsyncHttpConnector --> Sslfactory
+    JettySSlContextFactory --> Sslfactory
+    Client.HttpLookup.HttpClient --> Sslfactory
+    Sslfactory -.-> DefaultSslFactory
+    Sslfactory -.-> CustomSslFactory
+```
+
+# Detailed Design
+
+## Design and Implementation Details
+
+### Pulsar Common Changes
+
+A new abstract class called `SslFactory` that provides public methods to 
create a SSL Context, Client SSL Engine and
+Server SSL Engine. The SSL Context class returned will be of type 
`javax.net.ssl.SSLContext`. This class will refresh 
+the SSL Context at the configured interval. This refresh behavior is the same 
as the 
+current `SslContextAutoRefreshBuilder`.
+
+```java
+public abstract class SslFactory {
+    public SslFactory(long certRefreshInSec);
+    public abstract SSLEngine getClientSslEngine(String peerHost, int 
peerPort);
+    public abstract SSLEngine getServerSslEngine() throws 
GeneralSecurityException, IOException;
+    public abstract boolean needsUpdate();
+    public abstract void update() throws Exception;
+    public abstract void configure(String sslProviderString, 
+                                   Set<String> ciphers, 
+                                   Set<String> protocols, 
+                                   boolean allowInsecureConnection, 
+                                   boolean requireTrustedClientCertOnConnect, 
+                                   AuthenticationDataProvider authData, 
+                                   String tlsCustomParams);
+    // Implementation similar to SslContextAutoRefreshBuilder class which will 
be threadsafe
+    public SSLContext getInternalSslContext();
+}
+```
+
+A default implementation of the above SSLFactory class called 
`DefaultSslFactory` that will generate the SSL Context 
+and SSL Engines using File-based Certificates. It will be able to support both 
Java keystores and "pem/crt/key" files.
+
+```java
+public class DefaultSslFactory extends SslFactory {
+  public DefaultSslFactory(long certRefreshInSec);
+  public void configure(String sslProviderString, String keyStoreTypeString, 
String keyStore, String keyStorePassword,
+                        String trustStoreTypeString, String trustStore, String 
trustStorePassword,
+                        Set<String> ciphers, Set<String> protocols, String 
trustCertsFilePath,
+                        String certificateFilePath, String keyFilePath, 
boolean allowInsecureConnection,
+                        boolean requireTrustedClientCertOnConnect, 
AuthenticationDataProvider authData,
+                        boolean isKeyStoreEnabled);

Review Comment:
   If PulsarSslFactory is an interface and there's a configure method that 
passes a value object with all possible configuration parameters, there won't 
be a need to have different methods for the default one. 



##########
pip/pip-333.md:
##########
@@ -0,0 +1,387 @@
+# PIP-337: SSL Factory Plugin to customize SSLContext/SSLEngine generation
+
+# Background knowledge
+Apache Pulsar supports TLS encrypted communication between the clients and 
servers. The TLS encryption setup requires
+loading the TLS certificates and its respective passwords to generate the SSL 
Context. Pulsar supports loading these 
+certificates and passwords via the filesystem. It supports both Java based 
Keystores/Truststores and TLS information in 
+".crt", ".pem" & ".key" formats. This information is refreshed based on a 
configurable interval.
+ 
+Apache Pulsar internally uses 3 different frameworks for connection management:
+
+- Netty: Connection management for Pulsar server and client that understands 
Pulsar binary protocol.
+- Jetty: HTTP Server creation for Pulsar Admin and websocket. Jetty Client is 
used by proxy for admin client calls.
+- AsyncHttpClient: HTTP Client creation for Admin client and HTTP Lookup
+
+Each of the above frameworks supports customizing the generation of the SSL 
Context and SSL Engine. Currently, Pulsar 
+uses these features to feed the SSL Context via its internal security tools 
after loading the file based certificates.
+One of the issues of using these features is that pulsar tries to bootstrap 
the SSL Context in multiple ways to suit
+each framework and file type.
+
+```mermaid
+flowchart TB
+    Proxy.DirectProxyHandler --> NettyClientSslContextRefresher
+    Proxy.DirectProxyHandler --> NettySSLContextAutoRefreshBuilder
+    Proxy.AdminProxyHandler --> KeyStoreSSLContext
+    Proxy.AdminProxyHandler --> SecurityUtility
+    Proxy.ServiceChannelInitializer --> NettySSLContextAutoRefreshBuilder
+    Proxy.ServiceChannelInitializer --> NettyServerSslContextBuilder
+    Broker.PulsarChannelInitializer --> NettyServerSslContextBuilder
+    Broker.PulsarChannelInitializer --> NettySSLContextAutoRefreshBuilder
+    Client.PulsarChannelInitializer --> NettySSLContextAutoRefreshBuilder
+    Client.PulsarChannelInitializer --> SecurityUtility
+    Broker.WebService --> JettySSlContextFactory
+    Proxy.WebServer --> JettySSlContextFactory
+    PulsarAdmin --> AsyncHttpConnector
+    AsyncHttpConnector --> KeyStoreSSLContext
+    AsyncHttpConnector --> SecurityUtility
+    JettySSlContextFactory --> NetSslContextBuilder
+    JettySSlContextFactory --> DefaultSslContextBuilder
+    NettyClientSslContextRefresher -.-> SslContextAutoRefreshBuilder
+    NettySSLContextAutoRefreshBuilder -.-> SslContextAutoRefreshBuilder
+    NettyServerSslContextBuilder -.-> SslContextAutoRefreshBuilder
+    NetSslContextBuilder -.-> SslContextAutoRefreshBuilder
+    DefaultSslContextBuilder -.-> SslContextAutoRefreshBuilder
+    Client.HttpLookup.HttpClient --> KeyStoreSSLContext
+    Client.HttpLookup.HttpClient --> SecurityUtility
+    SecurityUtility -.-> KeyManagerProxy
+    SecurityUtility -.-> TrustManagerProxy
+```
+The above diagram is an example of the complexity of the TLS encryption setup 
within Pulsar. The above diagram only
+contains the basic components of Pulsar excluding Websockets, Functions, etc.
+
+Pulsar uses 2 base classes to load the TLS information.
+
+- `SecurityUtility`: It loads files of type ".crt", ".pem" and ".key" and 
converts it into SSL Context. This SSL Context
+can be of type `io.netty.handler.ssl.SslContext` or `javax.net.ssl.SSLContext` 
based on the caller. Security Utility 
+can be used to create SSL Context that internally has KeyManager and 
Trustmanager proxies that load cert changes 
+dynamically.
+- `KeyStoreSSLContext`: It loads files of type Java Keystore/Truststore and 
converts it into SSL Context. This SSL
+Context will be of type `javax.net.ssl.SSLContext`. This is always used to 
create the SSL Engine.
+
+Each of the above classes are either directly used by Pulsar Clients or used 
via implementations of the abstract class 
+`SslContextAutoRefreshBuilder`.
+
+- `SslContextAutoRefreshBuilder` - This abstract class is used to refresh 
certificates at a configurable interval. It 
+internally provides a public API to return the SSL Context.
+
+There are several implementations of the above abstract class to suit the 
needs of each of the framework and the
+respective TLS certificate files:
+
+- `NettyClientSslContextRefresher` - It internally creates the 
`io.netty.handler.ssl.SslContext` using the ".crt", 
+".pem" and ".key" files for the proxy client.
+- `NettySSLContextAutoRefreshBuilder` - It internally creates the 
`KeyStoreSSLContext` using the Java Keystores.
+- `NettyServerSslContextBuilder` - It internally creates the 
`io.netty.handler.ssl.SslContext` using the ".crt",
+  ".pem" and ".key" files for the server.
+- `NetSslContextBuilder` - It internally creates the 
`javax.net.ssl.SSLContext` using the Java Keystores for the web 
+server.
+- `DefaultSslContextBuilder` - It internally creates the 
`javax.net.ssl.SSLContext` using the ".crt", ".pem" and ".key"
+files for the web server.
+
+# Motivation
+Apache Pulsar's TLS encryption configuration is not pluggable. It only 
supports file-based certificates. This makes 
+Pulsar difficult to adopt for organizations that require loading TLS 
certificates by other mechanisms.
+
+# Goals
+The purpose of this PIP is to introduce the following:
+
+- Provide a mechanism to plugin a custom SSL Factory that can generate SSL 
Context and SSL Engine. 
+- Simplify the Pulsar code base to universally use `javax.net.ssl.SSLContext` 
and reduce the amount of code required to
+build and configure the SSL context taking into consideration backwards 
compatibility.
+
+## In Scope
+
+- Creation of a new abstract class `SSLFactory` that can generate a SSL 
Context, Client SSL Engine and Server SSL 
+Engine. It should support refreshing the certificates at a configurable 
interval.
+- Creation of a default implementation of `SSLFactory` that supports loading 
the SSL Context and SSL Engine via
+file-based certificates. Internally it will use the SecurityUtility and 
KeyStoreSSLContext.
+- Modify the Pulsar Components to support the `SSLFactory` instead of the 
SslContextAutoRefreshBuilder, SecurityUtility
+and KeyStoreSSLContext.
+- Remove the SslContextAutoRefreshBuilder and all its implementations.
+
+# High Level Design
+```mermaid
+flowchart TB
+    Proxy.DirectProxyHandler --> Sslfactory
+    Proxy.AdminProxyHandler --> Sslfactory
+    Proxy.ServiceChannelInitializer --> Sslfactory
+    Broker.PulsarChannelInitializer --> Sslfactory
+    Client.PulsarChannelInitializer --> Sslfactory
+    Broker.WebService --> JettySSlContextFactory
+    Proxy.WebServer --> JettySSlContextFactory
+    PulsarAdmin --> AsyncHttpConnector
+    AsyncHttpConnector --> Sslfactory
+    JettySSlContextFactory --> Sslfactory
+    Client.HttpLookup.HttpClient --> Sslfactory
+    Sslfactory -.-> DefaultSslFactory
+    Sslfactory -.-> CustomSslFactory
+```
+
+# Detailed Design
+
+## Design and Implementation Details
+
+### Pulsar Common Changes
+
+A new abstract class called `SslFactory` that provides public methods to 
create a SSL Context, Client SSL Engine and
+Server SSL Engine. The SSL Context class returned will be of type 
`javax.net.ssl.SSLContext`. This class will refresh 
+the SSL Context at the configured interval. This refresh behavior is the same 
as the 
+current `SslContextAutoRefreshBuilder`.
+
+```java
+public abstract class SslFactory {
+    public SslFactory(long certRefreshInSec);
+    public abstract SSLEngine getClientSslEngine(String peerHost, int 
peerPort);
+    public abstract SSLEngine getServerSslEngine() throws 
GeneralSecurityException, IOException;
+    public abstract boolean needsUpdate();
+    public abstract void update() throws Exception;
+    public abstract void configure(String sslProviderString, 
+                                   Set<String> ciphers, 
+                                   Set<String> protocols, 
+                                   boolean allowInsecureConnection, 
+                                   boolean requireTrustedClientCertOnConnect, 
+                                   AuthenticationDataProvider authData, 
+                                   String tlsCustomParams);
+    // Implementation similar to SslContextAutoRefreshBuilder class which will 
be threadsafe
+    public SSLContext getInternalSslContext();
+}
+```
+
+A default implementation of the above SSLFactory class called 
`DefaultSslFactory` that will generate the SSL Context 
+and SSL Engines using File-based Certificates. It will be able to support both 
Java keystores and "pem/crt/key" files.
+
+```java
+public class DefaultSslFactory extends SslFactory {
+  public DefaultSslFactory(long certRefreshInSec);
+  public void configure(String sslProviderString, String keyStoreTypeString, 
String keyStore, String keyStorePassword,
+                        String trustStoreTypeString, String trustStore, String 
trustStorePassword,
+                        Set<String> ciphers, Set<String> protocols, String 
trustCertsFilePath,
+                        String certificateFilePath, String keyFilePath, 
boolean allowInsecureConnection,
+                        boolean requireTrustedClientCertOnConnect, 
AuthenticationDataProvider authData,
+                        boolean isKeyStoreEnabled);
+  public SSLEngine getClientSslEngine(String peerHost, int peerPort);
+  public SSLEngine getServerSslEngine();
+  public boolean needsUpdate();
+  public void update() throws Exception;
+  //The below will be a noop
+  public void configure(String sslProviderString,
+                        Set<String> ciphers,
+                        Set<String> protocols,
+                        boolean allowInsecureConnection,
+                        boolean requireTrustedClientCertOnConnect,
+                        AuthenticationDataProvider authData,
+                        String tlsCustomParams);
+}
+```
+
+### Pulsar Commmon Changes
+
+6 new configurations will need to be added into the Configurations like 
`ServiceConfiguration`, 
+`ClientConfigurationData`, `ProxyConfiguration`, etc. All of the below will be 
optional. It will use the default values
+to match the current behavior of Pulsar.
+
+- `sslFactoryPlugin`: SSL Factory Plugin class to provide SSLEngine and 
SSLContext objects.
+The default class used is `DefaultSslFactory`.
+- `sslFactoryPluginParams`: SSL Factory plugin configuration parameters. It 
will be of type string. It can be parsed by
+the plugin at its discretion.
+- `sslFactorySslContextInitTimeoutInMs`: SSL Context initialization timeout in 
ms for the first time it is initialized 
+by the SSLFactory
+
+The below configs will be applicable only to the Pulsar Server components like 
Broker and Proxy:
+- `brokerClientSslFactoryPlugin`: SSL Factory Plugin class used by internal 
client to provide SSLEngine and SSLContext 
+objects. The default class used is `DefaultSslFactory`.
+- `brokerClientSslFactoryPluginParams`: SSL Factory plugin configuration 
parameters used by internal client. It can be 
+parsed by the plugin at its discretion.
+- `brokerClientsslFactorySslContextInitTimeoutInMs`: SSL Context 
initialization timeout in ms for the first time 
+it is initialized by the SSLFactory in the internal client
+
+`JettySslContextFactory` class will need to be changed to internally use the 
`SslFactory` class to generate the 
+SslContext.
+
+### SslFactory Usage across Pulsar Netty based server components
+
+Example Changes in broker's `PulsarChannelInitializer` to initialize the 
SslFactory:
+```java
+sslFactory = (SslFactory) Class.forName(config.getSslFactoryPlugin())
+                    .getDeclaredConstructor(Long.TYPE, LONG.TYPE)
+                    .newInstance(config.getTlsCertRefreshCheckDurationSec(),
+                                 
config.getSslFactorySslContextInitTimeoutInMs);
+if (this.sslFactory instanceof DefaultSslFactory) {

Review Comment:
   Please see the previous comment of having a solution where the 
PulsarSslFactory interface's confgiure method would pass in a value object with 
all possible configuration options. In that case there wouldn't need to be any 
conditional login here.



##########
pip/pip-333.md:
##########
@@ -0,0 +1,387 @@
+# PIP-337: SSL Factory Plugin to customize SSLContext/SSLEngine generation
+
+# Background knowledge
+Apache Pulsar supports TLS encrypted communication between the clients and 
servers. The TLS encryption setup requires
+loading the TLS certificates and its respective passwords to generate the SSL 
Context. Pulsar supports loading these 
+certificates and passwords via the filesystem. It supports both Java based 
Keystores/Truststores and TLS information in 
+".crt", ".pem" & ".key" formats. This information is refreshed based on a 
configurable interval.
+ 
+Apache Pulsar internally uses 3 different frameworks for connection management:
+
+- Netty: Connection management for Pulsar server and client that understands 
Pulsar binary protocol.
+- Jetty: HTTP Server creation for Pulsar Admin and websocket. Jetty Client is 
used by proxy for admin client calls.
+- AsyncHttpClient: HTTP Client creation for Admin client and HTTP Lookup
+
+Each of the above frameworks supports customizing the generation of the SSL 
Context and SSL Engine. Currently, Pulsar 
+uses these features to feed the SSL Context via its internal security tools 
after loading the file based certificates.
+One of the issues of using these features is that pulsar tries to bootstrap 
the SSL Context in multiple ways to suit
+each framework and file type.
+
+```mermaid
+flowchart TB
+    Proxy.DirectProxyHandler --> NettyClientSslContextRefresher
+    Proxy.DirectProxyHandler --> NettySSLContextAutoRefreshBuilder
+    Proxy.AdminProxyHandler --> KeyStoreSSLContext
+    Proxy.AdminProxyHandler --> SecurityUtility
+    Proxy.ServiceChannelInitializer --> NettySSLContextAutoRefreshBuilder
+    Proxy.ServiceChannelInitializer --> NettyServerSslContextBuilder
+    Broker.PulsarChannelInitializer --> NettyServerSslContextBuilder
+    Broker.PulsarChannelInitializer --> NettySSLContextAutoRefreshBuilder
+    Client.PulsarChannelInitializer --> NettySSLContextAutoRefreshBuilder
+    Client.PulsarChannelInitializer --> SecurityUtility
+    Broker.WebService --> JettySSlContextFactory
+    Proxy.WebServer --> JettySSlContextFactory
+    PulsarAdmin --> AsyncHttpConnector
+    AsyncHttpConnector --> KeyStoreSSLContext
+    AsyncHttpConnector --> SecurityUtility
+    JettySSlContextFactory --> NetSslContextBuilder
+    JettySSlContextFactory --> DefaultSslContextBuilder
+    NettyClientSslContextRefresher -.-> SslContextAutoRefreshBuilder
+    NettySSLContextAutoRefreshBuilder -.-> SslContextAutoRefreshBuilder
+    NettyServerSslContextBuilder -.-> SslContextAutoRefreshBuilder
+    NetSslContextBuilder -.-> SslContextAutoRefreshBuilder
+    DefaultSslContextBuilder -.-> SslContextAutoRefreshBuilder
+    Client.HttpLookup.HttpClient --> KeyStoreSSLContext
+    Client.HttpLookup.HttpClient --> SecurityUtility
+    SecurityUtility -.-> KeyManagerProxy
+    SecurityUtility -.-> TrustManagerProxy
+```
+The above diagram is an example of the complexity of the TLS encryption setup 
within Pulsar. The above diagram only
+contains the basic components of Pulsar excluding Websockets, Functions, etc.
+
+Pulsar uses 2 base classes to load the TLS information.
+
+- `SecurityUtility`: It loads files of type ".crt", ".pem" and ".key" and 
converts it into SSL Context. This SSL Context
+can be of type `io.netty.handler.ssl.SslContext` or `javax.net.ssl.SSLContext` 
based on the caller. Security Utility 
+can be used to create SSL Context that internally has KeyManager and 
Trustmanager proxies that load cert changes 
+dynamically.
+- `KeyStoreSSLContext`: It loads files of type Java Keystore/Truststore and 
converts it into SSL Context. This SSL
+Context will be of type `javax.net.ssl.SSLContext`. This is always used to 
create the SSL Engine.
+
+Each of the above classes are either directly used by Pulsar Clients or used 
via implementations of the abstract class 
+`SslContextAutoRefreshBuilder`.
+
+- `SslContextAutoRefreshBuilder` - This abstract class is used to refresh 
certificates at a configurable interval. It 
+internally provides a public API to return the SSL Context.
+
+There are several implementations of the above abstract class to suit the 
needs of each of the framework and the
+respective TLS certificate files:
+
+- `NettyClientSslContextRefresher` - It internally creates the 
`io.netty.handler.ssl.SslContext` using the ".crt", 
+".pem" and ".key" files for the proxy client.
+- `NettySSLContextAutoRefreshBuilder` - It internally creates the 
`KeyStoreSSLContext` using the Java Keystores.
+- `NettyServerSslContextBuilder` - It internally creates the 
`io.netty.handler.ssl.SslContext` using the ".crt",
+  ".pem" and ".key" files for the server.
+- `NetSslContextBuilder` - It internally creates the 
`javax.net.ssl.SSLContext` using the Java Keystores for the web 
+server.
+- `DefaultSslContextBuilder` - It internally creates the 
`javax.net.ssl.SSLContext` using the ".crt", ".pem" and ".key"
+files for the web server.
+
+# Motivation
+Apache Pulsar's TLS encryption configuration is not pluggable. It only 
supports file-based certificates. This makes 
+Pulsar difficult to adopt for organizations that require loading TLS 
certificates by other mechanisms.
+
+# Goals
+The purpose of this PIP is to introduce the following:
+
+- Provide a mechanism to plugin a custom SSL Factory that can generate SSL 
Context and SSL Engine. 
+- Simplify the Pulsar code base to universally use `javax.net.ssl.SSLContext` 
and reduce the amount of code required to
+build and configure the SSL context taking into consideration backwards 
compatibility.
+
+## In Scope
+
+- Creation of a new abstract class `SSLFactory` that can generate a SSL 
Context, Client SSL Engine and Server SSL 
+Engine. It should support refreshing the certificates at a configurable 
interval.
+- Creation of a default implementation of `SSLFactory` that supports loading 
the SSL Context and SSL Engine via
+file-based certificates. Internally it will use the SecurityUtility and 
KeyStoreSSLContext.
+- Modify the Pulsar Components to support the `SSLFactory` instead of the 
SslContextAutoRefreshBuilder, SecurityUtility
+and KeyStoreSSLContext.
+- Remove the SslContextAutoRefreshBuilder and all its implementations.
+
+# High Level Design
+```mermaid
+flowchart TB
+    Proxy.DirectProxyHandler --> Sslfactory
+    Proxy.AdminProxyHandler --> Sslfactory
+    Proxy.ServiceChannelInitializer --> Sslfactory
+    Broker.PulsarChannelInitializer --> Sslfactory
+    Client.PulsarChannelInitializer --> Sslfactory
+    Broker.WebService --> JettySSlContextFactory
+    Proxy.WebServer --> JettySSlContextFactory
+    PulsarAdmin --> AsyncHttpConnector
+    AsyncHttpConnector --> Sslfactory
+    JettySSlContextFactory --> Sslfactory
+    Client.HttpLookup.HttpClient --> Sslfactory
+    Sslfactory -.-> DefaultSslFactory
+    Sslfactory -.-> CustomSslFactory
+```
+
+# Detailed Design
+
+## Design and Implementation Details
+
+### Pulsar Common Changes
+
+A new abstract class called `SslFactory` that provides public methods to 
create a SSL Context, Client SSL Engine and
+Server SSL Engine. The SSL Context class returned will be of type 
`javax.net.ssl.SSLContext`. This class will refresh 
+the SSL Context at the configured interval. This refresh behavior is the same 
as the 
+current `SslContextAutoRefreshBuilder`.
+
+```java
+public abstract class SslFactory {
+    public SslFactory(long certRefreshInSec);
+    public abstract SSLEngine getClientSslEngine(String peerHost, int 
peerPort);
+    public abstract SSLEngine getServerSslEngine() throws 
GeneralSecurityException, IOException;
+    public abstract boolean needsUpdate();
+    public abstract void update() throws Exception;
+    public abstract void configure(String sslProviderString, 
+                                   Set<String> ciphers, 
+                                   Set<String> protocols, 
+                                   boolean allowInsecureConnection, 
+                                   boolean requireTrustedClientCertOnConnect, 
+                                   AuthenticationDataProvider authData, 
+                                   String tlsCustomParams);

Review Comment:
   This is a long list of parameters for a method call. I think that there will 
need to be some intermediate value object that holds the possible configuration.



##########
pip/pip-333.md:
##########
@@ -0,0 +1,387 @@
+# PIP-337: SSL Factory Plugin to customize SSLContext/SSLEngine generation
+
+# Background knowledge
+Apache Pulsar supports TLS encrypted communication between the clients and 
servers. The TLS encryption setup requires
+loading the TLS certificates and its respective passwords to generate the SSL 
Context. Pulsar supports loading these 
+certificates and passwords via the filesystem. It supports both Java based 
Keystores/Truststores and TLS information in 
+".crt", ".pem" & ".key" formats. This information is refreshed based on a 
configurable interval.
+ 
+Apache Pulsar internally uses 3 different frameworks for connection management:
+
+- Netty: Connection management for Pulsar server and client that understands 
Pulsar binary protocol.
+- Jetty: HTTP Server creation for Pulsar Admin and websocket. Jetty Client is 
used by proxy for admin client calls.
+- AsyncHttpClient: HTTP Client creation for Admin client and HTTP Lookup
+
+Each of the above frameworks supports customizing the generation of the SSL 
Context and SSL Engine. Currently, Pulsar 
+uses these features to feed the SSL Context via its internal security tools 
after loading the file based certificates.
+One of the issues of using these features is that pulsar tries to bootstrap 
the SSL Context in multiple ways to suit
+each framework and file type.
+
+```mermaid
+flowchart TB
+    Proxy.DirectProxyHandler --> NettyClientSslContextRefresher
+    Proxy.DirectProxyHandler --> NettySSLContextAutoRefreshBuilder
+    Proxy.AdminProxyHandler --> KeyStoreSSLContext
+    Proxy.AdminProxyHandler --> SecurityUtility
+    Proxy.ServiceChannelInitializer --> NettySSLContextAutoRefreshBuilder
+    Proxy.ServiceChannelInitializer --> NettyServerSslContextBuilder
+    Broker.PulsarChannelInitializer --> NettyServerSslContextBuilder
+    Broker.PulsarChannelInitializer --> NettySSLContextAutoRefreshBuilder
+    Client.PulsarChannelInitializer --> NettySSLContextAutoRefreshBuilder
+    Client.PulsarChannelInitializer --> SecurityUtility
+    Broker.WebService --> JettySSlContextFactory
+    Proxy.WebServer --> JettySSlContextFactory
+    PulsarAdmin --> AsyncHttpConnector
+    AsyncHttpConnector --> KeyStoreSSLContext
+    AsyncHttpConnector --> SecurityUtility
+    JettySSlContextFactory --> NetSslContextBuilder
+    JettySSlContextFactory --> DefaultSslContextBuilder
+    NettyClientSslContextRefresher -.-> SslContextAutoRefreshBuilder
+    NettySSLContextAutoRefreshBuilder -.-> SslContextAutoRefreshBuilder
+    NettyServerSslContextBuilder -.-> SslContextAutoRefreshBuilder
+    NetSslContextBuilder -.-> SslContextAutoRefreshBuilder
+    DefaultSslContextBuilder -.-> SslContextAutoRefreshBuilder
+    Client.HttpLookup.HttpClient --> KeyStoreSSLContext
+    Client.HttpLookup.HttpClient --> SecurityUtility
+    SecurityUtility -.-> KeyManagerProxy
+    SecurityUtility -.-> TrustManagerProxy
+```
+The above diagram is an example of the complexity of the TLS encryption setup 
within Pulsar. The above diagram only
+contains the basic components of Pulsar excluding Websockets, Functions, etc.
+
+Pulsar uses 2 base classes to load the TLS information.
+
+- `SecurityUtility`: It loads files of type ".crt", ".pem" and ".key" and 
converts it into SSL Context. This SSL Context
+can be of type `io.netty.handler.ssl.SslContext` or `javax.net.ssl.SSLContext` 
based on the caller. Security Utility 
+can be used to create SSL Context that internally has KeyManager and 
Trustmanager proxies that load cert changes 
+dynamically.
+- `KeyStoreSSLContext`: It loads files of type Java Keystore/Truststore and 
converts it into SSL Context. This SSL
+Context will be of type `javax.net.ssl.SSLContext`. This is always used to 
create the SSL Engine.
+
+Each of the above classes are either directly used by Pulsar Clients or used 
via implementations of the abstract class 
+`SslContextAutoRefreshBuilder`.
+
+- `SslContextAutoRefreshBuilder` - This abstract class is used to refresh 
certificates at a configurable interval. It 
+internally provides a public API to return the SSL Context.
+
+There are several implementations of the above abstract class to suit the 
needs of each of the framework and the
+respective TLS certificate files:
+
+- `NettyClientSslContextRefresher` - It internally creates the 
`io.netty.handler.ssl.SslContext` using the ".crt", 
+".pem" and ".key" files for the proxy client.
+- `NettySSLContextAutoRefreshBuilder` - It internally creates the 
`KeyStoreSSLContext` using the Java Keystores.
+- `NettyServerSslContextBuilder` - It internally creates the 
`io.netty.handler.ssl.SslContext` using the ".crt",
+  ".pem" and ".key" files for the server.
+- `NetSslContextBuilder` - It internally creates the 
`javax.net.ssl.SSLContext` using the Java Keystores for the web 
+server.
+- `DefaultSslContextBuilder` - It internally creates the 
`javax.net.ssl.SSLContext` using the ".crt", ".pem" and ".key"
+files for the web server.
+
+# Motivation
+Apache Pulsar's TLS encryption configuration is not pluggable. It only 
supports file-based certificates. This makes 
+Pulsar difficult to adopt for organizations that require loading TLS 
certificates by other mechanisms.
+
+# Goals
+The purpose of this PIP is to introduce the following:
+
+- Provide a mechanism to plugin a custom SSL Factory that can generate SSL 
Context and SSL Engine. 
+- Simplify the Pulsar code base to universally use `javax.net.ssl.SSLContext` 
and reduce the amount of code required to
+build and configure the SSL context taking into consideration backwards 
compatibility.
+
+## In Scope
+
+- Creation of a new abstract class `SSLFactory` that can generate a SSL 
Context, Client SSL Engine and Server SSL 
+Engine. It should support refreshing the certificates at a configurable 
interval.
+- Creation of a default implementation of `SSLFactory` that supports loading 
the SSL Context and SSL Engine via
+file-based certificates. Internally it will use the SecurityUtility and 
KeyStoreSSLContext.
+- Modify the Pulsar Components to support the `SSLFactory` instead of the 
SslContextAutoRefreshBuilder, SecurityUtility
+and KeyStoreSSLContext.
+- Remove the SslContextAutoRefreshBuilder and all its implementations.
+
+# High Level Design
+```mermaid
+flowchart TB
+    Proxy.DirectProxyHandler --> Sslfactory
+    Proxy.AdminProxyHandler --> Sslfactory
+    Proxy.ServiceChannelInitializer --> Sslfactory
+    Broker.PulsarChannelInitializer --> Sslfactory
+    Client.PulsarChannelInitializer --> Sslfactory
+    Broker.WebService --> JettySSlContextFactory
+    Proxy.WebServer --> JettySSlContextFactory
+    PulsarAdmin --> AsyncHttpConnector
+    AsyncHttpConnector --> Sslfactory
+    JettySSlContextFactory --> Sslfactory
+    Client.HttpLookup.HttpClient --> Sslfactory
+    Sslfactory -.-> DefaultSslFactory
+    Sslfactory -.-> CustomSslFactory
+```
+
+# Detailed Design
+
+## Design and Implementation Details
+
+### Pulsar Common Changes
+
+A new abstract class called `SslFactory` that provides public methods to 
create a SSL Context, Client SSL Engine and
+Server SSL Engine. The SSL Context class returned will be of type 
`javax.net.ssl.SSLContext`. This class will refresh 
+the SSL Context at the configured interval. This refresh behavior is the same 
as the 
+current `SslContextAutoRefreshBuilder`.
+
+```java
+public abstract class SslFactory {
+    public SslFactory(long certRefreshInSec);
+    public abstract SSLEngine getClientSslEngine(String peerHost, int 
peerPort);
+    public abstract SSLEngine getServerSslEngine() throws 
GeneralSecurityException, IOException;
+    public abstract boolean needsUpdate();
+    public abstract void update() throws Exception;

Review Comment:
   Add javadocs for `needsUpdate` and `update` to make it clear how they are 
are intended to work.



##########
pip/pip-333.md:
##########
@@ -0,0 +1,387 @@
+# PIP-337: SSL Factory Plugin to customize SSLContext/SSLEngine generation
+
+# Background knowledge
+Apache Pulsar supports TLS encrypted communication between the clients and 
servers. The TLS encryption setup requires
+loading the TLS certificates and its respective passwords to generate the SSL 
Context. Pulsar supports loading these 
+certificates and passwords via the filesystem. It supports both Java based 
Keystores/Truststores and TLS information in 
+".crt", ".pem" & ".key" formats. This information is refreshed based on a 
configurable interval.
+ 
+Apache Pulsar internally uses 3 different frameworks for connection management:
+
+- Netty: Connection management for Pulsar server and client that understands 
Pulsar binary protocol.
+- Jetty: HTTP Server creation for Pulsar Admin and websocket. Jetty Client is 
used by proxy for admin client calls.
+- AsyncHttpClient: HTTP Client creation for Admin client and HTTP Lookup
+
+Each of the above frameworks supports customizing the generation of the SSL 
Context and SSL Engine. Currently, Pulsar 
+uses these features to feed the SSL Context via its internal security tools 
after loading the file based certificates.
+One of the issues of using these features is that pulsar tries to bootstrap 
the SSL Context in multiple ways to suit
+each framework and file type.
+
+```mermaid
+flowchart TB
+    Proxy.DirectProxyHandler --> NettyClientSslContextRefresher
+    Proxy.DirectProxyHandler --> NettySSLContextAutoRefreshBuilder
+    Proxy.AdminProxyHandler --> KeyStoreSSLContext
+    Proxy.AdminProxyHandler --> SecurityUtility
+    Proxy.ServiceChannelInitializer --> NettySSLContextAutoRefreshBuilder
+    Proxy.ServiceChannelInitializer --> NettyServerSslContextBuilder
+    Broker.PulsarChannelInitializer --> NettyServerSslContextBuilder
+    Broker.PulsarChannelInitializer --> NettySSLContextAutoRefreshBuilder
+    Client.PulsarChannelInitializer --> NettySSLContextAutoRefreshBuilder
+    Client.PulsarChannelInitializer --> SecurityUtility
+    Broker.WebService --> JettySSlContextFactory
+    Proxy.WebServer --> JettySSlContextFactory
+    PulsarAdmin --> AsyncHttpConnector
+    AsyncHttpConnector --> KeyStoreSSLContext
+    AsyncHttpConnector --> SecurityUtility
+    JettySSlContextFactory --> NetSslContextBuilder
+    JettySSlContextFactory --> DefaultSslContextBuilder
+    NettyClientSslContextRefresher -.-> SslContextAutoRefreshBuilder
+    NettySSLContextAutoRefreshBuilder -.-> SslContextAutoRefreshBuilder
+    NettyServerSslContextBuilder -.-> SslContextAutoRefreshBuilder
+    NetSslContextBuilder -.-> SslContextAutoRefreshBuilder
+    DefaultSslContextBuilder -.-> SslContextAutoRefreshBuilder
+    Client.HttpLookup.HttpClient --> KeyStoreSSLContext
+    Client.HttpLookup.HttpClient --> SecurityUtility
+    SecurityUtility -.-> KeyManagerProxy
+    SecurityUtility -.-> TrustManagerProxy
+```
+The above diagram is an example of the complexity of the TLS encryption setup 
within Pulsar. The above diagram only
+contains the basic components of Pulsar excluding Websockets, Functions, etc.
+
+Pulsar uses 2 base classes to load the TLS information.
+
+- `SecurityUtility`: It loads files of type ".crt", ".pem" and ".key" and 
converts it into SSL Context. This SSL Context
+can be of type `io.netty.handler.ssl.SslContext` or `javax.net.ssl.SSLContext` 
based on the caller. Security Utility 
+can be used to create SSL Context that internally has KeyManager and 
Trustmanager proxies that load cert changes 
+dynamically.
+- `KeyStoreSSLContext`: It loads files of type Java Keystore/Truststore and 
converts it into SSL Context. This SSL
+Context will be of type `javax.net.ssl.SSLContext`. This is always used to 
create the SSL Engine.
+
+Each of the above classes are either directly used by Pulsar Clients or used 
via implementations of the abstract class 
+`SslContextAutoRefreshBuilder`.
+
+- `SslContextAutoRefreshBuilder` - This abstract class is used to refresh 
certificates at a configurable interval. It 
+internally provides a public API to return the SSL Context.
+
+There are several implementations of the above abstract class to suit the 
needs of each of the framework and the
+respective TLS certificate files:
+
+- `NettyClientSslContextRefresher` - It internally creates the 
`io.netty.handler.ssl.SslContext` using the ".crt", 
+".pem" and ".key" files for the proxy client.
+- `NettySSLContextAutoRefreshBuilder` - It internally creates the 
`KeyStoreSSLContext` using the Java Keystores.
+- `NettyServerSslContextBuilder` - It internally creates the 
`io.netty.handler.ssl.SslContext` using the ".crt",
+  ".pem" and ".key" files for the server.
+- `NetSslContextBuilder` - It internally creates the 
`javax.net.ssl.SSLContext` using the Java Keystores for the web 
+server.
+- `DefaultSslContextBuilder` - It internally creates the 
`javax.net.ssl.SSLContext` using the ".crt", ".pem" and ".key"
+files for the web server.
+
+# Motivation
+Apache Pulsar's TLS encryption configuration is not pluggable. It only 
supports file-based certificates. This makes 
+Pulsar difficult to adopt for organizations that require loading TLS 
certificates by other mechanisms.
+
+# Goals
+The purpose of this PIP is to introduce the following:
+
+- Provide a mechanism to plugin a custom SSL Factory that can generate SSL 
Context and SSL Engine. 
+- Simplify the Pulsar code base to universally use `javax.net.ssl.SSLContext` 
and reduce the amount of code required to
+build and configure the SSL context taking into consideration backwards 
compatibility.
+
+## In Scope
+
+- Creation of a new abstract class `SSLFactory` that can generate a SSL 
Context, Client SSL Engine and Server SSL 
+Engine. It should support refreshing the certificates at a configurable 
interval.
+- Creation of a default implementation of `SSLFactory` that supports loading 
the SSL Context and SSL Engine via
+file-based certificates. Internally it will use the SecurityUtility and 
KeyStoreSSLContext.
+- Modify the Pulsar Components to support the `SSLFactory` instead of the 
SslContextAutoRefreshBuilder, SecurityUtility
+and KeyStoreSSLContext.
+- Remove the SslContextAutoRefreshBuilder and all its implementations.
+
+# High Level Design
+```mermaid
+flowchart TB
+    Proxy.DirectProxyHandler --> Sslfactory
+    Proxy.AdminProxyHandler --> Sslfactory
+    Proxy.ServiceChannelInitializer --> Sslfactory
+    Broker.PulsarChannelInitializer --> Sslfactory
+    Client.PulsarChannelInitializer --> Sslfactory
+    Broker.WebService --> JettySSlContextFactory
+    Proxy.WebServer --> JettySSlContextFactory
+    PulsarAdmin --> AsyncHttpConnector
+    AsyncHttpConnector --> Sslfactory
+    JettySSlContextFactory --> Sslfactory
+    Client.HttpLookup.HttpClient --> Sslfactory
+    Sslfactory -.-> DefaultSslFactory
+    Sslfactory -.-> CustomSslFactory
+```
+
+# Detailed Design
+
+## Design and Implementation Details
+
+### Pulsar Common Changes
+
+A new abstract class called `SslFactory` that provides public methods to 
create a SSL Context, Client SSL Engine and
+Server SSL Engine. The SSL Context class returned will be of type 
`javax.net.ssl.SSLContext`. This class will refresh 
+the SSL Context at the configured interval. This refresh behavior is the same 
as the 
+current `SslContextAutoRefreshBuilder`.
+
+```java
+public abstract class SslFactory {
+    public SslFactory(long certRefreshInSec);
+    public abstract SSLEngine getClientSslEngine(String peerHost, int 
peerPort);
+    public abstract SSLEngine getServerSslEngine() throws 
GeneralSecurityException, IOException;
+    public abstract boolean needsUpdate();
+    public abstract void update() throws Exception;
+    public abstract void configure(String sslProviderString, 
+                                   Set<String> ciphers, 
+                                   Set<String> protocols, 
+                                   boolean allowInsecureConnection, 
+                                   boolean requireTrustedClientCertOnConnect, 
+                                   AuthenticationDataProvider authData, 
+                                   String tlsCustomParams);
+    // Implementation similar to SslContextAutoRefreshBuilder class which will 
be threadsafe
+    public SSLContext getInternalSslContext();

Review Comment:
   Does this create a new instance? (would be `create*` in that case)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to