2222import io .netty .handler .codec .http .HttpServerCodec ;
2323import io .netty .handler .codec .http .websocketx .WebSocketServerProtocolHandler ;
2424import io .netty .handler .codec .mqtt .MqttDecoder ;
25+ import io .netty .handler .ssl .SslContext ;
2526import io .netty .handler .ssl .SslHandler ;
2627import io .netty .handler .timeout .IdleStateHandler ;
2728import io .streamnative .pulsar .handlers .mqtt .broker .MQTTServerConfiguration ;
3233import io .streamnative .pulsar .handlers .mqtt .common .adapter .MqttAdapterDecoder ;
3334import io .streamnative .pulsar .handlers .mqtt .common .adapter .MqttAdapterEncoder ;
3435import io .streamnative .pulsar .handlers .mqtt .common .psk .PSKUtils ;
35- import java .util .concurrent .ScheduledExecutorService ;
36- import java .util .concurrent .TimeUnit ;
37- import lombok .extern .slf4j .Slf4j ;
38- import org .apache .pulsar .common .util .PulsarSslConfiguration ;
39- import org .apache .pulsar .common .util .PulsarSslFactory ;
36+ import org .apache .pulsar .common .util .NettyServerSslContextBuilder ;
37+ import org .apache .pulsar .common .util .SslContextAutoRefreshBuilder ;
38+ import org .apache .pulsar .common .util .keystoretls .NettySSLContextAutoRefreshBuilder ;
4039
4140/**
4241 * A channel initializer that initialize channels for MQTT protocol.
4342 */
44- @ Slf4j
4543public class MQTTChannelInitializer extends ChannelInitializer <SocketChannel > {
4644
4745 private final MQTTServerConfiguration mqttConfig ;
4846 private final MQTTService mqttService ;
4947 private final boolean enableTls ;
5048 private final boolean enableTlsPsk ;
5149 private final boolean enableWs ;
52- private PulsarSslFactory sslFactory ;
50+ private final boolean tlsEnabledWithKeyStore ;
5351
54- public MQTTChannelInitializer (MQTTService mqttService , boolean enableTls , boolean enableWs ,
55- ScheduledExecutorService sslContextRefresher ) throws Exception {
56- this (mqttService , enableTls , false , enableWs , sslContextRefresher );
52+ private SslContextAutoRefreshBuilder <SslContext > sslCtxRefresher ;
53+ private NettySSLContextAutoRefreshBuilder nettySSLContextAutoRefreshBuilder ;
54+
55+ public MQTTChannelInitializer (MQTTService mqttService , boolean enableTls , boolean enableWs ) {
56+ this (mqttService , enableTls , false , enableWs );
5757 }
5858
59- public MQTTChannelInitializer (
60- MQTTService mqttService , boolean enableTls , boolean enableTlsPsk , boolean enableWs ,
61- ScheduledExecutorService sslContextRefresher ) throws Exception {
59+ public MQTTChannelInitializer (MQTTService mqttService , boolean enableTls , boolean enableTlsPsk , boolean enableWs ) {
6260 super ();
6361 this .mqttService = mqttService ;
6462 this .mqttConfig = mqttService .getServerConfiguration ();
6563 this .enableTls = enableTls ;
6664 this .enableTlsPsk = enableTlsPsk ;
6765 this .enableWs = enableWs ;
66+ this .tlsEnabledWithKeyStore = mqttConfig .isMqttTlsEnabledWithKeyStore ();
6867 if (this .enableTls ) {
69- PulsarSslConfiguration sslConfiguration = buildSslConfiguration (mqttConfig );
70- this .sslFactory = (PulsarSslFactory ) Class .forName (mqttConfig .getSslFactoryPlugin ())
71- .getConstructor ().newInstance ();
72- this .sslFactory .initialize (sslConfiguration );
73- this .sslFactory .createInternalSslContext ();
74- if (mqttConfig .getTlsCertRefreshCheckDurationSec () > 0 ) {
75- sslContextRefresher .scheduleWithFixedDelay (this ::refreshSslContext ,
76- mqttConfig .getTlsCertRefreshCheckDurationSec (),
77- mqttConfig .getTlsCertRefreshCheckDurationSec (), TimeUnit .SECONDS );
68+ if (tlsEnabledWithKeyStore ) {
69+ nettySSLContextAutoRefreshBuilder = new NettySSLContextAutoRefreshBuilder (
70+ mqttConfig .getMqttTlsProvider (),
71+ mqttConfig .getMqttTlsKeyStoreType (),
72+ mqttConfig .getMqttTlsKeyStore (),
73+ mqttConfig .getMqttTlsKeyStorePassword (),
74+ mqttConfig .isMqttTlsAllowInsecureConnection (),
75+ mqttConfig .getMqttTlsTrustStoreType (),
76+ mqttConfig .getMqttTlsTrustStore (),
77+ mqttConfig .getMqttTlsTrustStorePassword (),
78+ mqttConfig .isMqttTlsRequireTrustedClientCertOnConnect (),
79+ mqttConfig .getMqttTlsCiphers (),
80+ mqttConfig .getMqttTlsProtocols (),
81+ mqttConfig .getMqttTlsCertRefreshCheckDurationSec ());
82+ } else {
83+ sslCtxRefresher = new NettyServerSslContextBuilder (
84+ null ,
85+ mqttConfig .isMqttTlsAllowInsecureConnection (),
86+ mqttConfig .getMqttTlsTrustCertsFilePath (),
87+ mqttConfig .getMqttTlsCertificateFilePath (),
88+ mqttConfig .getMqttTlsKeyFilePath (),
89+ mqttConfig .getMqttTlsCiphers (),
90+ mqttConfig .getMqttTlsProtocols (),
91+ mqttConfig .isMqttTlsRequireTrustedClientCertOnConnect (),
92+ mqttConfig .getMqttTlsCertRefreshCheckDurationSec ());
7893 }
7994 }
8095 }
@@ -83,7 +98,12 @@ public MQTTChannelInitializer(
8398 public void initChannel (SocketChannel ch ) throws Exception {
8499 ch .pipeline ().addFirst ("idleStateHandler" , new IdleStateHandler (0 , 0 , 120 ));
85100 if (this .enableTls ) {
86- ch .pipeline ().addLast (TLS_HANDLER , new SslHandler (sslFactory .createServerSslEngine (ch .alloc ())));
101+ if (this .tlsEnabledWithKeyStore ) {
102+ ch .pipeline ().addLast (TLS_HANDLER ,
103+ new SslHandler (nettySSLContextAutoRefreshBuilder .get ().createSSLEngine ()));
104+ } else {
105+ ch .pipeline ().addLast (TLS_HANDLER , sslCtxRefresher .get ().newHandler (ch .alloc ()));
106+ }
87107 } else if (this .enableTlsPsk ) {
88108 ch .pipeline ().addLast (TLS_HANDLER ,
89109 new SslHandler (PSKUtils .createServerEngine (ch , mqttService .getPskConfiguration ())));
@@ -121,36 +141,4 @@ private void addWsHandler(ChannelPipeline pipeline) {
121141 true , mqttConfig .getWebSocketMaxFrameSize ()));
122142 pipeline .addLast (Constants .HANDLER_MQTT_WEB_SOCKET_CODEC , new MqttWebSocketCodec ());
123143 }
124-
125- protected PulsarSslConfiguration buildSslConfiguration (MQTTServerConfiguration config ) {
126- return PulsarSslConfiguration .builder ()
127- .tlsProvider (config .getMqttTlsProvider ())
128- .tlsKeyStoreType (config .getMqttTlsKeyStoreType ())
129- .tlsKeyStorePath (config .getMqttTlsKeyStore ())
130- .tlsKeyStorePassword (config .getMqttTlsKeyStorePassword ())
131- .tlsTrustStoreType (config .getMqttTlsTrustStoreType ())
132- .tlsTrustStorePath (config .getMqttTlsTrustStore ())
133- .tlsTrustStorePassword (config .getMqttTlsTrustStorePassword ())
134- .tlsCiphers (config .getMqttTlsCiphers ())
135- .tlsProtocols (config .getMqttTlsProtocols ())
136- .tlsTrustCertsFilePath (config .getMqttTlsTrustCertsFilePath ())
137- .tlsCertificateFilePath (config .getMqttTlsCertificateFilePath ())
138- .tlsKeyFilePath (config .getMqttTlsKeyFilePath ())
139- .allowInsecureConnection (config .isMqttTlsAllowInsecureConnection ())
140- .requireTrustedClientCertOnConnect (config .isMqttTlsRequireTrustedClientCertOnConnect ())
141- .tlsEnabledWithKeystore (config .isMqttTlsEnabledWithKeyStore ())
142- .tlsCustomParams (config .getSslFactoryPluginParams ())
143- .authData (null )
144- .serverMode (true )
145- .build ();
146- }
147-
148- protected void refreshSslContext () {
149- try {
150- this .sslFactory .update ();
151- } catch (Exception e ) {
152- log .error ("Failed to refresh SSL context for mqtt channel." , e );
153- }
154- }
155-
156144}
0 commit comments