Added internal publish once the broker is embedded in hosting applications

This commit is contained in:
andsel
2015-12-08 18:12:00 +01:00
parent 6805cf89ee
commit 16a5556fa3
5 changed files with 374 additions and 2 deletions
@@ -17,6 +17,7 @@ package io.moquette.server;
import io.moquette.BrokerConstants;
import io.moquette.interception.InterceptHandler;
import io.moquette.proto.messages.PublishMessage;
import io.moquette.server.config.MemoryConfig;
import io.moquette.spi.impl.SimpleMessaging;
import io.moquette.server.config.FilesystemConfig;
@@ -26,6 +27,7 @@ import io.moquette.spi.impl.ProtocolProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
@@ -42,6 +44,10 @@ public class Server {
private ServerAcceptor m_acceptor;
private volatile boolean m_initialized;
private ProtocolProcessor m_processor;
public static void main(String[] args) throws IOException {
final Server server = new Server();
server.startServer();
@@ -111,12 +117,29 @@ public class Server {
m_acceptor = new NettyAcceptor();
m_acceptor.initialize(processor, config);
m_processor = processor;
m_initialized = true;
}
/**
* Use the broker to publish a message. It's intended for embedding applications.
* It can be used only after the server is correctly started with startServer.
*
* @param msg the message to forward.
* @throws IllegalStateException if the server is not yet started
* */
public void internalPublish(PublishMessage msg) {
if (!m_initialized) {
throw new IllegalStateException("Can't publish on a server is not yet started");
}
m_processor.internalPublish(msg);
}
public void stopServer() {
LOG.info("Server stopping...");
m_acceptor.close();
SimpleMessaging.getInstance().shutdown();
m_initialized = false;
LOG.info("Server stopped");
}
}
@@ -303,7 +303,7 @@ public class ProtocolProcessor {
route2Subscribers(toStoreMsg);
sendPubAck(clientID, messageID);
LOG.debug("replying with PubAck to MSG ID {}", messageID);
} else if (qos == AbstractMessage.QOSType.EXACTLY_ONCE) { //QoS2
} else if (qos == AbstractMessage.QOSType.EXACTLY_ONCE) { //QoS2
guid = m_messagesStore.storePublishForFuture(toStoreMsg);
sendPubRec(clientID, messageID);
//Next the client will send us a pub rel
@@ -328,6 +328,87 @@ public class ProtocolProcessor {
}
m_interceptor.notifyTopicPublished(msg, clientID);
}
/**
* Intended usage is only for embedded versions of the broker, where the hosting application want to use the
* broker to send a publish message.
* Inspired by {@link #processPublish} but with some changes to avoid security check, and the handshake phases
* for Qos1 and Qos2.
* It also doesn't notifyTopicPublished because using internally the owner should already know where
* it's publishing.
* */
// public void internalPublish(PublishMessage msg) {
// final AbstractMessage.QOSType qos = msg.getQos();
// final String topic = msg.getTopicName();
// LOG.info("embedded PUBLISH on topic <{}> with QoS {}", topic, qos);
//
// String guid = null;
// IMessagesStore.StoredMessage toStoreMsg = asStoredMessage(msg);
// toStoreMsg.setClientID("BROKER_SELF");
// toStoreMsg.setMessageID(1);
// if (qos == AbstractMessage.QOSType.MOST_ONE || qos == AbstractMessage.QOSType.LEAST_ONE) { //QoS0, QoS1
// route2Subscribers(toStoreMsg);
// } else if (qos == AbstractMessage.QOSType.EXACTLY_ONCE) { //QoS2
// guid = m_messagesStore.storePublishForFuture(toStoreMsg);
//
// route2Subscribers(toStoreMsg);
//
// if (toStoreMsg.isRetained()) {
// if (!toStoreMsg.getMessage().hasRemaining()) {
// m_messagesStore.cleanRetained(topic);
// } else {
// m_messagesStore.storeRetained(topic, guid);
// }
// }
// return;
// }
//
// if (msg.isRetainFlag()) {
// if (qos == AbstractMessage.QOSType.MOST_ONE) {
// //QoS == 0 && retain => clean old retained
// m_messagesStore.cleanRetained(topic);
// } else {
// if (!msg.getPayload().hasRemaining()) {
// m_messagesStore.cleanRetained(topic);
// } else {
// if (guid == null) {
// //before wasn't stored
// guid = m_messagesStore.storePublishForFuture(toStoreMsg);
// }
// m_messagesStore.storeRetained(topic, guid);
// }
// }
// }
// }
public void internalPublish(PublishMessage msg) {
final AbstractMessage.QOSType qos = msg.getQos();
final String topic = msg.getTopicName();
LOG.info("embedded PUBLISH on topic <{}> with QoS {}", topic, qos);
String guid = null;
IMessagesStore.StoredMessage toStoreMsg = asStoredMessage(msg);
toStoreMsg.setClientID("BROKER_SELF");
toStoreMsg.setMessageID(1);
if (qos == AbstractMessage.QOSType.EXACTLY_ONCE) { //QoS2
guid = m_messagesStore.storePublishForFuture(toStoreMsg);
}
route2Subscribers(toStoreMsg);
if (!msg.isRetainFlag()) {
return;
}
if (qos == AbstractMessage.QOSType.MOST_ONE || !msg.getPayload().hasRemaining()) {
//QoS == 0 && retain => clean old retained
m_messagesStore.cleanRetained(topic);
return;
}
if (guid == null) {
//before wasn't stored
guid = m_messagesStore.storePublishForFuture(toStoreMsg);
}
m_messagesStore.storeRetained(topic, guid);
}
/**
* Specialized version to publish will testament message.