Changed String for guids to its value object
This commit is contained in:
@@ -78,14 +78,14 @@ public class ClientSession {
|
|||||||
* */
|
* */
|
||||||
public List<IMessagesStore.StoredMessage> storedMessages() {
|
public List<IMessagesStore.StoredMessage> storedMessages() {
|
||||||
//read all messages from enqueued store
|
//read all messages from enqueued store
|
||||||
Collection<String> guids = this.m_sessionsStore.enqueued(clientID);
|
Collection<MessageGUID> guids = this.m_sessionsStore.enqueued(clientID);
|
||||||
return messagesStore.listMessagesInSession(guids);
|
return messagesStore.listMessagesInSession(guids);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the messages stored in a cleanSession false.
|
* Remove the messages stored in a cleanSession false.
|
||||||
*/
|
*/
|
||||||
public void removeEnqueued(String guid) {
|
public void removeEnqueued(MessageGUID guid) {
|
||||||
this.m_sessionsStore.removeEnqueued(this.clientID, guid);
|
this.m_sessionsStore.removeEnqueued(this.clientID, guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,22 +175,22 @@ public class ClientSession {
|
|||||||
m_sessionsStore.inFlightAck(this.clientID, messageID);
|
m_sessionsStore.inFlightAck(this.clientID, messageID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void inFlightAckWaiting(String guid, int messageID) {
|
public void inFlightAckWaiting(MessageGUID guid, int messageID) {
|
||||||
LOG.trace("Adding to inflight {}, guid <{}>", messageID, guid);
|
LOG.trace("Adding to inflight {}, guid <{}>", messageID, guid);
|
||||||
m_sessionsStore.inFlight(this.clientID, messageID, guid);
|
m_sessionsStore.inFlight(this.clientID, messageID, guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IMessagesStore.StoredMessage secondPhaseAcknowledged(int messageID) {
|
public IMessagesStore.StoredMessage secondPhaseAcknowledged(int messageID) {
|
||||||
String guid = m_sessionsStore.secondPhaseAcknowledged(clientID, messageID);
|
MessageGUID guid = m_sessionsStore.secondPhaseAcknowledged(clientID, messageID);
|
||||||
return messagesStore.getMessageByGuid(guid);
|
return messagesStore.getMessageByGuid(guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enqueueToDeliver(String guid) {
|
public void enqueueToDeliver(MessageGUID guid) {
|
||||||
this.m_sessionsStore.bindToDeliver(guid, this.clientID);
|
this.m_sessionsStore.bindToDeliver(guid, this.clientID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IMessagesStore.StoredMessage storedMessage(int messageID) {
|
public IMessagesStore.StoredMessage storedMessage(int messageID) {
|
||||||
final String guid = m_sessionsStore.mapToGuid(clientID, messageID);
|
final MessageGUID guid = m_sessionsStore.mapToGuid(clientID, messageID);
|
||||||
return messagesStore.getMessageByGuid(guid);
|
return messagesStore.getMessageByGuid(guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public interface IMessagesStore {
|
|||||||
private String m_clientID;
|
private String m_clientID;
|
||||||
//Optional attribute, available only fo QoS 1 and 2
|
//Optional attribute, available only fo QoS 1 and 2
|
||||||
private Integer m_msgID;
|
private Integer m_msgID;
|
||||||
private String m_guid;
|
private MessageGUID m_guid;
|
||||||
private int referenceCounter = 0;
|
private int referenceCounter = 0;
|
||||||
|
|
||||||
public StoredMessage(byte[] message, AbstractMessage.QOSType qos, String topic) {
|
public StoredMessage(byte[] message, AbstractMessage.QOSType qos, String topic) {
|
||||||
@@ -56,11 +56,11 @@ public interface IMessagesStore {
|
|||||||
return m_topic;
|
return m_topic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGuid(String guid) {
|
public void setGuid(MessageGUID guid) {
|
||||||
this.m_guid = guid;
|
this.m_guid = guid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getGuid() {
|
public MessageGUID getGuid() {
|
||||||
return m_guid;
|
return m_guid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@ public interface IMessagesStore {
|
|||||||
* Persist the message.
|
* Persist the message.
|
||||||
* If the message is empty then the topic is cleaned, else it's stored.
|
* If the message is empty then the topic is cleaned, else it's stored.
|
||||||
*/
|
*/
|
||||||
void storeRetained(String topic, String guid);
|
void storeRetained(String topic, MessageGUID guid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a list of retained messages that satisfy the condition.
|
* Return a list of retained messages that satisfy the condition.
|
||||||
@@ -136,22 +136,22 @@ public interface IMessagesStore {
|
|||||||
* Persist the message.
|
* Persist the message.
|
||||||
* @return the unique id in the storage (guid).
|
* @return the unique id in the storage (guid).
|
||||||
* */
|
* */
|
||||||
String storePublishForFuture(StoredMessage evt);
|
MessageGUID storePublishForFuture(StoredMessage evt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the list of persisted publishes for the given clientID.
|
* Return the list of persisted publishes for the given clientID.
|
||||||
* For QoS1 and QoS2 with clean session flag, this method return the list of
|
* For QoS1 and QoS2 with clean session flag, this method return the list of
|
||||||
* missed publish events while the client was disconnected.
|
* missed publish events while the client was disconnected.
|
||||||
*/
|
*/
|
||||||
List<StoredMessage> listMessagesInSession(Collection<String> guids);
|
List<StoredMessage> listMessagesInSession(Collection<MessageGUID> guids);
|
||||||
|
|
||||||
void dropMessagesInSession(String clientID);
|
void dropMessagesInSession(String clientID);
|
||||||
|
|
||||||
StoredMessage getMessageByGuid(String guid);
|
StoredMessage getMessageByGuid(MessageGUID guid);
|
||||||
|
|
||||||
void cleanRetained(String topic);
|
void cleanRetained(String topic);
|
||||||
|
|
||||||
void incUsageCounter(String guid);
|
void incUsageCounter(MessageGUID guid);
|
||||||
|
|
||||||
void decUsageCounter(String guid);
|
void decUsageCounter(MessageGUID guid);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ public interface ISessionsStore {
|
|||||||
/**
|
/**
|
||||||
* Save the binding messageID, clientID <-> guid
|
* Save the binding messageID, clientID <-> guid
|
||||||
* */
|
* */
|
||||||
void inFlight(String clientID, int messageID, String guid);
|
void inFlight(String clientID, int messageID, MessageGUID guid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the next valid packetIdentifier for the given client session.
|
* Return the next valid packetIdentifier for the given client session.
|
||||||
@@ -122,26 +122,26 @@ public interface ISessionsStore {
|
|||||||
/**
|
/**
|
||||||
* Store the guid to be later published.
|
* Store the guid to be later published.
|
||||||
* */
|
* */
|
||||||
void bindToDeliver(String guid, String clientID);
|
void bindToDeliver(MessageGUID guid, String clientID);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List the guids for retained messages for the session
|
* List the guids for retained messages for the session
|
||||||
* */
|
* */
|
||||||
Collection<String> enqueued(String clientID);
|
Collection<MessageGUID> enqueued(String clientID);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove form the queue of stored messages for session.
|
* Remove form the queue of stored messages for session.
|
||||||
* */
|
* */
|
||||||
void removeEnqueued(String clientID, String guid);
|
void removeEnqueued(String clientID, MessageGUID guid);
|
||||||
|
|
||||||
void moveInFlightToSecondPhaseAckWaiting(String clientID, int messageID);
|
void moveInFlightToSecondPhaseAckWaiting(String clientID, int messageID);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the guid of message just acked.
|
* @return the guid of message just acked.
|
||||||
* */
|
* */
|
||||||
String secondPhaseAcknowledged(String clientID, int messageID);
|
MessageGUID secondPhaseAcknowledged(String clientID, int messageID);
|
||||||
|
|
||||||
String mapToGuid(String clientID, int messageID);
|
MessageGUID mapToGuid(String clientID, int messageID);
|
||||||
|
|
||||||
StoredMessage getInflightMessage(String clientID, int messageID);
|
StoredMessage getInflightMessage(String clientID, int messageID);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012-2015 The original author or authors
|
||||||
|
* ------------------------------------------------------
|
||||||
|
* 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.spi;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value object for GUIDs of messages.
|
||||||
|
* */
|
||||||
|
public class MessageGUID implements Serializable {
|
||||||
|
private final String guid;
|
||||||
|
|
||||||
|
public MessageGUID(String guid) {
|
||||||
|
this.guid = guid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
MessageGUID that = (MessageGUID) o;
|
||||||
|
|
||||||
|
return guid != null ? guid.equals(that.guid) : that.guid == null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return guid != null ? guid.hashCode() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "MessageGUID{" +
|
||||||
|
"guid='" + guid + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,11 +25,8 @@ import io.moquette.interception.InterceptHandler;
|
|||||||
import io.moquette.server.ConnectionDescriptor;
|
import io.moquette.server.ConnectionDescriptor;
|
||||||
import io.moquette.server.netty.AutoFlushHandler;
|
import io.moquette.server.netty.AutoFlushHandler;
|
||||||
import io.moquette.server.netty.NettyUtils;
|
import io.moquette.server.netty.NettyUtils;
|
||||||
import io.moquette.spi.ClientSession;
|
import io.moquette.spi.*;
|
||||||
import io.moquette.spi.IMatchingCondition;
|
|
||||||
import io.moquette.spi.IMessagesStore;
|
|
||||||
import io.moquette.spi.IMessagesStore.StoredMessage;
|
import io.moquette.spi.IMessagesStore.StoredMessage;
|
||||||
import io.moquette.spi.ISessionsStore;
|
|
||||||
import io.moquette.spi.security.IAuthenticator;
|
import io.moquette.spi.security.IAuthenticator;
|
||||||
import io.moquette.spi.security.IAuthorizator;
|
import io.moquette.spi.security.IAuthorizator;
|
||||||
import io.moquette.spi.impl.subscriptions.SubscriptionsStore;
|
import io.moquette.spi.impl.subscriptions.SubscriptionsStore;
|
||||||
@@ -150,7 +147,6 @@ public class ProtocolProcessor {
|
|||||||
* @param allowZeroByteClientId true to allow clients connect without a clientid
|
* @param allowZeroByteClientId true to allow clients connect without a clientid
|
||||||
* @param authorizator used to apply ACL policies to publishes and subscriptions.
|
* @param authorizator used to apply ACL policies to publishes and subscriptions.
|
||||||
* @param interceptor to notify events to an intercept handler
|
* @param interceptor to notify events to an intercept handler
|
||||||
* @param serverPort
|
|
||||||
*/
|
*/
|
||||||
void init(SubscriptionsStore subscriptions, IMessagesStore storageService,
|
void init(SubscriptionsStore subscriptions, IMessagesStore storageService,
|
||||||
ISessionsStore sessionsStore,
|
ISessionsStore sessionsStore,
|
||||||
@@ -387,7 +383,7 @@ public class ProtocolProcessor {
|
|||||||
final Integer messageID = msg.getMessageID();
|
final Integer messageID = msg.getMessageID();
|
||||||
LOG.info("PUBLISH on server {} from clientID <{}> on topic <{}> with QoS {}", m_server_port, clientID, topic, qos);
|
LOG.info("PUBLISH on server {} from clientID <{}> on topic <{}> with QoS {}", m_server_port, clientID, topic, qos);
|
||||||
|
|
||||||
String guid = null;
|
MessageGUID guid = null;
|
||||||
IMessagesStore.StoredMessage toStoreMsg = asStoredMessage(msg);
|
IMessagesStore.StoredMessage toStoreMsg = asStoredMessage(msg);
|
||||||
toStoreMsg.setClientID(clientID);
|
toStoreMsg.setClientID(clientID);
|
||||||
if (qos == AbstractMessage.QOSType.MOST_ONE) { //QoS0
|
if (qos == AbstractMessage.QOSType.MOST_ONE) { //QoS0
|
||||||
@@ -439,7 +435,7 @@ public class ProtocolProcessor {
|
|||||||
final String topic = msg.getTopicName();
|
final String topic = msg.getTopicName();
|
||||||
LOG.info("embedded PUBLISH on topic <{}> with QoS {}", topic, qos);
|
LOG.info("embedded PUBLISH on topic <{}> with QoS {}", topic, qos);
|
||||||
|
|
||||||
String guid = null;
|
MessageGUID guid = null;
|
||||||
IMessagesStore.StoredMessage toStoreMsg = asStoredMessage(msg);
|
IMessagesStore.StoredMessage toStoreMsg = asStoredMessage(msg);
|
||||||
if (msg.getClientId() == null || msg.getClientId().isEmpty()) {
|
if (msg.getClientId() == null || msg.getClientId().isEmpty()) {
|
||||||
toStoreMsg.setClientID("BROKER_SELF");
|
toStoreMsg.setClientID("BROKER_SELF");
|
||||||
@@ -498,7 +494,7 @@ public class ProtocolProcessor {
|
|||||||
LOG.trace("subscription tree {}", subscriptions.dumpTree());
|
LOG.trace("subscription tree {}", subscriptions.dumpTree());
|
||||||
}
|
}
|
||||||
//if QoS 1 or 2 store the message
|
//if QoS 1 or 2 store the message
|
||||||
String guid = null;
|
MessageGUID guid = null;
|
||||||
if (publishingQos == QOSType.EXACTLY_ONCE || publishingQos == QOSType.LEAST_ONE) {
|
if (publishingQos == QOSType.EXACTLY_ONCE || publishingQos == QOSType.LEAST_ONE) {
|
||||||
guid = m_messagesStore.storePublishForFuture(pubMsg);
|
guid = m_messagesStore.storePublishForFuture(pubMsg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ package io.moquette.spi.persistence;
|
|||||||
|
|
||||||
import io.moquette.spi.IMatchingCondition;
|
import io.moquette.spi.IMatchingCondition;
|
||||||
import io.moquette.spi.IMessagesStore;
|
import io.moquette.spi.IMessagesStore;
|
||||||
|
import io.moquette.spi.MessageGUID;
|
||||||
import org.mapdb.DB;
|
import org.mapdb.DB;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -36,9 +37,9 @@ class MapDBMessagesStore implements IMessagesStore {
|
|||||||
private DB m_db;
|
private DB m_db;
|
||||||
|
|
||||||
//maps clientID -> guid
|
//maps clientID -> guid
|
||||||
private ConcurrentMap<String, String> m_retainedStore;
|
private ConcurrentMap<String, MessageGUID> m_retainedStore;
|
||||||
//maps guid to message, it's message store
|
//maps guid to message, it's message store
|
||||||
private ConcurrentMap<String, IMessagesStore.StoredMessage> m_persistentMessageStore;
|
private ConcurrentMap<MessageGUID, IMessagesStore.StoredMessage> m_persistentMessageStore;
|
||||||
|
|
||||||
|
|
||||||
MapDBMessagesStore(DB db) {
|
MapDBMessagesStore(DB db) {
|
||||||
@@ -52,7 +53,7 @@ class MapDBMessagesStore implements IMessagesStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void storeRetained(String topic, String guid) {
|
public void storeRetained(String topic, MessageGUID guid) {
|
||||||
m_retainedStore.put(topic, guid);
|
m_retainedStore.put(topic, guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,8 +62,8 @@ class MapDBMessagesStore implements IMessagesStore {
|
|||||||
LOG.debug("searchMatching scanning all retained messages, presents are {}", m_retainedStore.size());
|
LOG.debug("searchMatching scanning all retained messages, presents are {}", m_retainedStore.size());
|
||||||
|
|
||||||
List<StoredMessage> results = new ArrayList<>();
|
List<StoredMessage> results = new ArrayList<>();
|
||||||
for (Map.Entry<String, String> entry : m_retainedStore.entrySet()) {
|
for (Map.Entry<String, MessageGUID> entry : m_retainedStore.entrySet()) {
|
||||||
final String guid = entry.getValue();
|
final MessageGUID guid = entry.getValue();
|
||||||
StoredMessage storedMsg = m_persistentMessageStore.get(guid);
|
StoredMessage storedMsg = m_persistentMessageStore.get(guid);
|
||||||
if (condition.match(entry.getKey())) {
|
if (condition.match(entry.getKey())) {
|
||||||
results.add(storedMsg);
|
results.add(storedMsg);
|
||||||
@@ -73,25 +74,25 @@ class MapDBMessagesStore implements IMessagesStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String storePublishForFuture(StoredMessage evt) {
|
public MessageGUID storePublishForFuture(StoredMessage evt) {
|
||||||
LOG.debug("storePublishForFuture store evt {}", evt);
|
LOG.debug("storePublishForFuture store evt {}", evt);
|
||||||
if (evt.getClientID() == null) {
|
if (evt.getClientID() == null) {
|
||||||
LOG.error("persisting a message without a clientID, bad programming error msg: {}", evt);
|
LOG.error("persisting a message without a clientID, bad programming error msg: {}", evt);
|
||||||
throw new IllegalArgumentException("\"persisting a message without a clientID, bad programming error");
|
throw new IllegalArgumentException("\"persisting a message without a clientID, bad programming error");
|
||||||
}
|
}
|
||||||
String guid = UUID.randomUUID().toString();
|
MessageGUID guid = new MessageGUID(UUID.randomUUID().toString());
|
||||||
evt.setGuid(guid);
|
evt.setGuid(guid);
|
||||||
LOG.debug("storePublishForFuture guid <{}>", guid);
|
LOG.debug("storePublishForFuture guid <{}>", guid);
|
||||||
m_persistentMessageStore.put(guid, evt);
|
m_persistentMessageStore.put(guid, evt);
|
||||||
ConcurrentMap<Integer, String> messageIdToGuid = m_db.getHashMap(MapDBSessionsStore.messageId2GuidsMapName(evt.getClientID()));
|
ConcurrentMap<Integer, MessageGUID> messageIdToGuid = m_db.getHashMap(MapDBSessionsStore.messageId2GuidsMapName(evt.getClientID()));
|
||||||
messageIdToGuid.put(evt.getMessageID(), guid);
|
messageIdToGuid.put(evt.getMessageID(), guid);
|
||||||
return guid;
|
return guid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<StoredMessage> listMessagesInSession(Collection<String> guids) {
|
public List<StoredMessage> listMessagesInSession(Collection<MessageGUID> guids) {
|
||||||
List<StoredMessage> ret = new ArrayList<>();
|
List<StoredMessage> ret = new ArrayList<>();
|
||||||
for (String guid : guids) {
|
for (MessageGUID guid : guids) {
|
||||||
ret.add(m_persistentMessageStore.get(guid));
|
ret.add(m_persistentMessageStore.get(guid));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@@ -99,14 +100,14 @@ class MapDBMessagesStore implements IMessagesStore {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dropMessagesInSession(String clientID) {
|
public void dropMessagesInSession(String clientID) {
|
||||||
ConcurrentMap<Integer, String> messageIdToGuid = m_db.getHashMap(MapDBSessionsStore.messageId2GuidsMapName(clientID));
|
ConcurrentMap<Integer, MessageGUID> messageIdToGuid = m_db.getHashMap(MapDBSessionsStore.messageId2GuidsMapName(clientID));
|
||||||
for (String guid : messageIdToGuid.values()) {
|
for (MessageGUID guid : messageIdToGuid.values()) {
|
||||||
removeStoredMessage(guid);
|
removeStoredMessage(guid);
|
||||||
}
|
}
|
||||||
messageIdToGuid.clear();
|
messageIdToGuid.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeStoredMessage(String guid) {
|
void removeStoredMessage(MessageGUID guid) {
|
||||||
//remove only the not retained and no more referenced
|
//remove only the not retained and no more referenced
|
||||||
StoredMessage storedMessage = m_persistentMessageStore.get(guid);
|
StoredMessage storedMessage = m_persistentMessageStore.get(guid);
|
||||||
if (!storedMessage.isRetained() && storedMessage.getReferenceCounter() == 0) {
|
if (!storedMessage.isRetained() && storedMessage.getReferenceCounter() == 0) {
|
||||||
@@ -116,7 +117,7 @@ class MapDBMessagesStore implements IMessagesStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StoredMessage getMessageByGuid(String guid) {
|
public StoredMessage getMessageByGuid(MessageGUID guid) {
|
||||||
return m_persistentMessageStore.get(guid);
|
return m_persistentMessageStore.get(guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,14 +127,14 @@ class MapDBMessagesStore implements IMessagesStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void incUsageCounter(String guid) {
|
public void incUsageCounter(MessageGUID guid) {
|
||||||
IMessagesStore.StoredMessage storedMessage = m_persistentMessageStore.get(guid);
|
IMessagesStore.StoredMessage storedMessage = m_persistentMessageStore.get(guid);
|
||||||
storedMessage.incReferenceCounter();
|
storedMessage.incReferenceCounter();
|
||||||
m_persistentMessageStore.replace(guid, storedMessage);
|
m_persistentMessageStore.replace(guid, storedMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decUsageCounter(String guid) {
|
public void decUsageCounter(MessageGUID guid) {
|
||||||
IMessagesStore.StoredMessage storedMessage = m_persistentMessageStore.get(guid);
|
IMessagesStore.StoredMessage storedMessage = m_persistentMessageStore.get(guid);
|
||||||
storedMessage.decReferenceCounter();
|
storedMessage.decReferenceCounter();
|
||||||
m_persistentMessageStore.replace(guid, storedMessage);
|
m_persistentMessageStore.replace(guid, storedMessage);
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package io.moquette.spi.persistence;
|
|||||||
import io.moquette.spi.ClientSession;
|
import io.moquette.spi.ClientSession;
|
||||||
import io.moquette.spi.IMessagesStore.StoredMessage;
|
import io.moquette.spi.IMessagesStore.StoredMessage;
|
||||||
import io.moquette.spi.ISessionsStore;
|
import io.moquette.spi.ISessionsStore;
|
||||||
|
import io.moquette.spi.MessageGUID;
|
||||||
import io.moquette.spi.impl.Utils;
|
import io.moquette.spi.impl.Utils;
|
||||||
import io.moquette.spi.impl.subscriptions.Subscription;
|
import io.moquette.spi.impl.subscriptions.Subscription;
|
||||||
import io.moquette.spi.persistence.MapDBPersistentStore.PersistentSession;
|
import io.moquette.spi.persistence.MapDBPersistentStore.PersistentSession;
|
||||||
@@ -38,14 +39,14 @@ class MapDBSessionsStore implements ISessionsStore {
|
|||||||
private static final Logger LOG = LoggerFactory.getLogger(MapDBSessionsStore.class);
|
private static final Logger LOG = LoggerFactory.getLogger(MapDBSessionsStore.class);
|
||||||
|
|
||||||
//maps clientID->[MessageId -> guid]
|
//maps clientID->[MessageId -> guid]
|
||||||
private ConcurrentMap<String, Map<Integer, String>> m_inflightStore;
|
private ConcurrentMap<String, Map<Integer, MessageGUID>> m_inflightStore;
|
||||||
//map clientID <-> set of currently in flight packet identifiers
|
//map clientID <-> set of currently in flight packet identifiers
|
||||||
private Map<String, Set<Integer>> m_inFlightIds;
|
private Map<String, Set<Integer>> m_inFlightIds;
|
||||||
private ConcurrentMap<String, PersistentSession> m_persistentSessions;
|
private ConcurrentMap<String, PersistentSession> m_persistentSessions;
|
||||||
//maps clientID->[guid*], insertion order cares, it's queue
|
//maps clientID->[guid*], insertion order cares, it's queue
|
||||||
private ConcurrentMap<String, List<String>> m_enqueuedStore;
|
private ConcurrentMap<String, List<MessageGUID>> m_enqueuedStore;
|
||||||
//maps clientID->[MessageId -> guid]
|
//maps clientID->[MessageId -> guid]
|
||||||
private ConcurrentMap<String, Map<Integer, String>> m_secondPhaseStore;
|
private ConcurrentMap<String, Map<Integer, MessageGUID>> m_secondPhaseStore;
|
||||||
|
|
||||||
private final DB m_db;
|
private final DB m_db;
|
||||||
private final MapDBMessagesStore m_messagesStore;
|
private final MapDBMessagesStore m_messagesStore;
|
||||||
@@ -172,7 +173,7 @@ class MapDBSessionsStore implements ISessionsStore {
|
|||||||
@Override
|
@Override
|
||||||
public void inFlightAck(String clientID, int messageID) {
|
public void inFlightAck(String clientID, int messageID) {
|
||||||
LOG.info("acknowledging inflight clientID <{}> messageID {}", clientID, messageID);
|
LOG.info("acknowledging inflight clientID <{}> messageID {}", clientID, messageID);
|
||||||
Map<Integer, String> m = this.m_inflightStore.get(clientID);
|
Map<Integer, MessageGUID> m = this.m_inflightStore.get(clientID);
|
||||||
if (m == null) {
|
if (m == null) {
|
||||||
LOG.error("Can't find the inFlight record for client <{}>", clientID);
|
LOG.error("Can't find the inFlight record for client <{}>", clientID);
|
||||||
return;
|
return;
|
||||||
@@ -187,8 +188,8 @@ class MapDBSessionsStore implements ISessionsStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void inFlight(String clientID, int messageID, String guid) {
|
public void inFlight(String clientID, int messageID, MessageGUID guid) {
|
||||||
Map<Integer, String> m = this.m_inflightStore.get(clientID);
|
Map<Integer, MessageGUID> m = this.m_inflightStore.get(clientID);
|
||||||
if (m == null) {
|
if (m == null) {
|
||||||
m = new HashMap<>();
|
m = new HashMap<>();
|
||||||
}
|
}
|
||||||
@@ -198,21 +199,21 @@ class MapDBSessionsStore implements ISessionsStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bindToDeliver(String guid, String clientID) {
|
public void bindToDeliver(MessageGUID guid, String clientID) {
|
||||||
List<String> guids = Utils.defaultGet(m_enqueuedStore, clientID, new ArrayList<String>());
|
List<MessageGUID> guids = Utils.defaultGet(m_enqueuedStore, clientID, new ArrayList<MessageGUID>());
|
||||||
guids.add(guid);
|
guids.add(guid);
|
||||||
m_enqueuedStore.put(clientID, guids);
|
m_enqueuedStore.put(clientID, guids);
|
||||||
m_messagesStore.incUsageCounter(guid);
|
m_messagesStore.incUsageCounter(guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<String> enqueued(String clientID) {
|
public Collection<MessageGUID> enqueued(String clientID) {
|
||||||
return Utils.defaultGet(m_enqueuedStore, clientID, new ArrayList<String>());
|
return Utils.defaultGet(m_enqueuedStore, clientID, new ArrayList<MessageGUID>());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeEnqueued(String clientID, String guid) {
|
public void removeEnqueued(String clientID, MessageGUID guid) {
|
||||||
List<String> guids = Utils.defaultGet(m_enqueuedStore, clientID, new ArrayList<String>());
|
List<MessageGUID> guids = Utils.defaultGet(m_enqueuedStore, clientID, new ArrayList<MessageGUID>());
|
||||||
guids.remove(guid);
|
guids.remove(guid);
|
||||||
m_enqueuedStore.put(clientID, guids);
|
m_enqueuedStore.put(clientID, guids);
|
||||||
m_messagesStore.decUsageCounter(guid);
|
m_messagesStore.decUsageCounter(guid);
|
||||||
@@ -223,12 +224,12 @@ class MapDBSessionsStore implements ISessionsStore {
|
|||||||
@Override
|
@Override
|
||||||
public void moveInFlightToSecondPhaseAckWaiting(String clientID, int messageID) {
|
public void moveInFlightToSecondPhaseAckWaiting(String clientID, int messageID) {
|
||||||
LOG.info("acknowledging inflight clientID <{}> messageID {}", clientID, messageID);
|
LOG.info("acknowledging inflight clientID <{}> messageID {}", clientID, messageID);
|
||||||
Map<Integer, String> m = this.m_inflightStore.get(clientID);
|
Map<Integer, MessageGUID> m = this.m_inflightStore.get(clientID);
|
||||||
if (m == null) {
|
if (m == null) {
|
||||||
LOG.error("Can't find the inFlight record for client <{}>", clientID);
|
LOG.error("Can't find the inFlight record for client <{}>", clientID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String guid = m.remove(messageID);
|
MessageGUID guid = m.remove(messageID);
|
||||||
|
|
||||||
//remove from the ids store
|
//remove from the ids store
|
||||||
Set<Integer> inFlightForClient = this.m_inFlightIds.get(clientID);
|
Set<Integer> inFlightForClient = this.m_inFlightIds.get(clientID);
|
||||||
@@ -237,22 +238,22 @@ class MapDBSessionsStore implements ISessionsStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LOG.info("Moving to second phase store");
|
LOG.info("Moving to second phase store");
|
||||||
Map<Integer, String> messageIDs = Utils.defaultGet(m_secondPhaseStore, clientID, new HashMap<Integer, String>());
|
Map<Integer, MessageGUID> messageIDs = Utils.defaultGet(m_secondPhaseStore, clientID, new HashMap<Integer, MessageGUID>());
|
||||||
messageIDs.put(messageID, guid);
|
messageIDs.put(messageID, guid);
|
||||||
m_secondPhaseStore.put(clientID, messageIDs);
|
m_secondPhaseStore.put(clientID, messageIDs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String secondPhaseAcknowledged(String clientID, int messageID) {
|
public MessageGUID secondPhaseAcknowledged(String clientID, int messageID) {
|
||||||
Map<Integer, String> messageIDs = Utils.defaultGet(m_secondPhaseStore, clientID, new HashMap<Integer, String>());
|
Map<Integer, MessageGUID> messageIDs = Utils.defaultGet(m_secondPhaseStore, clientID, new HashMap<Integer, MessageGUID>());
|
||||||
String guid = messageIDs.remove(messageID);
|
MessageGUID guid = messageIDs.remove(messageID);
|
||||||
m_secondPhaseStore.put(clientID, messageIDs);
|
m_secondPhaseStore.put(clientID, messageIDs);
|
||||||
return guid;
|
return guid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String mapToGuid(String clientID, int messageID) {
|
public MessageGUID mapToGuid(String clientID, int messageID) {
|
||||||
ConcurrentMap<Integer, String> messageIdToGuid = m_db.getHashMap(messageId2GuidsMapName(clientID));
|
ConcurrentMap<Integer, MessageGUID> messageIdToGuid = m_db.getHashMap(messageId2GuidsMapName(clientID));
|
||||||
return messageIdToGuid.get(messageID);
|
return messageIdToGuid.get(messageID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,10 +263,10 @@ class MapDBSessionsStore implements ISessionsStore {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StoredMessage getInflightMessage(String clientID, int messageID) {
|
public StoredMessage getInflightMessage(String clientID, int messageID) {
|
||||||
Map<Integer, String> clientEntries = m_inflightStore.get(clientID);
|
Map<Integer, MessageGUID> clientEntries = m_inflightStore.get(clientID);
|
||||||
if (clientEntries == null)
|
if (clientEntries == null)
|
||||||
return null;
|
return null;
|
||||||
String guid = clientEntries.get(messageID);
|
MessageGUID guid = clientEntries.get(messageID);
|
||||||
LOG.info("inflight messageID {} guid <{}>", messageID, guid);
|
LOG.info("inflight messageID {} guid <{}>", messageID, guid);
|
||||||
if (guid == null)
|
if (guid == null)
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ package io.moquette.spi.impl;
|
|||||||
|
|
||||||
import io.moquette.spi.IMessagesStore;
|
import io.moquette.spi.IMessagesStore;
|
||||||
import io.moquette.spi.IMatchingCondition;
|
import io.moquette.spi.IMatchingCondition;
|
||||||
|
import io.moquette.spi.MessageGUID;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -31,11 +32,11 @@ public class MemoryMessagesStore implements IMessagesStore {
|
|||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(MemoryMessagesStore.class);
|
private static final Logger LOG = LoggerFactory.getLogger(MemoryMessagesStore.class);
|
||||||
|
|
||||||
private Map<String, String> m_retainedStore = new HashMap<>();
|
private Map<String, MessageGUID> m_retainedStore = new HashMap<>();
|
||||||
private Map<String, StoredMessage> m_persistentMessageStore = new HashMap<>();
|
private Map<MessageGUID, StoredMessage> m_persistentMessageStore = new HashMap<>();
|
||||||
private Map<String, Map<Integer, String>> m_messageToGuids;
|
private Map<String, Map<Integer, MessageGUID>> m_messageToGuids;
|
||||||
|
|
||||||
MemoryMessagesStore(Map<String, Map<Integer, String>> messageToGuids) {
|
MemoryMessagesStore(Map<String, Map<Integer, MessageGUID>> messageToGuids) {
|
||||||
m_messageToGuids = messageToGuids;
|
m_messageToGuids = messageToGuids;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +45,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void storeRetained(String topic, String guid) {
|
public void storeRetained(String topic, MessageGUID guid) {
|
||||||
m_retainedStore.put(topic, guid);
|
m_retainedStore.put(topic, guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,8 +55,8 @@ public class MemoryMessagesStore implements IMessagesStore {
|
|||||||
|
|
||||||
List<StoredMessage> results = new ArrayList<>();
|
List<StoredMessage> results = new ArrayList<>();
|
||||||
|
|
||||||
for (Map.Entry<String, String> entry : m_retainedStore.entrySet()) {
|
for (Map.Entry<String, MessageGUID> entry : m_retainedStore.entrySet()) {
|
||||||
final String guid = entry.getValue();
|
final MessageGUID guid = entry.getValue();
|
||||||
StoredMessage storedMsg = m_persistentMessageStore.get(guid);
|
StoredMessage storedMsg = m_persistentMessageStore.get(guid);
|
||||||
if (condition.match(entry.getKey())) {
|
if (condition.match(entry.getKey())) {
|
||||||
results.add(storedMsg);
|
results.add(storedMsg);
|
||||||
@@ -66,21 +67,21 @@ public class MemoryMessagesStore implements IMessagesStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String storePublishForFuture(StoredMessage evt) {
|
public MessageGUID storePublishForFuture(StoredMessage evt) {
|
||||||
LOG.debug("storePublishForFuture store evt {}", evt);
|
LOG.debug("storePublishForFuture store evt {}", evt);
|
||||||
String guid = UUID.randomUUID().toString();
|
MessageGUID guid = new MessageGUID(UUID.randomUUID().toString());
|
||||||
evt.setGuid(guid);
|
evt.setGuid(guid);
|
||||||
m_persistentMessageStore.put(guid, evt);
|
m_persistentMessageStore.put(guid, evt);
|
||||||
HashMap<Integer, String> guids = (HashMap<Integer, String>) defaultGet(m_messageToGuids,
|
HashMap<Integer, MessageGUID> guids = (HashMap<Integer, MessageGUID>) defaultGet(m_messageToGuids,
|
||||||
evt.getClientID(), new HashMap<Integer, String>());
|
evt.getClientID(), new HashMap<Integer, MessageGUID>());
|
||||||
guids.put(evt.getMessageID(), guid);
|
guids.put(evt.getMessageID(), guid);
|
||||||
return guid;
|
return guid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<StoredMessage> listMessagesInSession(Collection<String> guids) {
|
public List<StoredMessage> listMessagesInSession(Collection<MessageGUID> guids) {
|
||||||
List<StoredMessage> ret = new ArrayList<>();
|
List<StoredMessage> ret = new ArrayList<>();
|
||||||
for (String guid : guids) {
|
for (MessageGUID guid : guids) {
|
||||||
ret.add(m_persistentMessageStore.get(guid));
|
ret.add(m_persistentMessageStore.get(guid));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@@ -88,11 +89,17 @@ public class MemoryMessagesStore implements IMessagesStore {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dropMessagesInSession(String clientID) {
|
public void dropMessagesInSession(String clientID) {
|
||||||
m_persistentMessageStore.remove(clientID);
|
Map<Integer, MessageGUID> messageGUIDMap = m_messageToGuids.get(clientID);
|
||||||
|
if (messageGUIDMap == null || messageGUIDMap.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (MessageGUID guid : messageGUIDMap.values()) {
|
||||||
|
m_persistentMessageStore.remove(guid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StoredMessage getMessageByGuid(String guid) {
|
public StoredMessage getMessageByGuid(MessageGUID guid) {
|
||||||
return m_persistentMessageStore.get(guid);
|
return m_persistentMessageStore.get(guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,14 +109,14 @@ public class MemoryMessagesStore implements IMessagesStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void incUsageCounter(String guid) {
|
public void incUsageCounter(MessageGUID guid) {
|
||||||
IMessagesStore.StoredMessage storedMessage = m_persistentMessageStore.get(guid);
|
IMessagesStore.StoredMessage storedMessage = m_persistentMessageStore.get(guid);
|
||||||
storedMessage.incReferenceCounter();
|
storedMessage.incReferenceCounter();
|
||||||
m_persistentMessageStore.replace(guid, storedMessage);
|
m_persistentMessageStore.replace(guid, storedMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decUsageCounter(String guid) {
|
public void decUsageCounter(MessageGUID guid) {
|
||||||
IMessagesStore.StoredMessage storedMessage = m_persistentMessageStore.get(guid);
|
IMessagesStore.StoredMessage storedMessage = m_persistentMessageStore.get(guid);
|
||||||
storedMessage.decReferenceCounter();
|
storedMessage.decReferenceCounter();
|
||||||
m_persistentMessageStore.replace(guid, storedMessage);
|
m_persistentMessageStore.replace(guid, storedMessage);
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ package io.moquette.spi.impl;
|
|||||||
|
|
||||||
import io.moquette.spi.IMessagesStore;
|
import io.moquette.spi.IMessagesStore;
|
||||||
import io.moquette.spi.ISessionsStore;
|
import io.moquette.spi.ISessionsStore;
|
||||||
|
import io.moquette.spi.MessageGUID;
|
||||||
import io.moquette.spi.persistence.MemorySessionStore;
|
import io.moquette.spi.persistence.MemorySessionStore;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -28,7 +29,7 @@ public class MemoryStorageService {
|
|||||||
private MemoryMessagesStore m_messagesStore;
|
private MemoryMessagesStore m_messagesStore;
|
||||||
|
|
||||||
public void initStore() {
|
public void initStore() {
|
||||||
Map<String, Map<Integer, String>> messageToGuids = new HashMap<>();
|
Map<String, Map<Integer, MessageGUID>> messageToGuids = new HashMap<>();
|
||||||
m_messagesStore = new MemoryMessagesStore(messageToGuids);
|
m_messagesStore = new MemoryMessagesStore(messageToGuids);
|
||||||
m_sessionsStore = new MemorySessionStore(m_messagesStore, messageToGuids);
|
m_sessionsStore = new MemorySessionStore(m_messagesStore, messageToGuids);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,8 @@ import io.moquette.interception.InterceptHandler;
|
|||||||
import io.moquette.parser.proto.messages.AbstractMessage.QOSType;
|
import io.moquette.parser.proto.messages.AbstractMessage.QOSType;
|
||||||
import io.moquette.server.ConnectionDescriptor;
|
import io.moquette.server.ConnectionDescriptor;
|
||||||
import io.moquette.server.netty.NettyUtils;
|
import io.moquette.server.netty.NettyUtils;
|
||||||
import io.moquette.spi.ClientSession;
|
import io.moquette.spi.*;
|
||||||
import io.moquette.spi.IMatchingCondition;
|
|
||||||
import io.moquette.spi.IMessagesStore;
|
|
||||||
import io.moquette.spi.IMessagesStore.StoredMessage;
|
import io.moquette.spi.IMessagesStore.StoredMessage;
|
||||||
import io.moquette.spi.ISessionsStore;
|
|
||||||
import io.moquette.spi.impl.security.PermitAllAuthorizator;
|
import io.moquette.spi.impl.security.PermitAllAuthorizator;
|
||||||
import io.moquette.spi.impl.subscriptions.Subscription;
|
import io.moquette.spi.impl.subscriptions.Subscription;
|
||||||
import io.moquette.spi.impl.subscriptions.SubscriptionsStore;
|
import io.moquette.spi.impl.subscriptions.SubscriptionsStore;
|
||||||
@@ -378,7 +375,7 @@ public class ProtocolProcessorTest {
|
|||||||
m_processor.processConnect(m_channel, connectMessage);
|
m_processor.processConnect(m_channel, connectMessage);
|
||||||
|
|
||||||
//Verify no messages are still stored
|
//Verify no messages are still stored
|
||||||
Collection<String> guids = m_sessionStore.enqueued(FAKE_PUBLISHER_ID);
|
Collection<MessageGUID> guids = m_sessionStore.enqueued(FAKE_PUBLISHER_ID);
|
||||||
assertTrue(m_messagesStore.listMessagesInSession(guids).isEmpty());
|
assertTrue(m_messagesStore.listMessagesInSession(guids).isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import io.moquette.spi.IMessagesStore;
|
|||||||
import io.moquette.spi.ISessionsStore;
|
import io.moquette.spi.ISessionsStore;
|
||||||
import io.moquette.spi.ISessionsStore.ClientTopicCouple;
|
import io.moquette.spi.ISessionsStore.ClientTopicCouple;
|
||||||
import io.moquette.parser.proto.messages.AbstractMessage;
|
import io.moquette.parser.proto.messages.AbstractMessage;
|
||||||
|
import io.moquette.spi.MessageGUID;
|
||||||
import io.moquette.spi.impl.subscriptions.Subscription;
|
import io.moquette.spi.impl.subscriptions.Subscription;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -108,7 +109,7 @@ public class MapDBPersistentStoreTest {
|
|||||||
//request a first ID
|
//request a first ID
|
||||||
|
|
||||||
int packetId = m_sessionsStore.nextPacketID("CLIENT");
|
int packetId = m_sessionsStore.nextPacketID("CLIENT");
|
||||||
m_sessionsStore.inFlight("CLIENT", packetId, "ABCDE"); //simulate an inflight
|
m_sessionsStore.inFlight("CLIENT", packetId, new MessageGUID("ABCDE")); //simulate an inflight
|
||||||
assertEquals(1, packetId);
|
assertEquals(1, packetId);
|
||||||
|
|
||||||
//release the ID
|
//release the ID
|
||||||
@@ -137,7 +138,7 @@ public class MapDBPersistentStoreTest {
|
|||||||
publishToStore.setClientID(TEST_CLIENT);
|
publishToStore.setClientID(TEST_CLIENT);
|
||||||
publishToStore.setMessageID(1);
|
publishToStore.setMessageID(1);
|
||||||
publishToStore.setRetained(false);
|
publishToStore.setRetained(false);
|
||||||
String guid = m_messagesStore.storePublishForFuture(publishToStore);
|
MessageGUID guid = m_messagesStore.storePublishForFuture(publishToStore);
|
||||||
|
|
||||||
//Exercise
|
//Exercise
|
||||||
m_messagesStore.dropMessagesInSession("TestClient");
|
m_messagesStore.dropMessagesInSession("TestClient");
|
||||||
@@ -155,7 +156,7 @@ public class MapDBPersistentStoreTest {
|
|||||||
publishToStore.setClientID(TEST_CLIENT);
|
publishToStore.setClientID(TEST_CLIENT);
|
||||||
publishToStore.setMessageID(1);
|
publishToStore.setMessageID(1);
|
||||||
publishToStore.setRetained(true);
|
publishToStore.setRetained(true);
|
||||||
String guid = m_messagesStore.storePublishForFuture(publishToStore);
|
MessageGUID guid = m_messagesStore.storePublishForFuture(publishToStore);
|
||||||
|
|
||||||
//Exercise
|
//Exercise
|
||||||
m_messagesStore.dropMessagesInSession("TestClient");
|
m_messagesStore.dropMessagesInSession("TestClient");
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import io.moquette.spi.ClientSession;
|
|||||||
import io.moquette.spi.IMessagesStore;
|
import io.moquette.spi.IMessagesStore;
|
||||||
import io.moquette.spi.IMessagesStore.StoredMessage;
|
import io.moquette.spi.IMessagesStore.StoredMessage;
|
||||||
import io.moquette.spi.ISessionsStore;
|
import io.moquette.spi.ISessionsStore;
|
||||||
|
import io.moquette.spi.MessageGUID;
|
||||||
import io.moquette.spi.impl.Utils;
|
import io.moquette.spi.impl.Utils;
|
||||||
import io.moquette.spi.impl.subscriptions.Subscription;
|
import io.moquette.spi.impl.subscriptions.Subscription;
|
||||||
|
|
||||||
@@ -39,17 +40,17 @@ public class MemorySessionStore implements ISessionsStore {
|
|||||||
private Map<String, MapDBPersistentStore.PersistentSession> m_persistentSessions = new HashMap<>();
|
private Map<String, MapDBPersistentStore.PersistentSession> m_persistentSessions = new HashMap<>();
|
||||||
|
|
||||||
//maps clientID->[MessageId -> guid]
|
//maps clientID->[MessageId -> guid]
|
||||||
private Map<String, Map<Integer, String>> m_inflightStore = new HashMap<>();
|
private Map<String, Map<Integer, MessageGUID>> m_inflightStore = new HashMap<>();
|
||||||
// private Map<String, Set<Integer>> m_inflightIDs = new HashMap<>();
|
// private Map<String, Set<Integer>> m_inflightIDs = new HashMap<>();
|
||||||
//maps clientID->[guid*]
|
//maps clientID->[guid*]
|
||||||
private Map<String, Set<String>> m_enqueuedStore = new HashMap<>();
|
private Map<String, Set<MessageGUID>> m_enqueuedStore = new HashMap<>();
|
||||||
//maps clientID->[MessageId -> guid]
|
//maps clientID->[MessageId -> guid]
|
||||||
private Map<String, Map<Integer, String>> m_secondPhaseStore = new HashMap<>();
|
private Map<String, Map<Integer, MessageGUID>> m_secondPhaseStore = new HashMap<>();
|
||||||
|
|
||||||
private Map<String, Map<Integer, String>> m_messageToGuids;
|
private Map<String, Map<Integer, MessageGUID>> m_messageToGuids;
|
||||||
private final IMessagesStore m_messagesStore;
|
private final IMessagesStore m_messagesStore;
|
||||||
|
|
||||||
public MemorySessionStore(IMessagesStore messagesStore, Map<String, Map<Integer, String>> messageToGuids) {
|
public MemorySessionStore(IMessagesStore messagesStore, Map<String, Map<Integer, MessageGUID>> messageToGuids) {
|
||||||
m_messageToGuids = messageToGuids;
|
m_messageToGuids = messageToGuids;
|
||||||
this.m_messagesStore = messagesStore;
|
this.m_messagesStore = messagesStore;
|
||||||
}
|
}
|
||||||
@@ -158,7 +159,7 @@ public class MemorySessionStore implements ISessionsStore {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void inFlightAck(String clientID, int messageID) {
|
public void inFlightAck(String clientID, int messageID) {
|
||||||
Map<Integer, String> m = this.m_inflightStore.get(clientID);
|
Map<Integer, MessageGUID> m = this.m_inflightStore.get(clientID);
|
||||||
if (m == null) {
|
if (m == null) {
|
||||||
LOG.error("Can't find the inFlight record for client <{}>", clientID);
|
LOG.error("Can't find the inFlight record for client <{}>", clientID);
|
||||||
return;
|
return;
|
||||||
@@ -167,8 +168,8 @@ public class MemorySessionStore implements ISessionsStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void inFlight(String clientID, int messageID, String guid) {
|
public void inFlight(String clientID, int messageID, MessageGUID guid) {
|
||||||
Map<Integer, String> m = this.m_inflightStore.get(clientID);
|
Map<Integer, MessageGUID> m = this.m_inflightStore.get(clientID);
|
||||||
if (m == null) {
|
if (m == null) {
|
||||||
m = new HashMap<>();
|
m = new HashMap<>();
|
||||||
}
|
}
|
||||||
@@ -181,7 +182,7 @@ public class MemorySessionStore implements ISessionsStore {
|
|||||||
* */
|
* */
|
||||||
@Override
|
@Override
|
||||||
public int nextPacketID(String clientID) {
|
public int nextPacketID(String clientID) {
|
||||||
Map<Integer, String> m = this.m_inflightStore.get(clientID);
|
Map<Integer, MessageGUID> m = this.m_inflightStore.get(clientID);
|
||||||
if (m == null) {
|
if (m == null) {
|
||||||
m = new HashMap<>();
|
m = new HashMap<>();
|
||||||
int nextPacketId = 1;
|
int nextPacketId = 1;
|
||||||
@@ -195,20 +196,20 @@ public class MemorySessionStore implements ISessionsStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bindToDeliver(String guid, String clientID) {
|
public void bindToDeliver(MessageGUID guid, String clientID) {
|
||||||
Set<String> guids = Utils.defaultGet(m_enqueuedStore, clientID, new HashSet<String>());
|
Set<MessageGUID> guids = Utils.defaultGet(m_enqueuedStore, clientID, new HashSet<MessageGUID>());
|
||||||
guids.add(guid);
|
guids.add(guid);
|
||||||
m_enqueuedStore.put(clientID, guids);
|
m_enqueuedStore.put(clientID, guids);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<String> enqueued(String clientID) {
|
public Collection<MessageGUID> enqueued(String clientID) {
|
||||||
return Utils.defaultGet(m_enqueuedStore, clientID, new HashSet<String>());
|
return Utils.defaultGet(m_enqueuedStore, clientID, new HashSet<MessageGUID>());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeEnqueued(String clientID, String guid) {
|
public void removeEnqueued(String clientID, MessageGUID guid) {
|
||||||
Set<String> guids = Utils.defaultGet(m_enqueuedStore, clientID, new HashSet<String>());
|
Set<MessageGUID> guids = Utils.defaultGet(m_enqueuedStore, clientID, new HashSet<MessageGUID>());
|
||||||
guids.remove(guid);
|
guids.remove(guid);
|
||||||
m_enqueuedStore.put(clientID, guids);
|
m_enqueuedStore.put(clientID, guids);
|
||||||
}
|
}
|
||||||
@@ -216,31 +217,31 @@ public class MemorySessionStore implements ISessionsStore {
|
|||||||
@Override
|
@Override
|
||||||
public void moveInFlightToSecondPhaseAckWaiting(String clientID, int messageID) {
|
public void moveInFlightToSecondPhaseAckWaiting(String clientID, int messageID) {
|
||||||
LOG.info("acknowledging inflight clientID <{}> messageID {}", clientID, messageID);
|
LOG.info("acknowledging inflight clientID <{}> messageID {}", clientID, messageID);
|
||||||
Map<Integer, String> m = this.m_inflightStore.get(clientID);
|
Map<Integer, MessageGUID> m = this.m_inflightStore.get(clientID);
|
||||||
if (m == null) {
|
if (m == null) {
|
||||||
LOG.error("Can't find the inFlight record for client <{}>", clientID);
|
LOG.error("Can't find the inFlight record for client <{}>", clientID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String guid = m.remove(messageID);
|
MessageGUID guid = m.remove(messageID);
|
||||||
|
|
||||||
LOG.info("Moving to second phase store");
|
LOG.info("Moving to second phase store");
|
||||||
Map<Integer, String> messageIDs = Utils.defaultGet(m_secondPhaseStore, clientID, new HashMap<Integer, String>());
|
Map<Integer, MessageGUID> messageIDs = Utils.defaultGet(m_secondPhaseStore, clientID, new HashMap<Integer, MessageGUID>());
|
||||||
messageIDs.put(messageID, guid);
|
messageIDs.put(messageID, guid);
|
||||||
m_secondPhaseStore.put(clientID, messageIDs);
|
m_secondPhaseStore.put(clientID, messageIDs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String secondPhaseAcknowledged(String clientID, int messageID) {
|
public MessageGUID secondPhaseAcknowledged(String clientID, int messageID) {
|
||||||
Map<Integer, String> messageIDs = Utils.defaultGet(m_secondPhaseStore, clientID, new HashMap<Integer, String>());
|
Map<Integer, MessageGUID> messageIDs = Utils.defaultGet(m_secondPhaseStore, clientID, new HashMap<Integer, MessageGUID>());
|
||||||
String guid = messageIDs.remove(messageID);
|
MessageGUID guid = messageIDs.remove(messageID);
|
||||||
m_secondPhaseStore.put(clientID, messageIDs);
|
m_secondPhaseStore.put(clientID, messageIDs);
|
||||||
return guid;
|
return guid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String mapToGuid(String clientID, int messageID) {
|
public MessageGUID mapToGuid(String clientID, int messageID) {
|
||||||
HashMap<Integer, String> guids = (HashMap<Integer, String>) Utils.defaultGet(m_messageToGuids,
|
HashMap<Integer, MessageGUID> guids = (HashMap<Integer, MessageGUID>) Utils.defaultGet(m_messageToGuids,
|
||||||
clientID, new HashMap<Integer, String>());
|
clientID, new HashMap<Integer, MessageGUID>());
|
||||||
return guids.get(messageID);
|
return guids.get(messageID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user