Introduced the FlightZone concept (inbound and outbound) and separated logic of storage system.

This commit is contained in:
andsel
2017-04-09 19:22:50 +02:00
parent 5c6889fbd5
commit 6dc762f47f
21 changed files with 356 additions and 396 deletions
@@ -43,6 +43,39 @@ import java.util.concurrent.BlockingQueue;
*/
public class ClientSession {
class OutboundFlightZone {
/**
* Save the binding messageID, clientID - guid
* @param messageID the packet ID used in transmission
* @param guid the guid of the message being in flight.
*/
void waitingAck(int messageID, MessageGUID guid) {
if (LOG.isTraceEnabled()) {
LOG.trace("Adding to inflight {}, guid <{}>", messageID, guid);
}
m_sessionsStore.inFlight(ClientSession.this.clientID, messageID, guid);
}
void acknowledged(int messageID) {
if (LOG.isTraceEnabled())
LOG.trace("Acknowledging inflight, clientID <{}> messageID {}", ClientSession.this.clientID, messageID);
m_sessionsStore.inFlightAck(ClientSession.this.clientID, messageID);
}
}
class InboundFlightZone {
public IMessagesStore.StoredMessage lookup(int messageID) {
return m_sessionsStore.inboundInflight(clientID, messageID);
}
public void waitingRel(int messageID, MessageGUID guid) {
m_sessionsStore.markAsInboundInflight(clientID, messageID, guid);
}
}
private final static Logger LOG = LoggerFactory.getLogger(ClientSession.class);
public final String clientID;
@@ -57,6 +90,8 @@ public class ClientSession {
// private BlockingQueue<AbstractMessage> m_queueToPublish = new
// ArrayBlockingQueue<>(Constants.MAX_MESSAGE_QUEUE);
private final OutboundFlightZone outboundFlightZone;
private final InboundFlightZone inboundFlightZone;
public ClientSession(String clientID, IMessagesStore messagesStore, ISessionsStore sessionsStore,
boolean cleanSession) {
@@ -64,6 +99,8 @@ public class ClientSession {
this.messagesStore = messagesStore;
this.m_sessionsStore = sessionsStore;
this.cleanSession = cleanSession;
this.outboundFlightZone = new OutboundFlightZone();
this.inboundFlightZone = new InboundFlightZone();
}
/**
@@ -84,17 +121,12 @@ public class ClientSession {
}
public boolean subscribe(Subscription newSubscription) {
LOG.info(
"Adding new subscription. ClientId={}, topics={}, qos={}",
newSubscription.getClientId(),
newSubscription.getTopicFilter(),
newSubscription.getRequestedQos());
LOG.info("Adding new subscription. ClientId={}, topics={}, qos={}", newSubscription.getClientId(),
newSubscription.getTopicFilter(), newSubscription.getRequestedQos());
boolean validTopic = newSubscription.getTopicFilter().isValid();
if (!validTopic) {
LOG.warn(
"The topic filter is not valid. ClientId={}, topics={}",
newSubscription.getClientId(),
newSubscription.getTopicFilter());
LOG.warn("The topic filter is not valid. ClientId={}, topics={}", newSubscription.getClientId(),
newSubscription.getTopicFilter());
// send SUBACK with 0x80 for this topic filter
return false;
}
@@ -140,7 +172,10 @@ public class ClientSession {
// remove also the messages stored of type QoS1/2
LOG.info("Removing stored messages with QoS 1 and 2. ClientId={}", this.clientID);
messagesStore.dropMessagesInSession(this.clientID);
messagesStore.dropInFlightMessagesInSession(m_sessionsStore.pendingAck(this.clientID));
//remove also the enqueued messages
this.m_sessionsStore.dropQueue(this.clientID);
}
public boolean isCleanSession() {
@@ -157,15 +192,19 @@ public class ClientSession {
}
public void inFlightAcknowledged(int messageID) {
if (LOG.isTraceEnabled())
LOG.trace("Acknowledging inflight, clientID <{}> messageID {}", this.clientID, messageID);
m_sessionsStore.inFlightAck(this.clientID, messageID);
outboundFlightZone.acknowledged(messageID);
}
public void inFlightAckWaiting(MessageGUID guid, int messageID) {
if (LOG.isTraceEnabled())
LOG.trace("Adding to inflight {}, guid <{}>", messageID, guid);
m_sessionsStore.inFlight(this.clientID, messageID, guid);
/**
* Mark the message identified by guid as publish in flight.
*
* @return the packetID for the message in flight.
* */
public int inFlightAckWaiting(MessageGUID guid) {
LOG.debug("Adding message ot inflight zone. ClientId={}, guid={}", clientID, guid);
int messageId = ClientSession.this.nextPacketId();
outboundFlightZone.waitingAck(messageId, guid);
return messageId;
}
public IMessagesStore.StoredMessage secondPhaseAcknowledged(int messageID) {
@@ -183,9 +222,12 @@ public class ClientSession {
this.m_sessionsStore.queue(this.clientID).add(message);
}
public IMessagesStore.StoredMessage storedMessage(int messageID) {
final MessageGUID guid = messagesStore.mapToGuid(clientID, messageID);
return messagesStore.getMessageByGuid(guid);
public IMessagesStore.StoredMessage inboundInflight(int messageID) {
return inboundFlightZone.lookup(messageID);
}
public void markAsInboundInflight(int messageID, MessageGUID guid) {
inboundFlightZone.waitingRel(messageID, guid);
}
public void moveInFlightToSecondPhaseAckWaiting(int messageID) {
@@ -37,8 +37,6 @@ public interface IMessagesStore {
final String m_topic;
private boolean m_retained;
private String m_clientID;
// Optional attribute, available only fo QoS 1 and 2
private Integer m_msgID;
private MessageGUID m_guid;
public StoredMessage(byte[] message, MqttQoS qos, String topic) {
@@ -75,14 +73,6 @@ public interface IMessagesStore {
this.m_clientID = m_clientID;
}
public void setMessageID(Integer messageID) {
this.m_msgID = messageID;
}
public Integer getMessageID() {
return m_msgID;
}
public ByteBuf getMessage() {
return Unpooled.copiedBuffer(m_payload);
}
@@ -97,7 +87,7 @@ public interface IMessagesStore {
@Override
public String toString() {
return "PublishEvent{" + "m_msgID=" + m_msgID + ", clientID='" + m_clientID + '\'' + ", m_retain="
return "PublishEvent{clientID='" + m_clientID + '\'' + ", m_retain="
+ m_retained + ", m_qos=" + m_qos + ", m_topic='" + m_topic + '\'' + '}';
}
}
@@ -135,13 +125,9 @@ public interface IMessagesStore {
*/
MessageGUID storePublishForFuture(StoredMessage storedMessage);
void dropMessagesInSession(String clientID);
void dropInFlightMessagesInSession(Collection<MessageGUID> pendingAckMessages);
StoredMessage getMessageByGuid(MessageGUID guid);
void cleanRetained(Topic topic);
int getPendingPublishMessages(String clientID);
MessageGUID mapToGuid(String clientID, int messageID);
}
@@ -16,13 +16,14 @@
package io.moquette.spi;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import io.moquette.spi.IMessagesStore.StoredMessage;
import io.moquette.spi.impl.subscriptions.Subscription;
import io.moquette.spi.impl.subscriptions.Topic;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.BlockingQueue;
/**
* Store used to handle the persistence of the subscriptions tree.
*
@@ -188,24 +189,33 @@ public interface ISessionsStore {
/**
* Returns the number of inflight messages for the given client ID
*
* @param clientID
* @return
* @param clientID target client.
* @return count of pending in flight publish messages.
*/
int getInflightMessagesNo(String clientID);
/**
* @return the inflight inbound (PUBREL for Qos2) message.
* */
IMessagesStore.StoredMessage inboundInflight(String clientID, int messageID);
void markAsInboundInflight(String clientID, int messageID, MessageGUID guid);
/**
* Returns the size of the session queue for the given client ID
*
* @param clientID
* @return
* @param clientID target client.
* @return count of enqueued publish messages.
*/
int getPendingPublishMessagesNo(String clientID);
/**
* Returns the number of second-phase ACK pending messages for the given client ID
*
* @param clientID
* @return
* @param clientID target client.
* @return count of pending in flight publish messages.
*/
int getSecondPhaseAckPendingMessages(String clientID);
Collection<MessageGUID> pendingAck(String clientID);
}
@@ -47,7 +47,7 @@ final class BrokerInterceptor implements Interceptor {
private final ExecutorService executor;
private BrokerInterceptor(int poolSize, List<InterceptHandler> handlers) {
LOG.info("Initializing broker interceptor. InterceptorIds = {}.", getInterceptorIds(handlers));
LOG.info("Initializing broker interceptor. InterceptorIds={}", getInterceptorIds(handlers));
this.handlers = new HashMap<>();
for (Class<?> messageType : InterceptHandler.ALL_MESSAGE_TYPES) {
this.handlers.put(messageType, new CopyOnWriteArrayList<InterceptHandler>());
@@ -94,10 +94,8 @@ final class BrokerInterceptor implements Interceptor {
@Override
public void notifyClientConnected(final MqttConnectMessage msg) {
for (final InterceptHandler handler : this.handlers.get(InterceptConnectMessage.class)) {
LOG.debug(
"Sending MQTT CONNECT message to interceptor. MqttClientId = {}, interceptorId = {}.",
msg.payload().clientIdentifier(),
handler.getID());
LOG.debug("Sending MQTT CONNECT message to interceptor. CId={}, interceptorId={}",
msg.payload().clientIdentifier(), handler.getID());
executor.execute(new Runnable() {
@Override
@@ -111,12 +109,8 @@ final class BrokerInterceptor implements Interceptor {
@Override
public void notifyClientDisconnected(final String clientID, final String username) {
for (final InterceptHandler handler : this.handlers.get(InterceptDisconnectMessage.class)) {
LOG.debug(
"Notifying MQTT client disconnection to interceptor. MqttClientId = {}, username = {}, "
+ "interceptorId = {}.",
clientID,
username,
handler.getID());
LOG.debug("Notifying MQTT client disconnection to interceptor. CId={}, username={}, interceptorId={}",
clientID, username, handler.getID());
executor.execute(new Runnable() {
@Override
@@ -130,12 +124,8 @@ final class BrokerInterceptor implements Interceptor {
@Override
public void notifyClientConnectionLost(final String clientID, final String username) {
for (final InterceptHandler handler : this.handlers.get(InterceptConnectionLostMessage.class)) {
LOG.debug(
"Notifying unexpected MQTT client disconnection to interceptor. MqttClientId = {}, "
+ "username = {}, interceptorId = {}.",
clientID,
username,
handler.getID());
LOG.debug("Notifying unexpected MQTT client disconnection to interceptor CId={}, username={}, " +
"interceptorId={}", clientID, username, handler.getID());
executor.execute(new Runnable() {
@Override
@@ -151,13 +141,8 @@ final class BrokerInterceptor implements Interceptor {
int messageId = msg.variableHeader().messageId();
String topic = msg.variableHeader().topicName();
for (final InterceptHandler handler : this.handlers.get(InterceptPublishMessage.class)) {
LOG.debug(
"Notifying MQTT PUBLISH message to interceptor. MqttClientId = {}, messageId = {}, topic = {}, "
+ "interceptorId = {}.",
clientID,
messageId,
topic,
handler.getID());
LOG.debug("Notifying MQTT PUBLISH message to interceptor. CId={}, messageId={}, topic={}, interceptorId={}",
clientID, messageId, topic, handler.getID());
executor.execute(new Runnable() {
@Override
@@ -171,12 +156,8 @@ final class BrokerInterceptor implements Interceptor {
@Override
public void notifyTopicSubscribed(final Subscription sub, final String username) {
for (final InterceptHandler handler : this.handlers.get(InterceptSubscribeMessage.class)) {
LOG.debug(
"Notifying MQTT SUBSCRIBE message to interceptor. MqttClientId = {}, topicFilter = {}, "
+ "interceptorId = {}.",
sub.getClientId(),
sub.getTopicFilter(),
handler.getID());
LOG.debug("Notifying MQTT SUBSCRIBE message to interceptor. CId={}, topicFilter={}, interceptorId={}",
sub.getClientId(), sub.getTopicFilter(), handler.getID());
executor.execute(new Runnable() {
@Override
@@ -190,12 +171,8 @@ final class BrokerInterceptor implements Interceptor {
@Override
public void notifyTopicUnsubscribed(final String topic, final String clientID, final String username) {
for (final InterceptHandler handler : this.handlers.get(InterceptUnsubscribeMessage.class)) {
LOG.debug(
"Notifying MQTT UNSUBSCRIBE message to interceptor. MqttClientId = {}, topic = {}, "
+ "interceptorId = {}.",
clientID,
topic,
handler.getID());
LOG.debug("Notifying MQTT UNSUBSCRIBE message to interceptor. CId={}, topic={}, interceptorId={}", clientID,
topic, handler.getID());
executor.execute(new Runnable() {
@Override
@@ -209,13 +186,8 @@ final class BrokerInterceptor implements Interceptor {
@Override
public void notifyMessageAcknowledged(final InterceptAcknowledgedMessage msg) {
for (final InterceptHandler handler : this.handlers.get(InterceptAcknowledgedMessage.class)) {
LOG.debug(
"Notifying MQTT ACK message to interceptor. MqttClientId = {}, messageId = {}, topic = {}, "
+ "interceptorId = {}.",
msg.getMsg().getClientID(),
msg.getMsg().getMessageID(),
msg.getTopic(),
handler.getID());
LOG.debug("Notifying MQTT ACK message to interceptor. CId={}, messageId={}, topic={}, interceptorId={}",
msg.getMsg().getClientID(), msg.getPacketID(), msg.getTopic(), handler.getID());
executor.execute(new Runnable() {
@Override
@@ -229,10 +201,8 @@ final class BrokerInterceptor implements Interceptor {
@Override
public void addInterceptHandler(InterceptHandler interceptHandler) {
Class<?>[] interceptedMessageTypes = getInterceptedMessageTypes(interceptHandler);
LOG.info(
"Adding MQTT message interceptor. InterceptorId = {}, handledMessageTypes = {}.",
interceptHandler.getID(),
interceptedMessageTypes);
LOG.info( "Adding MQTT message interceptor. InterceptorId={}, handledMessageTypes={}",
interceptHandler.getID(), interceptedMessageTypes);
for (Class<?> interceptMessageType : interceptedMessageTypes) {
this.handlers.get(interceptMessageType).add(interceptHandler);
}
@@ -241,10 +211,8 @@ final class BrokerInterceptor implements Interceptor {
@Override
public void removeInterceptHandler(InterceptHandler interceptHandler) {
Class<?>[] interceptedMessageTypes = getInterceptedMessageTypes(interceptHandler);
LOG.info(
"Removing MQTT message interceptor. InterceptorId = {}, handledMessageTypes = {}.",
interceptHandler.getID(),
interceptedMessageTypes);
LOG.info("Removing MQTT message interceptor. InterceptorId={}, handledMessageTypes={}",
interceptHandler.getID(), interceptedMessageTypes);
for (Class<?> interceptMessageType : interceptedMessageTypes) {
this.handlers.get(interceptMessageType).remove(interceptHandler);
}
@@ -25,17 +25,16 @@ class InternalRepublisher {
void publishRetained(ClientSession targetSession, Collection<IMessagesStore.StoredMessage> messages) {
for (IMessagesStore.StoredMessage storedMsg : messages) {
// fire as retained the message
Integer packetID = storedMsg.getQos() == MqttQoS.AT_MOST_ONCE ? null : targetSession.nextPacketId();
if (packetID != null) {
LOG.debug("Adding message to inflight zone. ClientId={}, packetId={}, messageId={}, topic={}",
targetSession.clientID, packetID, storedMsg.getMessageID(), storedMsg.getTopic());
targetSession.inFlightAckWaiting(storedMsg.getGuid(), packetID);
}
MqttPublishMessage publishMsg = retainedPublish(storedMsg);
// set the PacketIdentifier only for QoS > 0
if (publishMsg.fixedHeader().qosLevel() != MqttQoS.AT_MOST_ONCE) {
if (storedMsg.getQos() != MqttQoS.AT_MOST_ONCE) {
LOG.debug("Adding message to inflight zone. ClientId={}, topic={}", targetSession.clientID,
storedMsg.getTopic());
int packetID = targetSession.inFlightAckWaiting(storedMsg.getGuid());
// set the PacketIdentifier only for QoS > 0
publishMsg = retainedPublish(storedMsg, packetID);
}
this.messageSender.sendPublish(targetSession, publishMsg);
}
}
@@ -46,13 +45,13 @@ class InternalRepublisher {
for (IMessagesStore.StoredMessage pubEvt : storedPublishes) {
// put in flight zone
LOG.debug("Adding message ot inflight zone. ClientId={}, guid={}, messageId={}, topic={}",
clientSession.clientID, pubEvt.getGuid(), pubEvt.getMessageID(), pubEvt.getTopic());
clientSession.inFlightAckWaiting(pubEvt.getGuid(), pubEvt.getMessageID());
LOG.debug("Adding message ot inflight zone. ClientId={}, guid={}, topic={}", clientSession.clientID,
pubEvt.getGuid(), pubEvt.getTopic());
int messageId = clientSession.inFlightAckWaiting(pubEvt.getGuid());
MqttPublishMessage publishMsg = notRetainedPublish(pubEvt);
// set the PacketIdentifier only for QoS > 0
if (publishMsg.fixedHeader().qosLevel() != MqttQoS.AT_MOST_ONCE) {
publishMsg = notRetainedPublish(pubEvt, pubEvt.getMessageID());
publishMsg = notRetainedPublish(pubEvt, messageId);
}
this.messageSender.sendPublish(clientSession, publishMsg);
}
@@ -63,25 +63,20 @@ class MessagesPublisher {
// refCnt = 0
ByteBuf message = origMessage.retainedDuplicate();
if (targetIsActive) {
LOG.debug(
"Sending PUBLISH message to active subscriber. MessageId={}, CId={}, topicFilter={}, qos={}",
pubMsg.getMessageID(),
sub.getClientId(),
sub.getTopicFilter(),
qos);
LOG.debug("Sending PUBLISH message to active subscriber. CId={}, topicFilter={}, qos={}",
sub.getClientId(), sub.getTopicFilter(), qos);
MqttPublishMessage publishMsg = notRetainedPublish(topic, qos, message);
if (qos != MqttQoS.AT_MOST_ONCE) {
// QoS 1 or 2
int messageId = targetSession.nextPacketId();
targetSession.inFlightAckWaiting(guid, messageId);
int messageId = targetSession.inFlightAckWaiting(guid);
// set the PacketIdentifier only for QoS > 0
publishMsg = notRetainedPublishWithMessageId(topic, qos, message, messageId);
}
this.messageSender.sendPublish(targetSession, publishMsg);
} else {
if (!targetSession.isCleanSession()) {
LOG.debug("Storing pending PUBLISH inactive message. MessageId={}, CId={}, topicFilter={}, qos={}",
pubMsg.getMessageID(), sub.getClientId(), sub.getTopicFilter(), qos);
LOG.debug("Storing pending PUBLISH inactive message. CId={}, topicFilter={}, qos={}",
sub.getClientId(), sub.getTopicFilter(), qos);
// store the message in targetSession queue to deliver
targetSession.enqueue(pubMsg);
}
@@ -474,7 +474,7 @@ public class ProtocolProcessor {
targetSession.inFlightAcknowledged(messageID);
String topic = inflightMsg.getTopic();
m_interceptor.notifyMessageAcknowledged(new InterceptAcknowledgedMessage(inflightMsg, topic, username));
m_interceptor.notifyMessageAcknowledged(new InterceptAcknowledgedMessage(inflightMsg, topic, username, messageID));
}
public static IMessagesStore.StoredMessage asStoredMessage(MqttPublishMessage msg) {
@@ -485,7 +485,6 @@ public class ProtocolProcessor {
IMessagesStore.StoredMessage stored = new IMessagesStore.StoredMessage(payloadContent,
msg.fixedHeader().qosLevel(), msg.variableHeader().topicName());
stored.setRetained(msg.fixedHeader().isRetain());
stored.setMessageID(msg.variableHeader().messageId());
return stored;
}
@@ -540,7 +539,6 @@ public class ProtocolProcessor {
} else {
toStoreMsg.setClientID(clientId);
}
toStoreMsg.setMessageID(1);
if (qos == EXACTLY_ONCE) { // QoS2
guid = m_messagesStore.storePublishForFuture(toStoreMsg);
}
@@ -568,18 +566,12 @@ public class ProtocolProcessor {
private void forwardPublishWill(WillMessage will, String clientID) {
// it has just to publish the message downstream to the subscribers
// NB it's a will publish, it needs a PacketIdentifier for this conn, default to 1
Integer messageId = null;
if (will.getQos() != AT_MOST_ONCE) {
messageId = m_sessionsStore.nextPacketID(clientID);
}
IMessagesStore.StoredMessage tobeStored = asStoredMessage(will);
tobeStored.setClientID(clientID);
tobeStored.setMessageID(messageId);
Topic topic = new Topic(tobeStored.getTopic());
List<Subscription> topicMatchingSubscriptions = subscriptions.matches(topic);
LOG.info("Publishing will message. CId={}, messageId={}, topic={}", clientID, messageId, topic);
LOG.info("Publishing will message. CId={}, topic={}", clientID, topic);
this.messagesPublisher.publish2Subscribers(tobeStored, topicMatchingSubscriptions);
}
@@ -626,7 +618,7 @@ public class ProtocolProcessor {
StoredMessage inflightMsg = targetSession.secondPhaseAcknowledged(messageID);
String username = NettyUtils.userName(channel);
String topic = inflightMsg.getTopic();
m_interceptor.notifyMessageAcknowledged(new InterceptAcknowledgedMessage(inflightMsg, topic, username));
m_interceptor.notifyMessageAcknowledged(new InterceptAcknowledgedMessage(inflightMsg, topic, username, messageID));
}
public void processDisconnect(Channel channel) throws InterruptedException {
@@ -759,8 +751,7 @@ public class ProtocolProcessor {
if (!validTopic) {
// close the connection, not valid topicFilter is a protocol violation
channel.close();
LOG.error( "Topic filter is not valid. CId={}, topics={}, badTopicFilter={}", clientID, topics,
topic);
LOG.error("Topic filter is not valid. CId={}, topics={}, badTopicFilter={}", clientID, topics, topic);
return;
}
@@ -16,6 +16,8 @@ import io.netty.handler.codec.mqtt.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import static io.moquette.spi.impl.DebugUtils.payload2Str;
import static io.moquette.spi.impl.ProtocolProcessor.asStoredMessage;
import static io.moquette.spi.impl.Utils.messageId;
import static io.netty.handler.codec.mqtt.MqttMessageIdVariableHeader.from;
@@ -23,7 +25,7 @@ import static io.netty.handler.codec.mqtt.MqttQoS.AT_MOST_ONCE;
class Qos2PublishHandler extends QosPublishHandler {
private static final Logger LOG = LoggerFactory.getLogger(Qos1PublishHandler.class);
private static final Logger LOG = LoggerFactory.getLogger(Qos2PublishHandler.class);
private final SubscriptionsStore subscriptions;
private final IMessagesStore m_messagesStore;
@@ -57,18 +59,16 @@ class Qos2PublishHandler extends QosPublishHandler {
String clientID = NettyUtils.clientID(channel);
toStoreMsg.setClientID(clientID);
LOG.info("Sending publish message to subscribers CId={}, topic={}, messageId={}", clientID, topic, messageID);
if (LOG.isTraceEnabled()) {
LOG.trace( "Sending publish message to subscribers. ClientId={}, topic={}, messageId={}, payload={}, " +
"subscriptionTree={}", clientID, topic, messageID, DebugUtils.payload2Str(toStoreMsg.getMessage()),
subscriptions.dumpTree());
} else {
LOG.info("Sending publish message to subscribers. ClientId={}, topic={}, messageId={}", clientID, topic,
messageID);
LOG.trace("payload={}, subs Tree={}", payload2Str(toStoreMsg.getMessage()), subscriptions.dumpTree());
}
// QoS2
MessageGUID guid = m_messagesStore.storePublishForFuture(toStoreMsg);
// TODO Don't send PUBREC for Hz publish notification, if (msg.isLocal()) {
ClientSession sourceSession = m_sessionsStore.sessionForClient(clientID);
sourceSession.markAsInboundInflight(messageID, guid);
sendPubRec(clientID, messageID);
// Next the client will send us a pub rel
@@ -92,18 +92,22 @@ class Qos2PublishHandler extends QosPublishHandler {
void processPubRel(Channel channel, MqttMessage msg) {
String clientID = NettyUtils.clientID(channel);
int messageID = messageId(msg);
LOG.info("Processing PUBREL message. ClientId={}, messageId={}", clientID, messageID);
LOG.info("Processing PUBREL message. CId={}, messageId={}", clientID, messageID);
ClientSession targetSession = m_sessionsStore.sessionForClient(clientID);
IMessagesStore.StoredMessage evt = targetSession.storedMessage(messageID);
IMessagesStore.StoredMessage evt = targetSession.inboundInflight(messageID);
if (evt == null) {
LOG.warn("Can't find inbound inflight message for CId={}, messageId={}", clientID, messageID);
throw new IllegalArgumentException("Can't find inbound inflight message");
}
final Topic topic = new Topic(evt.getTopic());
List<Subscription> topicMatchingSubscriptions = subscriptions.matches(topic);
if (LOG.isDebugEnabled()) {
LOG.debug("Sending publish message to subscribers. ClientId={}, topic={}, messageId={}, payload={}, " +
"subscriptionTree={}", clientID, topic, messageID, DebugUtils.payload2Str(evt.getMessage()),
LOG.debug("Sending publish message to subscribers. CId={}, topic={}, messageId={}, payload={}, " +
"subscriptionTree={}", clientID, topic, messageID, payload2Str(evt.getMessage()),
subscriptions.dumpTree());
} else {
LOG.info("Sending publish message to subscribers. ClientId={}, topic={}, messageId={}", clientID, topic,
LOG.info("Sending publish message to subscribers. CId={}, topic={}, messageId={}", clientID, topic,
messageID);
}
this.publisher.publish2Subscribers(evt, topicMatchingSubscriptions);
@@ -120,14 +124,14 @@ class Qos2PublishHandler extends QosPublishHandler {
}
private void sendPubRec(String clientID, int messageID) {
LOG.debug("Sending PUBREC message. ClientId={}, messageId={}", clientID, messageID);
LOG.debug("Sending PUBREC message. CId={}, messageId={}", clientID, messageID);
MqttFixedHeader fixedHeader = new MqttFixedHeader(MqttMessageType.PUBREC, false, AT_MOST_ONCE, false, 0);
MqttMessage pubRecMessage = new MqttMessage(fixedHeader, from(messageID));
connectionDescriptors.sendMessage(pubRecMessage, messageID, clientID);
}
private void sendPubComp(String clientID, int messageID) {
LOG.debug("Sending PUBCOMP message. ClientId={}, messageId={}", clientID, messageID);
LOG.debug("Sending PUBCOMP message. CId={}, messageId={}", clientID, messageID);
MqttFixedHeader fixedHeader = new MqttFixedHeader(MqttMessageType.PUBCOMP, false, AT_MOST_ONCE, false, 0);
MqttMessage pubCompMessage = new MqttMessage(fixedHeader, from(messageID));
connectionDescriptors.sendMessage(pubCompMessage, messageID, clientID);