Used the message store for QoS2 messages
This commit is contained in:
@@ -171,4 +171,9 @@ public class ClientSession {
|
||||
public void enqueueToDeliver(String guid) {
|
||||
this.m_sessionsStore.bindToDeliver(guid, this.clientID);
|
||||
}
|
||||
|
||||
public PublishEvent storedMessage(int messageID) {
|
||||
final String guid = m_sessionsStore.mapToGuid(clientID, messageID);
|
||||
return messagesStore.getMessageByGuid(guid);
|
||||
}
|
||||
}
|
||||
@@ -83,8 +83,10 @@ public interface IMessagesStore {
|
||||
|
||||
void dropMessagesInSession(String clientID);
|
||||
|
||||
PublishEvent getMessageByGuid(String guid);
|
||||
|
||||
/**
|
||||
* Return the next valid packetIdentifer for the given client session.
|
||||
* Return the next valid packetIdentifier for the given client session.
|
||||
* */
|
||||
int nextPacketID(String clientID);
|
||||
|
||||
|
||||
@@ -91,4 +91,6 @@ public interface ISessionsStore {
|
||||
void secondPhaseAcknowledged(String clientID, int messageID);
|
||||
|
||||
void secondPhaseAckWaiting(String clientID, int messageID);
|
||||
|
||||
String mapToGuid(String clientID, int messageID);
|
||||
}
|
||||
|
||||
@@ -121,7 +121,6 @@ public class ProtocolProcessor {
|
||||
ISessionsStore sessionsStore,
|
||||
IAuthenticator authenticator,
|
||||
boolean allowAnonymous, IAuthorizator authorizator, BrokerInterceptor interceptor) {
|
||||
//m_clientIDs = clientIDs;
|
||||
this.m_clientIDs = new ConcurrentHashMap<>();
|
||||
this.m_interceptor = interceptor;
|
||||
this.subscriptions = subscriptions;
|
||||
@@ -274,16 +273,10 @@ public class ProtocolProcessor {
|
||||
final String topic = msg.getTopicName();
|
||||
//check if the topic can be wrote
|
||||
String user = (String) session.getAttribute(NettyChannel.ATTR_KEY_USERNAME);
|
||||
if (m_authorizator.canWrite(topic, user, clientID)) {
|
||||
executePublish(clientID, msg);
|
||||
m_interceptor.notifyTopicPublished(msg, clientID);
|
||||
} else {
|
||||
if (!m_authorizator.canWrite(topic, user, clientID)) {
|
||||
LOG.debug("topic {} doesn't have write credentials", topic);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void executePublish(String clientID, PublishMessage msg) {
|
||||
final String topic = msg.getTopicName();
|
||||
final AbstractMessage.QOSType qos = msg.getQos();
|
||||
final ByteBuffer message = msg.getPayload();
|
||||
boolean retain = msg.isRetainFlag();
|
||||
@@ -298,9 +291,11 @@ public class ProtocolProcessor {
|
||||
sendPubAck(new PubAckEvent(messageID, clientID));
|
||||
LOG.debug("replying with PubAck to MSG ID {}", messageID);
|
||||
} else if (qos == AbstractMessage.QOSType.EXACTLY_ONCE) { //QoS2
|
||||
String publishKey = String.format("%s%d", clientID, messageID);
|
||||
// String publishKey = String.format("%s%d", clientID, messageID);
|
||||
//store the message in temp store
|
||||
m_messagesStore.persistQoS2Message(publishKey, publishEvt);
|
||||
//TODO use the global message store
|
||||
// m_messagesStore.persistQoS2Message(publishKey, publishEvt);
|
||||
m_messagesStore.storePublishForFuture(publishEvt);
|
||||
sendPubRec(clientID, messageID);
|
||||
//Next the client will send us a pub rel
|
||||
//NB publish to subscribers for QoS 2 happen upon PUBREL from publisher
|
||||
@@ -308,14 +303,15 @@ public class ProtocolProcessor {
|
||||
|
||||
if (retain) {
|
||||
if (qos == AbstractMessage.QOSType.MOST_ONE) {
|
||||
//QoS == 0 && retain => clean old retained
|
||||
//QoS == 0 && retain => clean old retained
|
||||
m_messagesStore.cleanRetained(topic);
|
||||
} else {
|
||||
m_messagesStore.storeRetained(topic, message, qos);
|
||||
}
|
||||
}
|
||||
m_interceptor.notifyTopicPublished(msg, clientID);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specialized version to publish will testament message.
|
||||
*/
|
||||
@@ -460,10 +456,13 @@ public class ProtocolProcessor {
|
||||
String clientID = (String) session.getAttribute(NettyChannel.ATTR_KEY_CLIENTID);
|
||||
int messageID = msg.getMessageID();
|
||||
LOG.debug("PUB --PUBREL--> SRV processPubRel invoked for clientID {} ad messageID {}", clientID, messageID);
|
||||
String publishKey = String.format("%s%d", clientID, messageID);
|
||||
PublishEvent evt = m_messagesStore.retrieveQoS2Message(publishKey);
|
||||
// String publishKey = String.format("%s%d", clientID, messageID);
|
||||
// PublishEvent evt = m_messagesStore.retrieveQoS2Message(publishKey);
|
||||
//get guid, get message
|
||||
ClientSession targetSession = m_sessionsStore.sessionForClient(clientID);
|
||||
PublishEvent evt = targetSession.storedMessage(messageID);
|
||||
forward2Subscribers(evt);
|
||||
m_messagesStore.removeQoS2Message(publishKey);
|
||||
// m_messagesStore.removeQoS2Message(publishKey);
|
||||
|
||||
if (evt.isRetain()) {
|
||||
final String topic = evt.getTopic();
|
||||
|
||||
@@ -170,6 +170,8 @@ public class MapDBPersistentStore implements IMessagesStore, ISessionsStore {
|
||||
String guid = UUID.randomUUID().toString();
|
||||
evt.setGuid(guid);
|
||||
m_persistentMessageStore.put(guid, convertToStored(evt));
|
||||
ConcurrentMap<Integer, String> messageIdToGuid = m_db.getHashMap("guidsMapping" + evt.getClientID());
|
||||
messageIdToGuid.put(evt.getMessageID(), guid);
|
||||
return guid;
|
||||
}
|
||||
|
||||
@@ -182,10 +184,23 @@ public class MapDBPersistentStore implements IMessagesStore, ISessionsStore {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropMessagesInSession(String clientID) {
|
||||
m_db.getHashMap("guidsMapping" + clientID).clear();
|
||||
m_persistentMessageStore.remove(clientID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PublishEvent getMessageByGuid(String guid) {
|
||||
return convertFromStored(m_persistentMessageStore.get(guid));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mapToGuid(String clientID, int messageID) {
|
||||
ConcurrentMap<Integer, String> messageIdToGuid = m_db.getHashMap("guidsMapping" + clientID);
|
||||
return messageIdToGuid.get(messageID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the next valid packetIdentifier for the given client session.
|
||||
* */
|
||||
|
||||
@@ -24,12 +24,10 @@ import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.eclipse.moquette.commons.Constants.PERSISTENT_STORE_PROPERTY_NAME;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
@@ -208,8 +206,8 @@ public class ServerIntegrationFuseTest {
|
||||
* subscriber connects again and receive "hello1" "hello2"
|
||||
*/
|
||||
@Test
|
||||
public void checkQoS2SuscriberDisconnectReceivePersistedPublishes() throws Exception {
|
||||
LOG.info("*** checkQoS2SuscriberDisconnectReceivePersistedPublishes ***");
|
||||
public void checkQoS2SubscriberDisconnectReceivePersistedPublishes() throws Exception {
|
||||
LOG.info("*** checkQoS2SubscriberDisconnectReceivePersistedPublishes ***");
|
||||
m_mqtt.setHost("localhost", 1883);
|
||||
m_mqtt.setCleanSession(false);
|
||||
m_mqtt.setClientId("Subscriber");
|
||||
|
||||
@@ -47,6 +47,7 @@ public class MemoryStorageService implements IMessagesStore, ISessionsStore {
|
||||
private Map<String, Set<Integer>> m_secondPhaseStore = new HashMap<>();
|
||||
private Map<String, Set<Integer>> m_inflightIDs = new HashMap<>();
|
||||
private Map<String, PublishEvent> m_qos2Store = new HashMap<>();
|
||||
private Map<String, Map<Integer, String>> m_messageToGuids = new HashMap<>();
|
||||
private MemorySessionStore m_sessionsStore;
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MemoryStorageService.class);
|
||||
@@ -95,6 +96,9 @@ public class MemoryStorageService implements IMessagesStore, ISessionsStore {
|
||||
String guid = UUID.randomUUID().toString();
|
||||
evt.setGuid(guid);
|
||||
m_persistentMessageStore.put(guid, evt);
|
||||
HashMap<Integer, String> guids = (HashMap<Integer, String>) defaultGet(m_messageToGuids,
|
||||
evt.getClientID(), new HashMap<Integer, String>());
|
||||
guids.put(evt.getMessageID(), guid);
|
||||
return guid;
|
||||
}
|
||||
|
||||
@@ -112,6 +116,18 @@ public class MemoryStorageService implements IMessagesStore, ISessionsStore {
|
||||
m_persistentMessageStore.remove(clientID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PublishEvent getMessageByGuid(String guid) {
|
||||
return m_persistentMessageStore.get(guid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mapToGuid(String clientID, int messageID) {
|
||||
HashMap<Integer, String> guids = (HashMap<Integer, String>) defaultGet(m_messageToGuids,
|
||||
clientID, new HashMap<Integer, String>());
|
||||
return guids.get(messageID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the next valid packetIdentifier for the given client session.
|
||||
* */
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.eclipse.moquette.spi.persistence;
|
||||
import org.eclipse.moquette.spi.ClientSession;
|
||||
import org.eclipse.moquette.spi.IMessagesStore;
|
||||
import org.eclipse.moquette.spi.ISessionsStore;
|
||||
import org.eclipse.moquette.spi.impl.MemoryStorageService;
|
||||
import org.eclipse.moquette.spi.impl.subscriptions.Subscription;
|
||||
|
||||
import static org.eclipse.moquette.spi.impl.Utils.defaultGet;
|
||||
@@ -29,7 +30,7 @@ import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author andream_messagesStore
|
||||
* @author andrea
|
||||
*/
|
||||
public class MemorySessionStore implements ISessionsStore {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MemorySessionStore.class);
|
||||
@@ -208,4 +209,9 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
messageIDs.add(messageID);
|
||||
m_secondPhaseStore.put(clientID, messageIDs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mapToGuid(String clientID, int messageID) {
|
||||
return ((MemoryStorageService) m_messagesStore).mapToGuid(clientID, messageID);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user