Skip to content

Commit 4cc93c3

Browse files
committed
fix branch-3.3
1 parent 7d76b42 commit 4cc93c3

File tree

15 files changed

+120
-496
lines changed

15 files changed

+120
-496
lines changed

mqtt-broker/src/main/java/io/streamnative/pulsar/handlers/mqtt/broker/MQTTProtocolHandler.java

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,19 @@
2525
import com.google.common.collect.ImmutableMap;
2626
import io.netty.channel.ChannelInitializer;
2727
import io.netty.channel.socket.SocketChannel;
28-
import io.netty.util.concurrent.DefaultThreadFactory;
2928
import io.streamnative.pulsar.handlers.mqtt.MopVersion;
3029
import io.streamnative.pulsar.handlers.mqtt.broker.channel.MQTTChannelInitializer;
3130
import io.streamnative.pulsar.handlers.mqtt.common.utils.ConfigurationUtils;
3231
import io.streamnative.pulsar.handlers.mqtt.proxy.MQTTProxyConfiguration;
3332
import io.streamnative.pulsar.handlers.mqtt.proxy.MQTTProxyService;
3433
import java.net.InetSocketAddress;
3534
import java.util.Map;
36-
import java.util.concurrent.Executors;
37-
import java.util.concurrent.ScheduledExecutorService;
3835
import lombok.Getter;
3936
import lombok.extern.slf4j.Slf4j;
4037
import org.apache.pulsar.broker.ServiceConfiguration;
4138
import org.apache.pulsar.broker.ServiceConfigurationUtils;
4239
import org.apache.pulsar.broker.protocol.ProtocolHandler;
4340
import org.apache.pulsar.broker.service.BrokerService;
44-
4541
/**
4642
* MQTT Protocol Handler load and run by Pulsar Service.
4743
*/
@@ -62,8 +58,6 @@ public class MQTTProtocolHandler implements ProtocolHandler {
6258
@Getter
6359
private MQTTService mqttService;
6460

65-
private ScheduledExecutorService sslContextRefresher;
66-
6761
@Override
6862
public String protocolName() {
6963
return PROTOCOL_NAME;
@@ -120,9 +114,6 @@ public Map<InetSocketAddress, ChannelInitializer<SocketChannel>> newChannelIniti
120114
checkArgument(mqttConfig.getMqttListeners() != null);
121115
checkArgument(brokerService != null);
122116

123-
this.sslContextRefresher = Executors.newSingleThreadScheduledExecutor(
124-
new DefaultThreadFactory("mop-ssl-context-refresher"));
125-
126117
String listeners = mqttConfig.getMqttListeners();
127118
String[] parts = listeners.split(LISTENER_DEL);
128119
try {
@@ -133,28 +124,27 @@ public Map<InetSocketAddress, ChannelInitializer<SocketChannel>> newChannelIniti
133124
if (listener.startsWith(PLAINTEXT_PREFIX)) {
134125
builder.put(
135126
new InetSocketAddress(brokerService.pulsar().getBindAddress(), getListenerPort(listener)),
136-
new MQTTChannelInitializer(mqttService, false, false, sslContextRefresher));
127+
new MQTTChannelInitializer(mqttService, false, false));
137128

138129
} else if (listener.startsWith(SSL_PREFIX)) {
139130
builder.put(
140131
new InetSocketAddress(brokerService.pulsar().getBindAddress(), getListenerPort(listener)),
141-
new MQTTChannelInitializer(mqttService, true, false, sslContextRefresher));
132+
new MQTTChannelInitializer(mqttService, true, false));
142133

143134
} else if (listener.startsWith(SSL_PSK_PREFIX) && mqttConfig.isMqttTlsPskEnabled()) {
144135
builder.put(
145136
new InetSocketAddress(brokerService.pulsar().getBindAddress(), getListenerPort(listener)),
146-
new MQTTChannelInitializer(
147-
mqttService, false, true, false, sslContextRefresher));
137+
new MQTTChannelInitializer(mqttService, false, true, false));
148138

149139
} else if (listener.startsWith(WS_PLAINTEXT_PREFIX)) {
150140
builder.put(
151141
new InetSocketAddress(brokerService.pulsar().getBindAddress(), getListenerPort(listener)),
152-
new MQTTChannelInitializer(mqttService, false, true, sslContextRefresher));
142+
new MQTTChannelInitializer(mqttService, false, true));
153143

154144
} else if (listener.startsWith(WS_SSL_PREFIX)) {
155145
builder.put(
156146
new InetSocketAddress(brokerService.pulsar().getBindAddress(), getListenerPort(listener)),
157-
new MQTTChannelInitializer(mqttService, true, true, sslContextRefresher));
147+
new MQTTChannelInitializer(mqttService, true, true));
158148

159149
} else {
160150
log.error("MQTT listener {} not supported. supports {}, {} or {}",
@@ -171,9 +161,6 @@ public Map<InetSocketAddress, ChannelInitializer<SocketChannel>> newChannelIniti
171161

172162
@Override
173163
public void close() {
174-
if (sslContextRefresher != null) {
175-
sslContextRefresher.shutdownNow();
176-
}
177164
if (proxyService != null) {
178165
proxyService.close();
179166
}

mqtt-broker/src/main/java/io/streamnative/pulsar/handlers/mqtt/broker/channel/MQTTChannelInitializer.java

Lines changed: 43 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import io.netty.handler.codec.http.HttpServerCodec;
2323
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
2424
import io.netty.handler.codec.mqtt.MqttDecoder;
25+
import io.netty.handler.ssl.SslContext;
2526
import io.netty.handler.ssl.SslHandler;
2627
import io.netty.handler.timeout.IdleStateHandler;
2728
import io.streamnative.pulsar.handlers.mqtt.broker.MQTTServerConfiguration;
@@ -32,49 +33,63 @@
3233
import io.streamnative.pulsar.handlers.mqtt.common.adapter.MqttAdapterDecoder;
3334
import io.streamnative.pulsar.handlers.mqtt.common.adapter.MqttAdapterEncoder;
3435
import 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
4543
public 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
}

mqtt-broker/src/main/java/io/streamnative/pulsar/handlers/mqtt/broker/impl/consumer/MessagePublishContext.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import java.util.concurrent.TimeUnit;
2222
import lombok.extern.slf4j.Slf4j;
2323
import org.apache.bookkeeper.mledger.Position;
24-
import org.apache.bookkeeper.mledger.PositionFactory;
24+
import org.apache.bookkeeper.mledger.impl.PositionImpl;
2525
import org.apache.pulsar.broker.service.Topic;
2626
import org.apache.pulsar.broker.service.Topic.PublishContext;
2727
import org.apache.pulsar.client.api.Message;
@@ -52,7 +52,7 @@ public void completed(Exception exception, long ledgerId, long entryId) {
5252
topic.getName(), ledgerId, entryId);
5353
}
5454
topic.recordAddLatency(System.nanoTime() - startTimeNs, TimeUnit.NANOSECONDS);
55-
positionFuture.complete(PositionFactory.create(ledgerId, entryId));
55+
positionFuture.complete(PositionImpl.get(ledgerId, entryId));
5656
}
5757
recycle();
5858
}

mqtt-broker/src/main/java/io/streamnative/pulsar/handlers/mqtt/broker/processor/MQTTBrokerProtocolMethodProcessor.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,7 @@
8181
import lombok.Getter;
8282
import lombok.extern.slf4j.Slf4j;
8383
import org.apache.bookkeeper.mledger.Position;
84-
import org.apache.bookkeeper.mledger.PositionFactory;
85-
import org.apache.bookkeeper.mledger.impl.AckSetStateUtil;
84+
import org.apache.bookkeeper.mledger.impl.PositionImpl;
8685
import org.apache.pulsar.broker.PulsarService;
8786
import org.apache.pulsar.broker.authentication.AuthenticationDataSource;
8887
import org.apache.pulsar.broker.authorization.AuthorizationService;
@@ -177,9 +176,9 @@ public void processPubAck(MqttAdapterMessage adapter) {
177176
for (int i = 0; i < packet.getBatchSize(); i++) {
178177
ackSets[i] = packet.getBatchIndex() == i ? 0 : 1;
179178
}
180-
position = AckSetStateUtil.createPositionWithAckSet(packet.getLedgerId(), packet.getEntryId(), ackSets);
179+
position = PositionImpl.get(packet.getLedgerId(), packet.getEntryId(), ackSets);
181180
} else {
182-
position = PositionFactory.create(packet.getLedgerId(), packet.getEntryId());
181+
position = PositionImpl.get(packet.getLedgerId(), packet.getEntryId());
183182
}
184183
packet.getConsumer().getSubscription().acknowledgeMessage(Collections.singletonList(position),
185184
CommandAck.AckType.Individual, Collections.emptyMap());

mqtt-proxy/src/main/java/io/streamnative/pulsar/handlers/mqtt/proxy/MQTTProxyProtocolHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ public Map<InetSocketAddress, ChannelInitializer<SocketChannel>> newChannelIniti
114114
new InetSocketAddress(brokerService.pulsar().getBindAddress(),
115115
getProxyListenerPort(listener)),
116116
new MQTTProxyChannelInitializer(
117-
proxyService, proxyConfig, false, false, sslContextRefresher));
117+
proxyService, proxyConfig, false, false));
118118
}
119119
}
120120
return builder.build();

mqtt-proxy/src/main/java/io/streamnative/pulsar/handlers/mqtt/proxy/MQTTProxyService.java

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@
3636
import io.streamnative.pulsar.handlers.mqtt.proxy.handler.PulsarServiceLookupHandler;
3737
import io.streamnative.pulsar.handlers.mqtt.proxy.impl.MQTTProxyException;
3838
import java.io.Closeable;
39-
import java.util.concurrent.Executors;
40-
import java.util.concurrent.ScheduledExecutorService;
4139
import lombok.Getter;
4240
import lombok.extern.slf4j.Slf4j;
4341
import org.apache.pulsar.broker.PulsarService;
@@ -77,7 +75,6 @@ public class MQTTProxyService implements Closeable {
7775

7876
private DefaultThreadFactory acceptorThreadFactory = new DefaultThreadFactory("mqtt-redirect-acceptor");
7977
private DefaultThreadFactory workerThreadFactory = new DefaultThreadFactory("mqtt-redirect-io");
80-
private ScheduledExecutorService sslContextRefresher;
8178

8279
public MQTTProxyService(BrokerService brokerService, MQTTProxyConfiguration proxyConfig) {
8380
configValid(proxyConfig);
@@ -110,8 +107,6 @@ public MQTTProxyService(BrokerService brokerService, MQTTProxyConfiguration prox
110107
this.eventCenter = new PulsarEventCenterImpl(brokerService,
111108
proxyConfig.getEventCenterCallbackPoolThreadNum());
112109
this.proxyAdapter = new MQTTProxyAdapter(this);
113-
this.sslContextRefresher = Executors.newSingleThreadScheduledExecutor(
114-
new DefaultThreadFactory("mop-proxy-ssl-context-refresher"));
115110
}
116111

117112
private void configValid(MQTTProxyConfiguration proxyConfig) {
@@ -125,8 +120,7 @@ public void start() throws MQTTProxyException {
125120
serverBootstrap.group(acceptorGroup, workerGroup);
126121
serverBootstrap.channel(EventLoopUtil.getServerSocketChannelClass(workerGroup));
127122
EventLoopUtil.enableTriggeredMode(serverBootstrap);
128-
serverBootstrap.childHandler(new MQTTProxyChannelInitializer(
129-
this, proxyConfig, false, sslContextRefresher));
123+
serverBootstrap.childHandler(new MQTTProxyChannelInitializer(this, proxyConfig, false));
130124

131125
try {
132126
listenChannel = serverBootstrap.bind(proxyConfig.getMqttProxyPort()).sync().channel();
@@ -137,8 +131,7 @@ public void start() throws MQTTProxyException {
137131

138132
if (proxyConfig.isMqttProxyTlsEnabled() || proxyConfig.isMqttProxyMTlsAuthenticationEnabled()) {
139133
ServerBootstrap tlsBootstrap = serverBootstrap.clone();
140-
tlsBootstrap.childHandler(new MQTTProxyChannelInitializer(
141-
this, proxyConfig, true, sslContextRefresher));
134+
tlsBootstrap.childHandler(new MQTTProxyChannelInitializer(this, proxyConfig, true));
142135
try {
143136
listenChannelTls = tlsBootstrap.bind(proxyConfig.getMqttProxyTlsPort()).sync().channel();
144137
log.info("Started MQTT Proxy with TLS on {}", listenChannelTls.localAddress());
@@ -157,8 +150,7 @@ public void start() throws MQTTProxyException {
157150
this.eventService.addListener(pskConfiguration.getEventListener());
158151
// Add channel initializer
159152
ServerBootstrap tlsPskBootstrap = serverBootstrap.clone();
160-
tlsPskBootstrap.childHandler(new MQTTProxyChannelInitializer(
161-
this, proxyConfig, false, true, sslContextRefresher));
153+
tlsPskBootstrap.childHandler(new MQTTProxyChannelInitializer(this, proxyConfig, false, true));
162154
try {
163155
listenChannelTlsPsk = tlsPskBootstrap.bind(proxyConfig.getMqttProxyTlsPskPort()).sync().channel();
164156
log.info("Started MQTT Proxy with TLS-PSK on {}", listenChannelTlsPsk.localAddress());
@@ -179,7 +171,7 @@ public void start0() throws MQTTProxyException {
179171
if (proxyConfig.isMqttProxyTlsEnabled() || proxyConfig.isMqttProxyMTlsAuthenticationEnabled()) {
180172
ServerBootstrap tlsBootstrap = serverBootstrap.clone();
181173
tlsBootstrap.childHandler(new MQTTProxyChannelInitializer(
182-
this, proxyConfig, true, sslContextRefresher));
174+
this, proxyConfig, true));
183175
try {
184176
listenChannelTls = tlsBootstrap.bind(proxyConfig.getMqttProxyTlsPort()).sync().channel();
185177
log.info("Started MQTT Proxy with TLS on {}", listenChannelTls.localAddress());
@@ -199,7 +191,7 @@ public void start0() throws MQTTProxyException {
199191
// Add channel initializer
200192
ServerBootstrap tlsPskBootstrap = serverBootstrap.clone();
201193
tlsPskBootstrap.childHandler(new MQTTProxyChannelInitializer(
202-
this, proxyConfig, false, true, sslContextRefresher));
194+
this, proxyConfig, false, true));
203195
try {
204196
listenChannelTlsPsk = tlsPskBootstrap.bind(proxyConfig.getMqttProxyTlsPskPort()).sync().channel();
205197
log.info("Started MQTT Proxy with TLS-PSK on {}", listenChannelTlsPsk.localAddress());
@@ -230,8 +222,5 @@ public void close() {
230222
}
231223
this.proxyAdapter.shutdown();
232224
this.connectionManager.close();
233-
if (sslContextRefresher != null) {
234-
sslContextRefresher.shutdownNow();
235-
}
236225
}
237226
}

0 commit comments

Comments
 (0)