Switched from Moquette's MQTT codec to Netty's MQTT codec ones

This commit is contained in:
andsel
2017-01-28 15:59:44 +01:00
parent 07093ab0cb
commit 1c64186a00
53 changed files with 1571 additions and 1048 deletions
@@ -1,23 +1,23 @@
package io.moquette.server;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.moquette.connections.IConnectionsManager;
import io.moquette.connections.MqttConnectionMetrics;
import io.moquette.connections.MqttSession;
import io.moquette.connections.MqttSubscription;
import io.moquette.parser.proto.messages.AbstractMessage;
import io.moquette.server.netty.metrics.BytesMetrics;
import io.moquette.server.netty.metrics.MessageMetrics;
import io.moquette.spi.ClientSession;
import io.moquette.spi.ISessionsStore;
import io.moquette.spi.impl.subscriptions.Subscription;
import io.netty.handler.codec.mqtt.MqttMessage;
import io.netty.handler.codec.mqtt.MqttMessageType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class ConnectionDescriptorStore implements IConnectionsManager {
@@ -27,38 +27,29 @@ public class ConnectionDescriptorStore implements IConnectionsManager {
private final ISessionsStore sessionsStore;
public ConnectionDescriptorStore(ISessionsStore sessionsStore) {
this.connectionDescriptors = new ConcurrentHashMap<String, ConnectionDescriptor>();
this.connectionDescriptors = new ConcurrentHashMap<>();
this.sessionsStore = sessionsStore;
}
public boolean sendMessage(AbstractMessage message, String clientId) {
return sendMessage(message, null, clientId);
}
public boolean sendMessage(AbstractMessage message, Integer messageID, String clientID) {
public boolean sendMessage(MqttMessage message, Integer messageID, String clientID) {
final MqttMessageType messageType = message.fixedHeader().messageType();
try {
// The connection descriptors map will never be null: it's a final
// attribute.
if (messageID != null) {
LOG.info("Sending {} message. MqttClientId = {}, messageId = {}.", message.getMessageType(), clientID,
messageID);
LOG.info("Sending {} message CId=<{}>, messageId={}", messageType, clientID, messageID);
} else {
LOG.debug("Sending {} message. MqttClientId = {}.", message.getMessageType(), clientID);
LOG.debug("Sending {} message CId=<{}>", messageType, clientID);
}
ConnectionDescriptor descriptor = connectionDescriptors.get(clientID);
if (descriptor == null) {
if (messageID != null) {
LOG.error(
"The client has just disconnected. The {} message could not be sent. MqttClientId = {}, messageId = {}.",
message.getMessageType(), clientID, messageID);
LOG.error("Client has just disconnected. The {} message could not be sent. CId=<{}>, messageId={}",
messageType, clientID, messageID);
} else {
LOG.error("The client has just disconnected. The {} could not be sent. MqttClientId = {}.",
message.getMessageType(), clientID);
LOG.error("Client has just disconnected. The {} could not be sent. CId=<{}>", messageType, clientID);
}
/*
* If the client hast just disconnected, its connection
* If the client has just disconnected, its connection
* descriptor will be null. We don't have to make the broker
* crash: we'll just discard the PUBACK message.
*/
@@ -67,14 +58,11 @@ public class ConnectionDescriptorStore implements IConnectionsManager {
descriptor.writeAndFlush(message);
return true;
} catch (Throwable e) {
String errorMsg = "Unable to send " + messageType + " message. CId=<" + clientID + ">";
if (messageID != null) {
LOG.error(
"Unable to send {} message. MqttClientId = {}, messageId = {}, cause = {}, errorMessage = {}.",
message.getMessageType(), clientID, messageID, e.getCause(), e.getMessage());
} else {
LOG.error("Unable to send {} message. MqttClientId = {}, cause = {}, errorMessage = {}.",
message.getMessageType(), clientID, e.getCause(), e.getMessage());
errorMsg += ", messageId=" + messageID;
}
LOG.error(errorMsg, e);
return false;
}
}
@@ -111,7 +99,7 @@ public class ConnectionDescriptorStore implements IConnectionsManager {
ConnectionDescriptor descriptor = connectionDescriptors.get(clientID);
if (descriptor == null) {
LOG.error(
"The connection descriptor doesn't exist. The MQTT connection cannot be closed. MqttClientId = {}, closeImmediately = {}.",
"The connection descriptor doesn't exist. The MQTT connection cannot be closed. CId=<{}>, closeImmediately = {}.",
clientID, closeImmediately);
return false;
}
@@ -125,10 +113,10 @@ public class ConnectionDescriptorStore implements IConnectionsManager {
@Override
public MqttSession getSessionStatus(String clientID) {
LOG.info("Retrieving status of session. MqttClientId = {}.", clientID);
LOG.info("Retrieving status of session. CId=<{}>", clientID);
ClientSession session = sessionsStore.sessionForClient(clientID);
if (session == null) {
LOG.error("The given MQTT client ID doesn't have an associated session. MqttClientId = {}.", clientID);
LOG.error("The given MQTT client ID doesn't have an associated session. CId=<{}>", clientID);
return null;
}
return buildMqttSession(session);
@@ -166,7 +154,7 @@ public class ConnectionDescriptorStore implements IConnectionsManager {
result.setPendingPublishMessagesNo(session.getPendingPublishMessagesNo());
result.setSecondPhaseAckPendingMessages(session.getSecondPhaseAckPendingMessages());
result.setInflightMessages(session.getInflightMessagesNo());
LOG.info("The status of the session has been retrieved successfully. MqttClientId = {}.", session.clientID);
LOG.info("The status of the session has been retrieved successfully. CId=<{}>", session.clientID);
return result;
}
@@ -3,13 +3,12 @@ package io.moquette.server;
import com.hazelcast.core.Message;
import com.hazelcast.core.MessageListener;
import io.moquette.interception.HazelcastMsg;
import io.moquette.parser.proto.messages.AbstractMessage;
import io.moquette.parser.proto.messages.PublishMessage;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.mqtt.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.ByteBuffer;
/**
* Created by mackristof on 28/05/2016.
*/
@@ -29,13 +28,14 @@ public class HazelcastListener implements MessageListener<HazelcastMsg> {
HazelcastMsg hzMsg = msg.getMessageObject();
LOG.info("{} received from hazelcast for topic {} message: {}", hzMsg.getClientId(),
hzMsg.getTopic(), hzMsg.getPayload());
PublishMessage publishMessage = new PublishMessage();
publishMessage.setTopicName(hzMsg.getTopic());
publishMessage.setQos(AbstractMessage.QOSType.valueOf(hzMsg.getQos()));
publishMessage.setPayload(ByteBuffer.wrap(hzMsg.getPayload()));
publishMessage.setLocal(false);
publishMessage.setClientId(hzMsg.getClientId());
server.internalPublish(publishMessage);
//TODO pass forward this information in somehow publishMessage.setLocal(false);
MqttQoS qos = MqttQoS.valueOf(hzMsg.getQos());
MqttFixedHeader fixedHeader = new MqttFixedHeader(MqttMessageType.PUBLISH, false, qos, false, 0);
MqttPublishVariableHeader varHeader = new MqttPublishVariableHeader(hzMsg.getTopic(), 0);
ByteBuf payload = Unpooled.wrappedBuffer(hzMsg.getPayload());
MqttPublishMessage publishMessage = new MqttPublishMessage(fixedHeader, varHeader, payload);
server.internalPublish(publishMessage, hzMsg.getClientId());
}
} catch (Exception ex) {
LOG.error("error polling hazelcast msg queue", ex);
@@ -27,15 +27,15 @@ import io.moquette.connections.IConnectionsManager;
import io.moquette.interception.HazelcastInterceptHandler;
import io.moquette.interception.HazelcastMsg;
import io.moquette.interception.InterceptHandler;
import io.moquette.parser.proto.messages.PublishMessage;
import io.moquette.server.config.*;
import io.moquette.spi.impl.ProtocolProcessorBootstrapper;
import io.moquette.server.netty.NettyAcceptor;
import io.moquette.spi.impl.ProtocolProcessor;
import io.moquette.spi.impl.ProtocolProcessorBootstrapper;
import io.moquette.spi.impl.subscriptions.Subscription;
import io.moquette.spi.security.IAuthenticator;
import io.moquette.spi.security.IAuthorizator;
import io.moquette.spi.security.ISslContextCreator;
import io.netty.handler.codec.mqtt.MqttPublishMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -221,16 +221,18 @@ public class Server {
* It can be used only after the server is correctly started with startServer.
*
* @param msg the message to forward.
* @param clientId the id of the sending server.
* @throws IllegalStateException if the server is not yet started
* */
public void internalPublish(PublishMessage msg) {
public void internalPublish(MqttPublishMessage msg, final String clientId) {
final int messageID = msg.variableHeader().messageId();
if (!m_initialized) {
LOG.error("The server is not started. The message cannot be published. MqttClientId = {}, messageId = {}.",
msg.getClientId(), msg.getMessageID());
LOG.error("The server is not started. The message cannot be published. MqttClientId = {}, messageId = {}",
clientId, messageID);
throw new IllegalStateException("Can't publish on a server is not yet started");
}
LOG.debug("Publishing message. MqttClientId = {}, messageId = {}.", msg.getClientId(), msg.getMessageID());
m_processor.internalPublish(msg);
LOG.debug("Publishing message. MqttClientId = {}, messageId = {}", clientId, messageID);
m_processor.internalPublish(msg, clientId);
}
public void stopServer() {
@@ -266,7 +268,6 @@ public class Server {
/**
* SPI method used by Broker embedded applications to add intercept handlers.
* @param interceptHandler the handler to add.
* @return true id operation was successful.
* */
public void addInterceptHandler(InterceptHandler interceptHandler) {
if (!m_initialized) {
@@ -282,7 +283,6 @@ public class Server {
/**
* SPI method used by Broker embedded applications to remove intercept handlers.
* @param interceptHandler the handler to remove.
* @return true id operation was successful.
* */
public void removeInterceptHandler(InterceptHandler interceptHandler) {
if (!m_initialized) {
@@ -297,7 +297,7 @@ public class Server {
/**
* Returns the connections manager of this broker.
*
* @return
* @return IConnectionsManager the instance used bt the broker.
*/
public IConnectionsManager getConnectionsManager() {
return m_processorBootstrapper.getConnectionDescriptors();
@@ -0,0 +1,220 @@
/*
* Copyright (c) 2012-2017 The original author or authorsgetRockQuestions()
* ------------------------------------------------------
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* The Apache License v2.0 is available at
* http://www.opensource.org/licenses/apache2.0.php
*
* You may elect to redistribute this code under either of these licenses.
*/
package io.moquette.server.netty;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.mqtt.*;
import java.util.ArrayList;
import java.util.List;
public class MessageBuilder {
public static class PublishBuilder {
private String topic = null;
private boolean retained = false;
private MqttQoS qos;
private byte[] payload;
private int messageId = 0;
public PublishBuilder topicName(String topic) {
this.topic = topic;
return PublishBuilder.this;
}
public PublishBuilder retained(boolean retained) {
this.retained = retained;
return this;
}
public PublishBuilder qos(MqttQoS qos) {
this.qos = qos;
return this;
}
public PublishBuilder payload(byte[] payload) {
this.payload = payload;
return this;
}
public PublishBuilder messageId(int messageId) {
this.messageId = messageId;
return this;
}
public MqttPublishMessage build() {
MqttFixedHeader mqttFixedHeader = new MqttFixedHeader(MqttMessageType.PUBLISH, false, qos, retained, 0);
MqttPublishVariableHeader mqttVariableHeader = new MqttPublishVariableHeader(topic, messageId);
return new MqttPublishMessage(mqttFixedHeader, mqttVariableHeader, Unpooled.buffer().writeBytes(payload));
}
}
public static class ConnectBuilder {
private MqttVersion version = MqttVersion.MQTT_3_1_1;
private String clientId;
private boolean cleanSession = false;
private boolean hasUser = false;
private boolean hasPassword = false;
private int keepAliveSecs;
private boolean willFlag = false;
private MqttQoS willQos = MqttQoS.AT_MOST_ONCE;
private String willTopic = null;
private String willMessage = null;
private String username = null;
private String password = null;
public ConnectBuilder protocolVersion(MqttVersion version) {
this.version = version;
return this;
}
public ConnectBuilder clientId(String clientId) {
this.clientId = clientId;
return this;
}
public ConnectBuilder cleanSession(boolean cleanSession) {
this.cleanSession = cleanSession;
return this;
}
public ConnectBuilder keepAlive(int keepAliveSecs) {
this.keepAliveSecs = keepAliveSecs;
return this;
}
public ConnectBuilder willFlag(boolean willFlag) {
this.willFlag = willFlag;
return this;
}
public ConnectBuilder willQoS(MqttQoS willQos) {
this.willQos = willQos;
return this;
}
public ConnectBuilder willTopic(String willTopic) {
this.willTopic = willTopic;
return this;
}
public ConnectBuilder willMessage(String willMessage) {
this.willMessage = willMessage;
return this;
}
public ConnectBuilder hasUser() {
this.hasUser = true;
return this;
}
public ConnectBuilder hasPassword() {
this.hasPassword = true;
return this;
}
public ConnectBuilder username(String username) {
this.username = username;
return this;
}
public ConnectBuilder password(String password) {
this.password = password;
return this;
}
public MqttConnectMessage build() {
MqttFixedHeader mqttFixedHeader = new MqttFixedHeader(MqttMessageType.CONNECT, false, MqttQoS.AT_MOST_ONCE, false, 0);
MqttConnectVariableHeader mqttConnectVariableHeader =
new MqttConnectVariableHeader(
version.protocolName(),
version.protocolLevel(),
hasUser,
hasPassword,
false,
willQos.value(),
willFlag,
cleanSession,
keepAliveSecs);
MqttConnectPayload mqttConnectPayload = new MqttConnectPayload(clientId, willTopic, willMessage, username, password);
return new MqttConnectMessage(mqttFixedHeader, mqttConnectVariableHeader, mqttConnectPayload);
}
}
public static class SubscribeBuilder {
private List<MqttTopicSubscription> subscriptions = new ArrayList<>();
private int messageId;
public SubscribeBuilder addSubscription(MqttQoS qos, String topic) {
subscriptions.add(new MqttTopicSubscription(topic, qos));
return this;
}
public SubscribeBuilder messageId(int messageId) {
this.messageId = messageId;
return this;
}
public MqttSubscribeMessage build() {
MqttFixedHeader mqttFixedHeader = new MqttFixedHeader(MqttMessageType.SUBSCRIBE, false, MqttQoS.AT_LEAST_ONCE, false, 0);
MqttMessageIdVariableHeader mqttVariableHeader = MqttMessageIdVariableHeader.from(messageId);
MqttSubscribePayload mqttSubscribePayload = new MqttSubscribePayload(subscriptions);
return new MqttSubscribeMessage(mqttFixedHeader, mqttVariableHeader, mqttSubscribePayload);
}
}
public static class UnsubscribeBuilder {
private List<String> topicFilters = new ArrayList<>();
private int messageId = 0;
public UnsubscribeBuilder addTopicFilter(String topic) {
topicFilters.add(topic);
return this;
}
public UnsubscribeBuilder messageId(int messageId) {
this.messageId = messageId;
return this;
}
public MqttUnsubscribeMessage build() {
MqttFixedHeader mqttFixedHeader = new MqttFixedHeader(MqttMessageType.UNSUBSCRIBE, false,
MqttQoS.AT_LEAST_ONCE, false, 0);
MqttMessageIdVariableHeader mqttVariableHeader = MqttMessageIdVariableHeader.from(messageId);
MqttUnsubscribePayload mqttSubscribePayload = new MqttUnsubscribePayload(topicFilters);
return new MqttUnsubscribeMessage(mqttFixedHeader, mqttVariableHeader, mqttSubscribePayload);
}
}
public static ConnectBuilder connect() {
return new ConnectBuilder();
}
public static PublishBuilder publish() {
return new PublishBuilder();
}
public static SubscribeBuilder subscribe() {
return new SubscribeBuilder();
}
public static UnsubscribeBuilder unsubscribe() {
return new UnsubscribeBuilder();
}
}
@@ -16,14 +16,11 @@
package io.moquette.server.netty;
import io.moquette.BrokerConstants;
import static io.moquette.BrokerConstants.*;
import io.moquette.parser.netty.MQTTDecoder;
import io.moquette.parser.netty.MQTTEncoder;
import io.moquette.spi.security.ISslContextCreator;
import io.moquette.server.ServerAcceptor;
import io.moquette.server.config.IConfig;
import io.moquette.server.netty.metrics.*;
import io.moquette.spi.impl.ProtocolProcessor;
import io.moquette.spi.security.ISslContextCreator;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
@@ -38,6 +35,8 @@ import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.codec.mqtt.MqttDecoder;
import io.netty.handler.codec.mqtt.MqttEncoder;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.concurrent.Future;
@@ -50,6 +49,8 @@ import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;
import static io.moquette.BrokerConstants.*;
/**
*
* @author andrea
@@ -179,8 +180,8 @@ public class NettyAcceptor implements ServerAcceptor {
pipeline.addAfter("idleStateHandler", "idleEventHandler", timeoutHandler);
// pipeline.addLast("logger", new LoggingHandler("Netty", LogLevel.ERROR));
pipeline.addFirst("bytemetrics", new BytesMetricsHandler(m_bytesMetricsCollector));
pipeline.addLast("decoder", new MQTTDecoder());
pipeline.addLast("encoder", new MQTTEncoder());
pipeline.addLast("decoder", new MqttDecoder());
pipeline.addLast("encoder", MqttEncoder.INSTANCE);
pipeline.addLast("metrics", new MessageMetricsHandler(m_metricsCollector));
pipeline.addLast("messageLogger", new MQTTMessageLogger());
pipeline.addLast("handler", handler);
@@ -213,8 +214,8 @@ public class NettyAcceptor implements ServerAcceptor {
pipeline.addFirst("idleStateHandler", new IdleStateHandler(0, 0, nettyChannelTimeoutSeconds));
pipeline.addAfter("idleStateHandler", "idleEventHandler", timeoutHandler);
pipeline.addFirst("bytemetrics", new BytesMetricsHandler(m_bytesMetricsCollector));
pipeline.addLast("decoder", new MQTTDecoder());
pipeline.addLast("encoder", new MQTTEncoder());
pipeline.addLast("decoder", new MqttDecoder());
pipeline.addLast("encoder", MqttEncoder.INSTANCE);
pipeline.addLast("metrics", new MessageMetricsHandler(m_metricsCollector));
pipeline.addLast("messageLogger", new MQTTMessageLogger());
pipeline.addLast("handler", handler);
@@ -247,8 +248,8 @@ public class NettyAcceptor implements ServerAcceptor {
pipeline.addAfter("idleStateHandler", "idleEventHandler", timeoutHandler);
//pipeline.addLast("logger", new LoggingHandler("Netty", LogLevel.ERROR));
pipeline.addFirst("bytemetrics", new BytesMetricsHandler(m_bytesMetricsCollector));
pipeline.addLast("decoder", new MQTTDecoder());
pipeline.addLast("encoder", new MQTTEncoder());
pipeline.addLast("decoder", new MqttDecoder());
pipeline.addLast("encoder", MqttEncoder.INSTANCE);
pipeline.addLast("metrics", new MessageMetricsHandler(m_metricsCollector));
pipeline.addLast("messageLogger", new MQTTMessageLogger());
pipeline.addLast("handler", handler);
@@ -283,8 +284,8 @@ public class NettyAcceptor implements ServerAcceptor {
pipeline.addFirst("idleStateHandler", new IdleStateHandler(0, 0, nettyChannelTimeoutSeconds));
pipeline.addAfter("idleStateHandler", "idleEventHandler", timeoutHandler);
pipeline.addFirst("bytemetrics", new BytesMetricsHandler(m_bytesMetricsCollector));
pipeline.addLast("decoder", new MQTTDecoder());
pipeline.addLast("encoder", new MQTTEncoder());
pipeline.addLast("decoder", new MqttDecoder());
pipeline.addLast("encoder", MqttEncoder.INSTANCE);
pipeline.addLast("metrics", new MessageMetricsHandler(m_metricsCollector));
pipeline.addLast("messageLogger", new MQTTMessageLogger());
pipeline.addLast("handler", handler);
@@ -15,18 +15,16 @@
*/
package io.moquette.server.netty;
import io.moquette.parser.proto.Utils;
import io.moquette.parser.proto.messages.*;
import io.moquette.spi.impl.ProtocolProcessor;
import static io.moquette.parser.proto.messages.AbstractMessage.*;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.mqtt.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static io.netty.handler.codec.mqtt.MqttQoS.AT_MOST_ONCE;
/**
*
@@ -44,47 +42,46 @@ public class NettyMQTTHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object message) {
AbstractMessage msg = (AbstractMessage) message;
String messageType = Utils.msgType2String(msg.getMessageType());
LOG.debug("Processing MQTT message. MessageType = {}.", messageType);
MqttMessage msg = (MqttMessage) message;
MqttMessageType messageType = msg.fixedHeader().messageType();
LOG.debug("Processing MQTT message, type={}", messageType);
try {
switch (msg.getMessageType()) {
switch (messageType) {
case CONNECT:
m_processor.processConnect(ctx.channel(), (ConnectMessage) msg);
m_processor.processConnect(ctx.channel(), (MqttConnectMessage) msg);
break;
case SUBSCRIBE:
m_processor.processSubscribe(ctx.channel(), (SubscribeMessage) msg);
m_processor.processSubscribe(ctx.channel(), (MqttSubscribeMessage) msg);
break;
case UNSUBSCRIBE:
m_processor.processUnsubscribe(ctx.channel(), (UnsubscribeMessage) msg);
m_processor.processUnsubscribe(ctx.channel(), (MqttUnsubscribeMessage) msg);
break;
case PUBLISH:
m_processor.processPublish(ctx.channel(), (PublishMessage) msg);
m_processor.processPublish(ctx.channel(), (MqttPublishMessage) msg);
break;
case PUBREC:
m_processor.processPubRec(ctx.channel(), (PubRecMessage) msg);
m_processor.processPubRec(ctx.channel(), msg);
break;
case PUBCOMP:
m_processor.processPubComp(ctx.channel(), (PubCompMessage) msg);
m_processor.processPubComp(ctx.channel(), msg);
break;
case PUBREL:
m_processor.processPubRel(ctx.channel(), (PubRelMessage) msg);
m_processor.processPubRel(ctx.channel(), msg);
break;
case DISCONNECT:
m_processor.processDisconnect(ctx.channel());
break;
case PUBACK:
m_processor.processPubAck(ctx.channel(), (PubAckMessage) msg);
m_processor.processPubAck(ctx.channel(), (MqttPubAckMessage) msg);
break;
case PINGREQ:
PingRespMessage pingResp = new PingRespMessage();
MqttFixedHeader pingHeader = new MqttFixedHeader(MqttMessageType.PINGRESP, false, AT_MOST_ONCE, false, 0);
MqttMessage pingResp = new MqttMessage(pingHeader);
ctx.writeAndFlush(pingResp);
break;
}
} catch (Throwable ex) {
LOG.error(
"An unexpected exception was caught while processing MQTT message. MessageType = {}, cause = {}, errorMessage = {}.",
messageType, ex.getCause(), ex.getMessage());
LOG.error("Exception was caught while processing MQTT message, " + ex.getCause(), ex);
ctx.fireExceptionCaught(ex);
}
}
@@ -15,16 +15,16 @@
*/
package io.moquette.server.netty.metrics;
import io.moquette.parser.proto.messages.*;
import io.moquette.server.netty.NettyUtils;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import io.netty.handler.codec.mqtt.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static io.moquette.parser.proto.messages.AbstractMessage.*;
import static io.moquette.spi.impl.Utils.messageId;
/**
*
@@ -42,46 +42,42 @@ public class MQTTMessageLogger extends ChannelDuplexHandler {
}
private void logMQTTMessage(ChannelHandlerContext ctx, Object message, String direction) {
if (!(message instanceof AbstractMessage)) {
if (!(message instanceof MqttMessage)) {
return;
}
AbstractMessage msg = (AbstractMessage) message;
MqttMessage msg = (MqttMessage) message;
String clientID = NettyUtils.clientID(ctx.channel());
switch (msg.getMessageType()) {
MqttMessageType messageType = msg.fixedHeader().messageType();
switch (messageType) {
case CONNECT:
ConnectMessage connect = (ConnectMessage) msg;
LOG.info("{} CONNECT client <{}>", direction, connect.getClientID());
LOG.info("{} CONNECT client <{}>", direction, clientID);
break;
case SUBSCRIBE:
SubscribeMessage subscribe = (SubscribeMessage) msg;
LOG.info("{} SUBSCRIBE <{}> to topics {}", direction, clientID, subscribe.subscriptions());
MqttSubscribeMessage subscribe = (MqttSubscribeMessage) msg;
LOG.info("{} SUBSCRIBE <{}> to topics {}", direction, clientID, subscribe.payload().topicSubscriptions());
break;
case UNSUBSCRIBE:
UnsubscribeMessage unsubscribe = (UnsubscribeMessage) msg;
LOG.info("{} UNSUBSCRIBE <{}> to topics <{}>", direction, clientID, unsubscribe.topicFilters());
MqttUnsubscribeMessage unsubscribe = (MqttUnsubscribeMessage) msg;
LOG.info("{} UNSUBSCRIBE <{}> to topics <{}>", direction, clientID, unsubscribe.payload().topics());
break;
case PUBLISH:
PublishMessage publish = (PublishMessage) msg;
LOG.info("{} PUBLISH <{}> to topics <{}>", direction, clientID, publish.getTopicName());
MqttPublishMessage publish = (MqttPublishMessage) msg;
LOG.info("{} PUBLISH <{}> to topics <{}>", direction, clientID, publish.variableHeader().topicName());
break;
case PUBREC:
PubRecMessage pubrec = (PubRecMessage) msg;
LOG.info("{} PUBREC <{}> packetID <{}>", direction, clientID, pubrec.getMessageID());
LOG.info("{} PUBREC <{}> packetID <{}>", direction, clientID, messageId(msg));
break;
case PUBCOMP:
PubCompMessage pubCompleted = (PubCompMessage) msg;
LOG.info("{} PUBCOMP <{}> packetID <{}>", direction, clientID, pubCompleted.getMessageID());
LOG.info("{} PUBCOMP <{}> packetID <{}>", direction, clientID, messageId(msg));
break;
case PUBREL:
PubRelMessage pubRelease = (PubRelMessage) msg;
LOG.info("{} PUBREL <{}> packetID <{}>", direction, clientID, pubRelease.getMessageID());
LOG.info("{} PUBREL <{}> packetID <{}>", direction, clientID, messageId(msg));
break;
case DISCONNECT:
LOG.info("{} DISCONNECT <{}>", direction, clientID);
break;
case PUBACK:
PubAckMessage pubAck = (PubAckMessage) msg;
LOG.info("{} PUBACK <{}> packetID <{}>", direction, clientID, pubAck.getMessageID());
LOG.info("{} PUBACK <{}> packetID <{}>", direction, clientID, messageId(msg));
break;
}
}
@@ -100,24 +96,4 @@ public class MQTTMessageLogger extends ChannelDuplexHandler {
logMQTTMessage(ctx, msg, "C<-B");
ctx.write(msg, promise);
}
//
// @Override
// public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
// if (cause instanceof CorruptedFrameException) {
// //something goes bad with decoding
// LOG.warn("Error decoding a packet, probably a bad formatted packet, message: " + cause.getMessage());
// } else {
// LOG.error("Ugly error on networking", cause);
// }
// ctx.close();
// }
//
// @Override
// public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
// if (ctx.channel().isWritable()) {
// m_processor.notifyChannelWritable(ctx.channel());
// }
// ctx.fireChannelWritabilityChanged();
// }
}