@Test public void testForceClientDisconnection_issue116() { final MQTTConnection clientXA = connectAs("subscriber"); subscribe(clientXA, NEWS_TOPIC, AT_MOST_ONCE); final MQTTConnection clientXB = connectAs("publisher"); final ByteBuf anyPayload = Unpooled.copiedBuffer("Hello", Charset.defaultCharset()); sut.receivedPublishQos2(clientXB, MqttMessageBuilders.publish() .payload(anyPayload) .qos(MqttQoS.EXACTLY_ONCE) .retained(false) .topicName(NEWS_TOPIC).build(), "username"); final MQTTConnection clientYA = connectAs("subscriber"); subscribe(clientYA, NEWS_TOPIC, AT_MOST_ONCE); final MQTTConnection clientYB = connectAs("publisher"); final ByteBuf anyPayload2 = Unpooled.copiedBuffer("Hello 2", Charset.defaultCharset()); sut.receivedPublishQos2(clientYB, MqttMessageBuilders.publish() .payload(anyPayload2) .qos(MqttQoS.EXACTLY_ONCE) .retained(true) .topicName(NEWS_TOPIC).build(), "username"); // Verify assertFalse("First 'subscriber' channel MUST be closed by the broker", clientXA.channel.isOpen()); ConnectionTestUtils.verifyPublishIsReceived((EmbeddedChannel) clientYA.channel, AT_MOST_ONCE, "Hello 2"); }
@Before public void setUp() { sessionRegistry = initPostOfficeAndSubsystems(); mockAuthenticator = new MockAuthenticator(singleton(FAKE_CLIENT_ID), singletonMap(TEST_USER, TEST_PWD)); connection = createMQTTConnection(ALLOW_ANONYMOUS_AND_ZERO_BYTES_CLID); connectMessage = ConnectionTestUtils.buildConnect(FAKE_CLIENT_ID); }
@Test public void testPublishToMultipleSubscribers() { final Set<String> clientIds = new HashSet<>(Arrays.asList(FAKE_CLIENT_ID, FAKE_CLIENT_ID2)); mockAuthenticator = new MockAuthenticator(clientIds, singletonMap(TEST_USER, TEST_PWD)); EmbeddedChannel channel1 = new EmbeddedChannel(); MQTTConnection connection1 = createMQTTConnection(ALLOW_ANONYMOUS_AND_ZERO_BYTES_CLID, channel1); connection1.processConnect(ConnectionTestUtils.buildConnect(FAKE_CLIENT_ID)); ConnectionTestUtils.assertConnectAccepted(channel1); EmbeddedChannel channel2 = new EmbeddedChannel(); MQTTConnection connection2 = createMQTTConnection(ALLOW_ANONYMOUS_AND_ZERO_BYTES_CLID, channel2); connection2.processConnect(ConnectionTestUtils.buildConnect(FAKE_CLIENT_ID2)); ConnectionTestUtils.assertConnectAccepted(channel2); // subscribe final MqttQoS qos = AT_MOST_ONCE; final String newsTopic = NEWS_TOPIC; subscribe(qos, newsTopic, connection1); subscribe(qos, newsTopic, connection2); // Exercise final ByteBuf payload = Unpooled.copiedBuffer("Hello world!", Charset.defaultCharset()); sut.receivedPublishQos0(new Topic(NEWS_TOPIC), TEST_USER, FAKE_CLIENT_ID, payload, false, MqttMessageBuilders.publish() .payload(payload.retainedDuplicate()) .qos(MqttQoS.AT_MOST_ONCE) .retained(false) .topicName(NEWS_TOPIC).build()); // Verify ConnectionTestUtils.verifyReceivePublish(channel1, NEWS_TOPIC, "Hello world!"); ConnectionTestUtils.verifyReceivePublish(channel2, NEWS_TOPIC, "Hello world!"); }
@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 testPublishWithQoS1() { connection.processConnect(connectMessage); ConnectionTestUtils.assertConnectAccepted(channel); subscribe(connection, NEWS_TOPIC, AT_LEAST_ONCE); // Exercise final ByteBuf anyPayload = Unpooled.copiedBuffer("Any payload", Charset.defaultCharset()); sut.receivedPublishQos1(connection, new Topic(NEWS_TOPIC), TEST_USER, anyPayload, 1, true, MqttMessageBuilders.publish() .payload(Unpooled.copiedBuffer("Any payload", Charset.defaultCharset())) .qos(MqttQoS.AT_LEAST_ONCE) .retained(true) .topicName(NEWS_TOPIC).build()); // Verify ConnectionTestUtils.verifyPublishIsReceived(channel, AT_LEAST_ONCE, "Any payload"); }
private MQTTConnection createMQTTConnection(BrokerConfiguration config) { channel = new EmbeddedChannel(); return createMQTTConnection(config, channel); }
@Test public void cleanRetainedMessageStoreWhenPublishWithRetainedQos0IsReceived() { connection.processConnect(connectMessage); ConnectionTestUtils.assertConnectAccepted(channel); // publish a QoS1 retained message final ByteBuf anyPayload = Unpooled.copiedBuffer("Any payload", Charset.defaultCharset()); final MqttPublishMessage publishMsg = MqttMessageBuilders.publish() .payload(Unpooled.copiedBuffer("Any payload", Charset.defaultCharset())) .qos(MqttQoS.AT_LEAST_ONCE) .retained(true) .topicName(NEWS_TOPIC) .build(); sut.receivedPublishQos1(connection, new Topic(NEWS_TOPIC), TEST_USER, anyPayload, 1, true, publishMsg); assertMessageIsRetained(NEWS_TOPIC, anyPayload); // publish a QoS0 retained message // Exercise final ByteBuf qos0Payload = Unpooled.copiedBuffer("QoS0 payload", Charset.defaultCharset()); sut.receivedPublishQos0(new Topic(NEWS_TOPIC), TEST_USER, connection.getClientId(), qos0Payload, true, MqttMessageBuilders.publish() .payload(qos0Payload) .qos(MqttQoS.AT_MOST_ONCE) .retained(false) .topicName(NEWS_TOPIC).build()); // Verify assertTrue("Retained message for topic /news must be cleared", retainedRepository.isEmpty()); }
@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"); }
@Test public void testPublishWithQoS2() { connection.processConnect(connectMessage); ConnectionTestUtils.assertConnectAccepted(channel); subscribe(connection, NEWS_TOPIC, EXACTLY_ONCE); // Exercise final ByteBuf anyPayload = Unpooled.copiedBuffer("Any payload", Charset.defaultCharset()); sut.receivedPublishQos2(connection, MqttMessageBuilders.publish() .payload(anyPayload) .qos(MqttQoS.EXACTLY_ONCE) .retained(true) .topicName(NEWS_TOPIC).build(), "username"); // Verify ConnectionTestUtils.verifyPublishIsReceived(channel, EXACTLY_ONCE, "Any payload"); }
private MQTTConnection connectAs(String clientId) { EmbeddedChannel channel = new EmbeddedChannel(); MQTTConnection connection = createMQTTConnection(CONFIG, channel); connection.processConnect(ConnectionTestUtils.buildConnect(clientId)); ConnectionTestUtils.assertConnectAccepted(channel); return connection; }
@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 testPublishQoS0ToItself() { connection.processConnect(connectMessage); ConnectionTestUtils.assertConnectAccepted(channel); // subscribe subscribe(AT_MOST_ONCE, NEWS_TOPIC, connection); // Exercise final ByteBuf payload = Unpooled.copiedBuffer("Hello world!", Charset.defaultCharset()); sut.receivedPublishQos0(new Topic(NEWS_TOPIC), TEST_USER, FAKE_CLIENT_ID, payload, false, MqttMessageBuilders.publish() .payload(payload.retainedDuplicate()) .qos(MqttQoS.AT_MOST_ONCE) .retained(false) .topicName(NEWS_TOPIC).build()); // Verify ConnectionTestUtils.verifyReceivePublish(channel, NEWS_TOPIC, "Hello world!"); }