protected void directSend( ClientSession clientsession, String topic, AbstractMessage.QOSType qos, ByteBuffer message, boolean retained, Integer messageID) { String clientId = clientsession.clientID; LOG.debug( "directSend invoked clientId <{}> on topic <{}> QoS {} retained {} messageID {}", clientId, topic, qos, retained, messageID); PublishMessage pubMessage = new PublishMessage(); pubMessage.setRetainFlag(retained); pubMessage.setTopicName(topic); pubMessage.setQos(qos); pubMessage.setPayload(message); LOG.info("send publish message to <{}> on topic <{}>", clientId, topic); if (LOG.isDebugEnabled()) { LOG.debug("content <{}>", DebugUtils.payload2Str(message)); } // set the PacketIdentifier only for QoS > 0 if (pubMessage.getQos() != AbstractMessage.QOSType.MOST_ONE) { pubMessage.setMessageID(messageID); } else { if (messageID != null) { throw new RuntimeException( "Internal bad error, trying to forwardPublish a QoS 0 message with PacketIdentifier: " + messageID); } } if (m_clientIDs == null) { throw new RuntimeException( "Internal bad error, found m_clientIDs to null while it should be initialized, somewhere it's overwritten!!"); } LOG.debug("clientIDs are {}", m_clientIDs); if (m_clientIDs.get(clientId) == null) { // TODO while we were publishing to the target client, that client disconnected, // could happen is not an error HANDLE IT throw new RuntimeException( String.format( "Can't find a ConnectionDescriptor for client <%s> in cache <%s>", clientId, m_clientIDs)); } ServerChannel session = m_clientIDs.get(clientId).session; LOG.debug("Session for clientId {} is {}", clientId, session); String user = (String) session.getAttribute(NettyChannel.ATTR_KEY_USERNAME); if (!m_authorizator.canRead(topic, user, clientId)) { LOG.debug("topic {} doesn't have read credentials", topic); return; } session.write(pubMessage); }
public void processPublish(ServerChannel session, PublishMessage msg) { LOG.trace("PUB --PUBLISH--> SRV executePublish invoked with {}", msg); String clientID = (String) session.getAttribute(NettyChannel.ATTR_KEY_CLIENTID); 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)) { LOG.debug("topic {} doesn't have write credentials", topic); return; } final AbstractMessage.QOSType qos = msg.getQos(); final Integer messageID = msg.getMessageID(); LOG.info("PUBLISH from clientID <{}> on topic <{}> with QoS {}", clientID, topic, qos); String guid = null; IMessagesStore.StoredMessage toStoreMsg = asStoredMessage(msg); toStoreMsg.setClientID(clientID); if (qos == AbstractMessage.QOSType.MOST_ONE) { // QoS0 route2Subscribers(toStoreMsg); } else if (qos == AbstractMessage.QOSType.LEAST_ONE) { // QoS1 route2Subscribers(toStoreMsg); sendPubAck(clientID, messageID); LOG.debug("replying with PubAck to MSG ID {}", messageID); } 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 // NB publish to subscribers for QoS 2 happen upon PUBREL from publisher } 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); } } } m_interceptor.notifyTopicPublished(msg, clientID); }