break; case DISCONNECT: processDisconnect(msg); break; case PUBACK:
private void connectPublishDisconnectFromAnotherClient(String firstPayload, String topic) { MQTTConnection anotherConnection = connectNotCleanAs(PUBLISHER_ID); // publish from another channel final ByteBuf anyPayload = Unpooled.copiedBuffer(firstPayload, Charset.defaultCharset()); sut.receivedPublishQos1(anotherConnection, new Topic(topic), TEST_USER, anyPayload, 1, false, MqttMessageBuilders.publish() .payload(Unpooled.copiedBuffer(firstPayload, Charset.defaultCharset())) .qos(MqttQoS.AT_LEAST_ONCE) .retained(false) .topicName(topic).build()); // disconnect the other channel anotherConnection.processDisconnect(null); }
@Test public void testClientSubscribeAfterDisconnected() { subscribe(AT_MOST_ONCE, "foo", connection); connection.processDisconnect(null); internalPublishTo("foo", AT_MOST_ONCE, false); verifyNoPublishIsReceived(channel); }
@Test public void avoidMultipleNotificationsAfterMultipleReconnection_cleanSessionFalseQoS1() { final MqttConnectMessage notCleanConnect = ConnectionTestUtils.buildConnectNotClean(FAKE_CLIENT_ID); connect(connection, notCleanConnect); subscribe(connection, NEWS_TOPIC, AT_LEAST_ONCE); connection.processDisconnect(null); // connect on another channel final String firstPayload = "Hello MQTT 1"; connectPublishDisconnectFromAnotherClient(firstPayload, NEWS_TOPIC); // reconnect FAKE_CLIENT on another channel EmbeddedChannel anotherChannel2 = new EmbeddedChannel(); MQTTConnection anotherConnection2 = createMQTTConnection(CONFIG, anotherChannel2); anotherConnection2.processConnect(notCleanConnect); ConnectionTestUtils.assertConnectAccepted(anotherChannel2); ConnectionTestUtils.verifyPublishIsReceived(anotherChannel2, MqttQoS.AT_LEAST_ONCE, firstPayload); anotherConnection2.processDisconnect(null); final String secondPayload = "Hello MQTT 2"; connectPublishDisconnectFromAnotherClient(secondPayload, NEWS_TOPIC); EmbeddedChannel anotherChannel3 = new EmbeddedChannel(); MQTTConnection anotherConnection3 = createMQTTConnection(CONFIG, anotherChannel3); anotherConnection3.processConnect(notCleanConnect); ConnectionTestUtils.assertConnectAccepted(anotherChannel3); ConnectionTestUtils.verifyPublishIsReceived(anotherChannel3, MqttQoS.AT_LEAST_ONCE, secondPayload); }
/** * subscriber connect and subscribe on "topic" subscriber disconnects publisher connects and * send two message "hello1" "hello2" to "topic" subscriber connects again and receive "hello1" * "hello2" */ @Test public void checkQoS2SubscriberDisconnectReceivePersistedPublishes() { connect(this.connection, FAKE_CLIENT_ID); subscribe(connection, NEWS_TOPIC, EXACTLY_ONCE); connection.processDisconnect(null); final MQTTConnection publisher = connectAs("Publisher"); publishQos2(publisher, NEWS_TOPIC, "Hello world MQTT!!-1"); publishQos2(publisher, NEWS_TOPIC, "Hello world MQTT!!-2"); createMQTTConnection(CONFIG); connect(this.connection, FAKE_CLIENT_ID); ConnectionTestUtils.verifyPublishIsReceived(channel, EXACTLY_ONCE, "Hello world MQTT!!-1"); ConnectionTestUtils.verifyPublishIsReceived(channel, EXACTLY_ONCE, "Hello world MQTT!!-2"); }
connection.processDisconnect(null); subscriberConnection.processDisconnect(null);
@Test public void noPublishToInactiveSession() { // create an inactive session for Subscriber connection.processConnect(ConnectionTestUtils.buildConnectNotClean(SUBSCRIBER_ID)); ConnectionTestUtils.assertConnectAccepted(channel); subscribe(connection, NEWS_TOPIC, AT_LEAST_ONCE); connection.processDisconnect(null); // Exercise EmbeddedChannel pubChannel = new EmbeddedChannel(); MQTTConnection pubConn = createMQTTConnection(ALLOW_ANONYMOUS_AND_ZERO_BYTES_CLID, pubChannel); pubConn.processConnect(ConnectionTestUtils.buildConnect(PUBLISHER_ID)); ConnectionTestUtils.assertConnectAccepted(pubChannel); final ByteBuf anyPayload = Unpooled.copiedBuffer("Any payload", Charset.defaultCharset()); sut.receivedPublishQos1(pubConn, new Topic(NEWS_TOPIC), TEST_USER, anyPayload, 1, true, MqttMessageBuilders.publish() .payload(anyPayload) .qos(MqttQoS.AT_LEAST_ONCE) .retained(true) .topicName(NEWS_TOPIC).build()); verifyNoPublishIsReceived(channel); }
@Test public void checkReplayofStoredPublishResumeAfter_a_disconnect_cleanSessionFalseQoS1() { final MQTTConnection publisher = connectAs("Publisher"); connect(this.connection, FAKE_CLIENT_ID); subscribe(connection, NEWS_TOPIC, AT_LEAST_ONCE); // publish from another channel publishQos1(publisher, NEWS_TOPIC, "Hello world MQTT!!-1", 99); ConnectionTestUtils.verifyPublishIsReceived(channel, AT_LEAST_ONCE, "Hello world MQTT!!-1"); connection.processDisconnect(null); publishQos1(publisher, NEWS_TOPIC, "Hello world MQTT!!-2", 100); publishQos1(publisher, NEWS_TOPIC, "Hello world MQTT!!-3", 101); createMQTTConnection(CONFIG); connect(this.connection, FAKE_CLIENT_ID); ConnectionTestUtils.verifyPublishIsReceived(channel, AT_LEAST_ONCE, "Hello world MQTT!!-2"); ConnectionTestUtils.verifyPublishIsReceived(channel, AT_LEAST_ONCE, "Hello world MQTT!!-3"); }
@Test public void testDontNotifyClientSubscribedToTopicAfterDisconnectedAndReconnectOnNewChannel() { connect(this.connection, FAKE_CLIENT_ID); subscribe(connection, NEWS_TOPIC, AT_MOST_ONCE); // publish on /news final ByteBuf payload = Unpooled.copiedBuffer("Hello world!", Charset.defaultCharset()); sut.receivedPublishQos0(new Topic(NEWS_TOPIC), TEST_USER, TEST_PWD, payload, false, MqttMessageBuilders.publish() .payload(payload.retainedDuplicate()) .qos(MqttQoS.AT_MOST_ONCE) .retained(false) .topicName(NEWS_TOPIC).build()); ConnectionTestUtils.verifyPublishIsReceived(channel, AT_MOST_ONCE, "Hello world!"); unsubscribeAndVerifyAck(NEWS_TOPIC); connection.processDisconnect(null); // connect on another channel EmbeddedChannel anotherChannel = new EmbeddedChannel(); MQTTConnection anotherConnection = createMQTTConnection(CONFIG, anotherChannel); anotherConnection.processConnect(connectMessage); ConnectionTestUtils.assertConnectAccepted(anotherChannel); // publish on /news final ByteBuf payload2 = Unpooled.copiedBuffer("Hello world!", Charset.defaultCharset()); sut.receivedPublishQos0(new Topic(NEWS_TOPIC), TEST_USER, TEST_PWD, payload2, false, MqttMessageBuilders.publish() .payload(payload2) .qos(MqttQoS.AT_MOST_ONCE) .retained(false) .topicName(NEWS_TOPIC).build()); ConnectionTestUtils.verifyNoPublishIsReceived(anotherChannel); }
@Test public void forwardQoS1PublishesWhenNotCleanSessionReconnects() { connection.processConnect(ConnectionTestUtils.buildConnectNotClean(FAKE_CLIENT_ID)); ConnectionTestUtils.assertConnectAccepted(channel); subscribe(connection, NEWS_TOPIC, AT_LEAST_ONCE); connection.processDisconnect(null); // publish a QoS 1 message from another client publish a message on the topic EmbeddedChannel pubChannel = new EmbeddedChannel(); MQTTConnection pubConn = createMQTTConnection(ALLOW_ANONYMOUS_AND_ZERO_BYTES_CLID, pubChannel); pubConn.processConnect(ConnectionTestUtils.buildConnect(PUBLISHER_ID)); ConnectionTestUtils.assertConnectAccepted(pubChannel); final ByteBuf anyPayload = Unpooled.copiedBuffer("Any payload", Charset.defaultCharset()); sut.receivedPublishQos1(pubConn, new Topic(NEWS_TOPIC), TEST_USER, anyPayload, 1, true, MqttMessageBuilders.publish() .payload(anyPayload.retainedDuplicate()) .qos(MqttQoS.AT_LEAST_ONCE) .topicName(NEWS_TOPIC).build()); // simulate a reconnection from the other client connection = createMQTTConnection(ALLOW_ANONYMOUS_AND_ZERO_BYTES_CLID); connectMessage = ConnectionTestUtils.buildConnectNotClean(FAKE_CLIENT_ID); connection.processConnect(connectMessage); ConnectionTestUtils.assertConnectAccepted(channel); // Verify ConnectionTestUtils.verifyPublishIsReceived(channel, AT_LEAST_ONCE, "Any payload"); }
@Test public void testClientSubscribeWithoutCleanSession() { subscribe(AT_MOST_ONCE, "foo", connection); connection.processDisconnect(null); assertEquals(1, subscriptions.size()); MQTTConnection anotherConn = createMQTTConnection(CONFIG); MqttConnectMessage connectMessage = MqttMessageBuilders.connect() .clientId(FAKE_CLIENT_ID) .cleanSession(false) .build(); anotherConn.processConnect(connectMessage); ConnectionTestUtils.assertConnectAccepted((EmbeddedChannel) anotherConn.channel); assertEquals(1, subscriptions.size()); internalPublishTo("foo", MqttQoS.AT_MOST_ONCE, false); ConnectionTestUtils.verifyPublishIsReceived((EmbeddedChannel) anotherConn.channel, AT_MOST_ONCE, PAYLOAD); }
@Test public void testCleanSession_maintainClientSubscriptions() { connection.processConnect(connectMessage); ConnectionTestUtils.assertConnectAccepted(channel); assertEquals("After CONNECT subscription MUST be empty", 0, subscriptions.size()); subscribe(channel, NEWS_TOPIC, AT_MOST_ONCE); assertEquals("Subscribe MUST contain one subscription", 1, subscriptions.size()); connection.processDisconnect(null); assertEquals("Disconnection MUSTN'T clear subscriptions", 1, subscriptions.size()); EmbeddedChannel anotherChannel = new EmbeddedChannel(); MQTTConnection anotherConn = createMQTTConnection(ALLOW_ANONYMOUS_AND_ZERO_BYTES_CLID, anotherChannel); anotherConn.processConnect(ConnectionTestUtils.buildConnect(FAKE_CLIENT_ID)); ConnectionTestUtils.assertConnectAccepted(anotherChannel); assertEquals("After a reconnect, subscription MUST be still present", 1, subscriptions.size()); final ByteBuf payload = Unpooled.copiedBuffer("Hello world!", Charset.defaultCharset()); sut.receivedPublishQos0(new Topic(NEWS_TOPIC), TEST_USER, TEST_PWD, payload, false, MqttMessageBuilders.publish() .payload(payload.retainedDuplicate()) .qos(MqttQoS.AT_MOST_ONCE) .retained(false) .topicName(NEWS_TOPIC).build()); ConnectionTestUtils.verifyPublishIsReceived(anotherChannel, AT_MOST_ONCE, "Hello world!"); }
@Test public void checkReceivePublishedMessage_after_a_reconnect_with_notCleanSession() { // first connect - subscribe -disconnect connection.processConnect(ConnectionTestUtils.buildConnectNotClean(FAKE_CLIENT_ID)); ConnectionTestUtils.assertConnectAccepted(channel); subscribe(connection, NEWS_TOPIC, AT_LEAST_ONCE); connection.processDisconnect(null); // connect - subscribe from another connection but with same ClientID EmbeddedChannel secondChannel = new EmbeddedChannel(); MQTTConnection secondConn = createMQTTConnection(ALLOW_ANONYMOUS_AND_ZERO_BYTES_CLID, secondChannel); secondConn.processConnect(ConnectionTestUtils.buildConnect(FAKE_CLIENT_ID)); ConnectionTestUtils.assertConnectAccepted(secondChannel); subscribe(secondConn, NEWS_TOPIC, AT_LEAST_ONCE); // publish a QoS 1 message another client publish a message on the topic EmbeddedChannel pubChannel = new EmbeddedChannel(); MQTTConnection pubConn = createMQTTConnection(ALLOW_ANONYMOUS_AND_ZERO_BYTES_CLID, pubChannel); pubConn.processConnect(ConnectionTestUtils.buildConnect(PUBLISHER_ID)); ConnectionTestUtils.assertConnectAccepted(pubChannel); final ByteBuf anyPayload = Unpooled.copiedBuffer("Any payload", Charset.defaultCharset()); sut.receivedPublishQos1(pubConn, new Topic(NEWS_TOPIC), TEST_USER, anyPayload, 1, true, MqttMessageBuilders.publish() .payload(anyPayload.retainedDuplicate()) .qos(MqttQoS.AT_LEAST_ONCE) .topicName(NEWS_TOPIC).build()); // Verify that after a reconnection the client receive the message ConnectionTestUtils.verifyPublishIsReceived(secondChannel, AT_LEAST_ONCE, "Any payload"); }
assertEquals("Subscribe MUST contain one subscription", 1, subscriptions.size()); connection.processDisconnect(null); assertEquals("Disconnection MUSTN'T clear subscriptions", 1, subscriptions.size());
@Test public void connectWithCleanSessionUpdateClientSession() { // first connect with clean session true MqttConnectMessage msg = connMsg.clientId(FAKE_CLIENT_ID).cleanSession(true).build(); connection.processConnect(msg); assertEqualsConnAck(CONNECTION_ACCEPTED, channel.readOutbound()); connection.processDisconnect(null); assertFalse(channel.isOpen()); // second connect with clean session false EmbeddedChannel anotherChannel = new EmbeddedChannel(); MQTTConnection anotherConnection = createMQTTConnection(ALLOW_ANONYMOUS_AND_ZEROBYTE_CLIENT_ID, anotherChannel); MqttConnectMessage secondConnMsg = MqttMessageBuilders.connect() .clientId(FAKE_CLIENT_ID) .protocolVersion(MqttVersion.MQTT_3_1) .build(); anotherConnection.processConnect(secondConnMsg); assertEqualsConnAck(CONNECTION_ACCEPTED, anotherChannel.readOutbound()); // Verify client session is clean false Session session = sut.retrieve(FAKE_CLIENT_ID); assertFalse(session.isClean()); } }