protected void connect(MQTTConnection connection, MqttConnectMessage connectMessage) { connection.processConnect(connectMessage); ConnectionTestUtils.assertConnectAccepted((EmbeddedChannel) connection.channel); }
@Test public void testSubscribe() { connection.processConnect(connectMessage); ConnectionTestUtils.assertConnectAccepted(channel); // Exercise & verify subscribe(channel, NEWS_TOPIC, AT_MOST_ONCE); }
@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); connection.processConnect(connectMessage); ConnectionTestUtils.assertConnectAccepted(channel); }
private MQTTConnection connectNotCleanAs(String clientId) { EmbeddedChannel channel = new EmbeddedChannel(); MQTTConnection connection = createMQTTConnection(CONFIG, channel); connection.processConnect(ConnectionTestUtils.buildConnectNotClean(clientId)); ConnectionTestUtils.assertConnectAccepted(channel); return connection; }
private MQTTConnection connectAs(String clientId) { EmbeddedChannel channel = new EmbeddedChannel(); MQTTConnection connection = createMQTTConnection(CONFIG, channel); connection.processConnect(ConnectionTestUtils.buildConnect(clientId)); ConnectionTestUtils.assertConnectAccepted(channel); return connection; }
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 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"); }
@Test public void testSubscribedToNotAuthorizedTopic() { NettyUtils.userName(channel, FAKE_USER_NAME); IAuthorizatorPolicy prohibitReadOnNewsTopic = mock(IAuthorizatorPolicy.class); when(prohibitReadOnNewsTopic.canRead(eq(new Topic(NEWS_TOPIC)), eq(FAKE_USER_NAME), eq(FAKE_CLIENT_ID))) .thenReturn(false); sut = new PostOffice(subscriptions, new MemoryRetainedRepository(), sessionRegistry, ConnectionTestUtils.NO_OBSERVERS_INTERCEPTOR, new Authorizator(prohibitReadOnNewsTopic)); connection.processConnect(connectMessage); ConnectionTestUtils.assertConnectAccepted(channel); //Exercise MqttSubscribeMessage subscribe = MqttMessageBuilders.subscribe() .addSubscription(AT_MOST_ONCE, NEWS_TOPIC) .messageId(1) .build(); sut.subscribeClientToTopics(subscribe, FAKE_CLIENT_ID, FAKE_USER_NAME, connection); // Verify MqttSubAckMessage subAckMsg = channel.readOutbound(); verifyFailureQos(subAckMsg); }
@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"); }
@Test public void testReceiveRetainedPublishRespectingSubscriptionQoSAndNotPublisher() { // publisher publish a retained message on topic /news connection.processConnect(connectMessage); ConnectionTestUtils.assertConnectAccepted(channel); final ByteBuf payload = Unpooled.copiedBuffer("Hello world!", Charset.defaultCharset()); final MqttPublishMessage retainedPubQoS1Msg = MqttMessageBuilders.publish() .payload(payload.retainedDuplicate()) .qos(MqttQoS.AT_LEAST_ONCE) .topicName(NEWS_TOPIC).build(); sut.receivedPublishQos1(connection, new Topic(NEWS_TOPIC), TEST_USER, payload, 1, true, retainedPubQoS1Msg); // subscriber connects subscribe to topic /news and receive the last retained message EmbeddedChannel subChannel = new EmbeddedChannel(); MQTTConnection subConn = createMQTTConnection(ALLOW_ANONYMOUS_AND_ZERO_BYTES_CLID, subChannel); subConn.processConnect(ConnectionTestUtils.buildConnect(SUBSCRIBER_ID)); ConnectionTestUtils.assertConnectAccepted(subChannel); subscribe(subConn, NEWS_TOPIC, MqttQoS.AT_MOST_ONCE); // Verify publish is received ConnectionTestUtils.verifyReceiveRetainedPublish(subChannel, NEWS_TOPIC, "Hello world!", MqttQoS.AT_MOST_ONCE); }
@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 testDoubleSubscribe() { connection.processConnect(connectMessage); ConnectionTestUtils.assertConnectAccepted(channel); assertEquals("After CONNECT subscription MUST be empty", 0, subscriptions.size()); subscribe(channel, NEWS_TOPIC, AT_MOST_ONCE); assertEquals("After /news subscribe, subscription MUST contain it", 1, subscriptions.size()); //Exercise & verify subscribe(channel, NEWS_TOPIC, AT_MOST_ONCE); }
@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 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!"); }
@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 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); }
@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 testPublishWithEmptyPayloadClearRetainedStore() { connection.processConnect(connectMessage); ConnectionTestUtils.assertConnectAccepted(channel); this.retainedRepository.retain(new Topic(NEWS_TOPIC), MqttMessageBuilders.publish() .payload(ByteBufUtil.writeAscii(UnpooledByteBufAllocator.DEFAULT, "Hello world!")) .qos(AT_LEAST_ONCE) .build()); // Exercise final ByteBuf anyPayload = Unpooled.copiedBuffer("Any payload", Charset.defaultCharset()); sut.receivedPublishQos0(new Topic(NEWS_TOPIC), TEST_USER, FAKE_CLIENT_ID, anyPayload, true, MqttMessageBuilders.publish() .payload(anyPayload) .qos(MqttQoS.AT_MOST_ONCE) .retained(false) .topicName(NEWS_TOPIC).build()); // Verify assertTrue("QoS0 MUST clean retained message for topic", retainedRepository.isEmpty()); }
@Test public void testSubscribeWithBadFormattedTopic() { connection.processConnect(connectMessage); ConnectionTestUtils.assertConnectAccepted(channel); assertEquals("After CONNECT subscription MUST be empty", 0, subscriptions.size()); //Exercise MqttSubscribeMessage subscribe = MqttMessageBuilders.subscribe() .addSubscription(AT_MOST_ONCE, BAD_FORMATTED_TOPIC) .messageId(1) .build(); this.sut.subscribeClientToTopics(subscribe, FAKE_CLIENT_ID, FAKE_USER_NAME, connection); MqttSubAckMessage subAckMsg = channel.readOutbound(); assertEquals("Bad topic CAN'T add any subscription", 0, subscriptions.size()); verifyFailureQos(subAckMsg); }
@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); }