Example usage for io.netty.handler.codec.mqtt MqttQoS EXACTLY_ONCE

List of usage examples for io.netty.handler.codec.mqtt MqttQoS EXACTLY_ONCE

Introduction

In this page you can find the example usage for io.netty.handler.codec.mqtt MqttQoS EXACTLY_ONCE.

Prototype

MqttQoS EXACTLY_ONCE

To view the source code for io.netty.handler.codec.mqtt MqttQoS EXACTLY_ONCE.

Click Source Link

Usage

From source file:com.caricah.iotracah.core.handlers.PublishInHandler.java

License:Apache License

/**
 * A PUBLISH Control Packet is sent from a Client to a Server or from Server to a Client
 * to transport an Application Message.//from  w  w  w  .jav  a2 s .c om
 *
 * @throws RetriableException
 * @throws UnRetriableException
 */
@Override
public void handle(PublishMessage publishMessage) throws RetriableException, UnRetriableException {

    log.debug(" handle : client attempting to publish a message.");

    /**
     * During an attempt to publish a message.
     *
     * All Topic Names and Topic Filters MUST be at least one character long [MQTT-4.7.3-1]
     *
     * The wildcard characters can be used in Topic Filters,
     * but MUST NOT be used within a Topic Name [MQTT-4.7.1-1].
     *
     * Topic Names and Topic Filters MUST NOT include the null character (Unicode U+0000) [Unicode] [MQTT-4.7.3-2]
     *
     * Topic Names and Topic Filters are UTF-8 encoded strings, they MUST NOT encode to more than 65535 bytes [MQTT-4.7.3-3]. See Section 1.5.3
     *
     */
    String topic = publishMessage.getTopic();
    if (null == topic || topic.isEmpty() || topic.contains(Constant.MULTI_LEVEL_WILDCARD)
            || topic.contains(Constant.SINGLE_LEVEL_WILDCARD) || topic.contains(Constant.SYS_PREFIX)) {
        log.info(" handle : Invalid topic " + publishMessage.getTopic());
        throw new ShutdownException(" Invalid topic name");
    }

    /**
     * Before publishing we should get the current session and validate it.
     */
    Observable<IOTClient> permissionObservable = checkPermission(publishMessage.getSessionId(),
            publishMessage.getAuthKey(), AuthorityRole.PUBLISH, topic);

    permissionObservable.subscribe((iotSession) -> {

        try {

            publishMessage.setPartitionId(iotSession.getPartitionId());
            publishMessage.setClientId(iotSession.getSessionId());
            publishMessage.setId(-1);

            /**
             * Message processing is based on 4.3 Quality of Service levels and protocol flows
             */

            /**
             *  4.3.1 QoS 0: At most once delivery
             *  Accepts ownership of the message when it receives the PUBLISH packet.
             */
            if (MqttQoS.AT_MOST_ONCE.value() == publishMessage.getQos()) {

                getMessenger().publish(iotSession.getPartitionId(), publishMessage);
            }

            /**
             * 4.3.2 QoS 1: At least once delivery
             *
             * MUST respond with a PUBACK Packet containing the Packet Identifier from the incoming PUBLISH Packet, having accepted ownership of the Application Message
             * After it has sent a PUBACK Packet the Receiver MUST treat any incoming PUBLISH packet that contains the same Packet Identifier as being a new publication, irrespective of the setting of its DUP flag.
             */
            if (MqttQoS.AT_LEAST_ONCE.value() == publishMessage.getQos()) {

                getMessenger().publish(iotSession.getPartitionId(), publishMessage);

                //We need to generate a puback message to close this conversation.

                AcknowledgeMessage acknowledgeMessage = AcknowledgeMessage.from(publishMessage.getMessageId());
                acknowledgeMessage.copyTransmissionData(publishMessage);

                pushToServer(acknowledgeMessage);

            }

            /**
             * 4.3.3 QoS 2: Exactly once delivery
             *
             * MUST respond with a PUBREC containing the Packet Identifier from the incoming PUBLISH Packet, having accepted ownership of the Application Message.
             * Until it has received the corresponding PUBREL packet, the Receiver MUST acknowledge any subsequent PUBLISH packet with the same Packet Identifier by sending a PUBREC.
             * It MUST NOT cause duplicate messages to be delivered to any onward recipients in this case.
             *
             */

            if (MqttQoS.EXACTLY_ONCE.value() == publishMessage.getQos()) {

                queueQos2Message(publishMessage);
            }

        } catch (UnRetriableException | RetriableException e) {
            disconnectDueToError(e, publishMessage);
        }

    }, throwable -> disconnectDueToError(throwable, publishMessage)

    );

}

From source file:com.caricah.iotracah.core.handlers.PublishInHandler.java

License:Apache License

private void queueQos2Message(PublishMessage message) throws UnRetriableException {
    if (MqttQoS.EXACTLY_ONCE.value() == message.getQos()) {
        //This message needs to be retained
        // while handshake is completed before being released.

        message.setIsRelease(false);//from   w  ww  .ja v  a2s . co m
        Observable<Map.Entry<Long, IotMessageKey>> messageIdObservable = getDatastore().saveMessage(message);

        messageIdObservable.subscribe(messageIdentity -> {

            //We need to push out a PUBREC

            PublishReceivedMessage publishReceivedMessage = PublishReceivedMessage
                    .from(messageIdentity.getValue().getMessageId());
            publishReceivedMessage.copyTransmissionData(message);
            pushToServer(publishReceivedMessage);

        });

    } else

        throw new UnRetriableException("Only qos 2 messages should be Queued for handshake to occur.");
}

From source file:com.caricah.iotracah.core.worker.state.SessionResetManager.java

License:Apache License

public void process(IOTClient iotClient) {

    log.debug(" process : Resetting a session for client {} ", iotClient);

    Observable<PublishMessage> publishMessageObservable = getDatastore().getMessages(iotClient);

    publishMessageObservable.subscribe(publishMessage -> {

        publishMessage = iotClient.copyTransmissionData(publishMessage);
        //Update current session id for message.

        if (publishMessage.getIsInbound()) {

            //We need to generate a PUBREC message to acknowledge message received.
            if (publishMessage.getQos() == MqttQoS.EXACTLY_ONCE.value()) {

                PublishReceivedMessage publishReceivedMessage = PublishReceivedMessage
                        .from(publishMessage.getMessageId());
                publishReceivedMessage = iotClient.copyTransmissionData(publishReceivedMessage);
                getWorker().pushToServer(publishReceivedMessage);

            }/*w  ww. j ava  2 s  .co  m*/

        } else {

            if (publishMessage.getQos() == MqttQoS.EXACTLY_ONCE.value() && publishMessage.getIsRelease()) {

                //We need to generate a PUBREL message to allow transmission of qos 2 message.
                ReleaseMessage releaseMessage = ReleaseMessage.from(publishMessage.getMessageId(), true);
                releaseMessage = iotClient.copyTransmissionData(releaseMessage);
                getWorker().pushToServer(releaseMessage);

            } else {

                //This message should be released to the client

                try {
                    getWorker().getHandler(PublishOutHandler.class).handle(publishMessage);
                } catch (RetriableException | UnRetriableException e) {
                    log.error(" process : problems releasing stored messages", e);
                }

            }
        }

    });

}

From source file:examples.VertxMqttClientExamples.java

License:Apache License

/**
 * Example for publishCompletionHandler method demonstration
 *
 * @param client//from   w w  w .ja  v a 2 s.  co m
 */
public void example5(MqttClient client) {
    client.publishCompletionHandler(id -> {
        System.out.println("Id of just received PUBACK or PUBCOMP packet is " + id);
    })
            // The line of code below will trigger publishCompletionHandler (QoS 2)
            .publish("hello", Buffer.buffer("hello"), MqttQoS.EXACTLY_ONCE, false, false)
            // The line of code below will trigger publishCompletionHandler (QoS is 1)
            .publish("hello", Buffer.buffer("hello"), MqttQoS.AT_LEAST_ONCE, false, false)
            // The line of code below does not trigger because QoS value is 0
            .publish("hello", Buffer.buffer("hello"), MqttQoS.AT_LEAST_ONCE, false, false);

}

From source file:examples.VertxMqttServerExamples.java

License:Apache License

/**
 * Example for handling client published message
 * @param endpoint//from w w w . j  a  v  a  2s  . co  m
 */
public void example6(MqttEndpoint endpoint) {

    // handling incoming published messages
    endpoint.publishHandler(message -> {

        System.out.println("Just received message [" + message.payload().toString(Charset.defaultCharset())
                + "] with QoS [" + message.qosLevel() + "]");

        if (message.qosLevel() == MqttQoS.AT_LEAST_ONCE) {
            endpoint.publishAcknowledge(message.messageId());
        } else if (message.qosLevel() == MqttQoS.EXACTLY_ONCE) {
            endpoint.publishRelease(message.messageId());
        }

    }).publishReleaseHandler(messageId -> {

        endpoint.publishComplete(messageId);
    });
}

From source file:examples.VertxMqttServerExamples.java

License:Apache License

/**
 * Example for handling publish message to the client
 * @param endpoint/*from w  w  w. j a  v a 2  s  .  c o  m*/
 */
public void example7(MqttEndpoint endpoint) {

    // just as example, publish a message with QoS level 2
    endpoint.publish("my_topic", Buffer.buffer("Hello from the Vert.x MQTT server"), MqttQoS.EXACTLY_ONCE,
            false, false);

    // specifing handlers for handling QoS 1 and 2
    endpoint.publishAcknowledgeHandler(messageId -> {

        System.out.println("Received ack for message = " + messageId);

    }).publishReceivedHandler(messageId -> {

        endpoint.publishRelease(messageId);

    }).publishCompletionHandler(messageId -> {

        System.out.println("Received ack for message = " + messageId);
    });
}

From source file:io.crate.mqtt.protocol.MqttQualityOfServiceTest.java

@Test
public void testProcessQoS2() throws Exception {
    expectedException.expect(UnsupportedOperationException.class);
    expectedException.expectMessage("QoS 2 (EXACTLY_ONCE) is not supported.");
    MqttPublishMessage message = messageWithQoS(MqttQoS.EXACTLY_ONCE);
    processor.handlePublish(ch, message);
}

From source file:io.moquette.persistence.AbstractStoreTest.java

License:Open Source License

@Before
public void setup() {
    publishToStore = new IMessagesStore.StoredMessage("Hello".getBytes(), MqttQoS.EXACTLY_ONCE, "id1/topic");
    publishToStore.setClientID(TEST_CLIENT);
    publishToStore.setRetained(false);/*w ww  .j  a  va 2  s  . c  om*/
}

From source file:io.moquette.persistence.AbstractStoreTest.java

License:Open Source License

@Test
public void overridingSubscriptions() {
    ClientSession session1 = sessionsStore.createNewSession("SESSION_ID_1", true, 0);

    // Subscribe on /topic with QOSType.MOST_ONE
    Subscription oldSubscription = new Subscription(session1.clientID, new Topic("/topic"),
            MqttQoS.AT_MOST_ONCE);//ww w  . ja  v  a2 s  .co  m
    session1.subscribe(oldSubscription);

    // Subscribe on /topic again that overrides the previous subscription.
    Subscription overridingSubscription = new Subscription(session1.clientID, new Topic("/topic"),
            MqttQoS.EXACTLY_ONCE);
    session1.subscribe(overridingSubscription);

    // Verify
    List<ClientTopicCouple> subscriptions = sessionsStore.subscriptionStore().listAllSubscriptions();
    assertThat(subscriptions).hasSize(1);
    Subscription sub = sessionsStore.subscriptionStore().getSubscription(subscriptions.get(0));
    assertThat(sub.getRequestedQos()).isEqualTo(overridingSubscription.getRequestedQos());
}

From source file:io.moquette.persistence.AbstractStoreTest.java

License:Open Source License

@Test
public void testNextPacketID() {
    sessionsStore.createNewSession("CLIENT", true, 0);
    // request a first ID

    IMessagesStore.StoredMessage publishToStore = new IMessagesStore.StoredMessage("Hello".getBytes(),
            MqttQoS.EXACTLY_ONCE, "/topic");
    publishToStore.setClientID("CLIENT");
    publishToStore.setRetained(false);// www . j  a  v  a2s  . c  o  m

    int packetId = sessionsStore.nextPacketID("CLIENT");
    sessionsStore.inFlight("CLIENT", packetId, publishToStore); //simulate an inflight
    assertThat(packetId).isEqualTo(1);

    // release the ID
    sessionsStore.inFlightAck("CLIENT", packetId);

    // request a second packetID, counter restarts from 0
    packetId = sessionsStore.nextPacketID("CLIENT");
    assertThat(packetId).isEqualTo(1);
}