Example usage for io.netty.handler.codec.mqtt MqttPublishMessage fixedHeader

List of usage examples for io.netty.handler.codec.mqtt MqttPublishMessage fixedHeader

Introduction

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

Prototype

public MqttFixedHeader fixedHeader() 

Source Link

Usage

From source file:io.crate.mqtt.operations.MqttIngestService.java

/**
 * Parse the payload of the provided mqtt message and find which {@link IngestRule}s match the message properties.
 * For every matched rule, execute the insert into the rule's target table.
 * If we encounter exceptions whilst executing the rules we try to send the ackCallback that failure that's not a
 * "row already exists" (because, in case of messages with the isDup flag set to true, we will send the PUBACK reply
 * to the message).//from w ww  .j ava  2  s .c  o  m
 * We do not want to acknowledge the message until all message rules are successfully applied (if
 * the only detected failure(s) is "row already exists", namely {@link VersionConflictEngineException}, we trigger
 * the ackCallback, as for QoS 1 (at least once) we expect message redeliveries)
 */
public void doInsert(String clientId, MqttPublishMessage msg, BiConsumer<Object, Throwable> ackCallback) {
    if (isInitialized == false) {
        throw new IllegalStateException("Service was not initialized");
    }

    Map<String, Object> payload = parsePayloadToMap(msg.content());
    if (payload == null) {
        return;
    }

    Set<Tuple<Predicate<Row>, IngestRule>> predicateAndIngestRules = predicateAndIngestRulesReference.get();
    int packetId = msg.variableHeader().packetId();
    Object[] args = new Object[] { clientId, packetId, msg.variableHeader().topicName(), payload };
    List<Object> argsAsList = Arrays.asList(args);

    boolean messageMatchedRule = false;
    boolean callbackNotified = false;
    Session session = sqlOperations.createSession(Schemas.DOC_SCHEMA_NAME, crateUser, Option.NONE, 1);
    List<CompletableFuture<?>> insertOperationsFuture = new ArrayList<>(predicateAndIngestRules.size());
    for (Tuple<Predicate<Row>, IngestRule> entry : predicateAndIngestRules) {
        if (entry.v1().test(new RowN(args))) {
            messageMatchedRule = true;
            IngestRule ingestRule = entry.v2();

            try {
                session.parse(ingestRule.getName(),
                        "insert into " + TableIdent.fromIndexName(ingestRule.getTargetTable()).fqn()
                                + " (\"client_id\", \"packet_id\", \"topic\", \"ts\", \"payload\") "
                                + "values (?, ?, ?, CURRENT_TIMESTAMP, ?)",
                        FIELD_TYPES);
                session.bind(Session.UNNAMED, ingestRule.getName(), argsAsList, null);
                BaseResultReceiver resultReceiver = new BaseResultReceiver();
                insertOperationsFuture.add(resultReceiver.completionFuture().exceptionally(t -> {
                    if (SQLExceptions.isDocumentAlreadyExistsException(t)) {
                        if (msg.fixedHeader().isDup()) {
                            // we are dealing with QoS1, so redeliveries and duplicate insert exceptions are
                            // normal in case of a duplicate message - indicated by the isDup flag
                            return null;
                        }
                    }

                    Exceptions.rethrowUnchecked(t);
                    return null;
                }));
                session.execute(Session.UNNAMED, 0, resultReceiver);
                session.sync();
            } catch (SQLActionException e) {
                ackCallback.accept(null, e);
                callbackNotified = true;
                break;
            }
        }
    }
    session.close();

    if (callbackNotified == false) {
        CompletableFuture<Void> allResultsComplete = CompletableFuture
                .allOf(insertOperationsFuture.toArray(new CompletableFuture[0]));

        allResultsComplete.whenComplete((r, t) -> {
            if (t != null) {
                // the actual cause is wrapped in a CompletionException by CompletableFuture#allOf
                ackCallback.accept(null, t.getCause());
            } else {
                ackCallback.accept(r, null);
            }
        });
    }

    if (messageMatchedRule == false) {
        LOGGER.warn(
                "Message with client_id {} and packet_id {} did not match any rule. The message will not be "
                        + "acknowledged",
                clientId, packetId);
    }
    if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("Parsed MQTT message into arguments: {}", argsAsList);
    }
}

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

public void handlePublish(Channel channel, MqttPublishMessage msg) {
    final MqttQoS qos = msg.fixedHeader().qosLevel();
    String clientId = NettyUtils.clientID(channel);
    switch (qos) {
    case AT_LEAST_ONCE:
        SendPubAckCallback ackCallback = new SendPubAckCallback(channel, msg.variableHeader().packetId(),
                msg.fixedHeader().isDup());
        ingestService.doInsert(clientId, msg, ackCallback);
        break;/*from   ww w .java  2  s  .co m*/
    default:
        String message = String.format(Locale.ENGLISH, "QoS %s (%s) is not supported.", qos.value(),
                qos.name());
        throw new UnsupportedOperationException(message);
    }
}

From source file:io.moquette.spi.impl.AbstractProtocolProcessorCommonUtils.java

License:Open Source License

protected void verifyPublishIsReceived(EmbeddedChannel channel, String expectedPayload, MqttQoS expectedQoS) {
    final MqttPublishMessage publishReceived = channel.readOutbound();
    String payloadMessage = new String(publishReceived.payload().array(), UTF_8);
    assertEquals("Sent and received payload must be identical", expectedPayload, payloadMessage);
    assertEquals("Expected QoS don't match", expectedQoS, publishReceived.fixedHeader().qosLevel());
}

From source file:io.moquette.spi.impl.InternalRepublisher.java

License:Open Source License

void publishStored(ClientSession clientSession, BlockingQueue<IMessagesStore.StoredMessage> publishedEvents) {
    List<IMessagesStore.StoredMessage> storedPublishes = new ArrayList<>();
    publishedEvents.drainTo(storedPublishes);

    for (IMessagesStore.StoredMessage pubEvt : storedPublishes) {
        // put in flight zone
        LOG.debug("Adding message ot inflight zone. ClientId={}, guid={}, topic={}", clientSession.clientID,
                pubEvt.getGuid(), pubEvt.getTopic());
        int messageId = clientSession.inFlightAckWaiting(pubEvt);
        MqttPublishMessage publishMsg = notRetainedPublish(pubEvt);
        // set the PacketIdentifier only for QoS > 0
        if (publishMsg.fixedHeader().qosLevel() != MqttQoS.AT_MOST_ONCE) {
            publishMsg = notRetainedPublish(pubEvt, messageId);
        }// www. j av a  2s  .c o  m
        this.messageSender.sendPublish(clientSession, publishMsg);
    }
}

From source file:net.anyflow.lannister.message.Message.java

License:Apache License

public static Message newMessage(String clientId, MqttPublishMessage published) {
    return new Message(published.variableHeader().messageId(), published.variableHeader().topicName(), clientId,
            NettyUtil.copy(published.payload()), published.fixedHeader().qosLevel(),
            published.fixedHeader().isRetain());
}

From source file:net.anyflow.lannister.packetreceiver.PublishReceiver.java

License:Apache License

@Override
protected void channelRead0(ChannelHandlerContext ctx, MqttPublishMessage msg) throws Exception {
    logger.debug("packet incoming [message={}]", msg.toString());
    Statistics.SELF.add(Statistics.Criterion.MESSAGES_PUBLISH_RECEIVED, 1);

    Session session = Session.NEXUS.get(ctx.channel().id());
    if (session == null) {
        logger.error("None exist session message [message={}]", msg.toString());

        ctx.channel().disconnect().addListener(ChannelFutureListener.CLOSE).addListener(fs -> // [MQTT-4.8.0-1]
        Plugins.SELF.get(DisconnectEventListener.class).disconnected(new AbnormalDisconnectEventArgs()));
        return;//w ww  .  java  2  s  .c  o m
    }

    session.setLastIncomingTime(new Date());

    if (!TopicMatcher.isValid(msg.variableHeader().topicName(), false)) {
        session.dispose(true);
        return;
    }

    Message message = Message.newMessage(session.clientId(), msg);

    if (!Plugins.SELF.get(PublishEventListener.class).allowPublish(new PublishEventArgs() {
        @Override
        public IMessage message() {
            return message;
        }
    })) {
        session.dispose(true);
        return;
    }

    // TODO What to do when sender re-publish message corrensponds to
    // unacked status?

    // TODO 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.[MQTT-4.3.3-2].

    final Topic topic = Topic.NEXUS.publish(message);

    switch (msg.fixedHeader().qosLevel()) {
    case AT_MOST_ONCE:
        return; // QoS 0 do not send any acknowledge packet [MQTT-3.3.4-1]

    case AT_LEAST_ONCE:
        session.send(MessageFactory.puback(msg.variableHeader().messageId())).addListener(
                f -> topic.removeInboundMessageStatus(session.clientId(), msg.variableHeader().messageId())); // [MQTT-3.3.4-1],[MQTT-2.3.1-6]
        logger.debug("Inbound message status REMOVED [clientId={}, messageId={}]", session.clientId(),
                msg.variableHeader().messageId());
        return;

    case EXACTLY_ONCE:
        session.send(MessageFactory.pubrec(msg.variableHeader().messageId()))
                .addListener(f -> topic.setInboundMessageStatus(session.clientId(),
                        msg.variableHeader().messageId(), InboundMessageStatus.Status.PUBRECED)); // [MQTT-3.3.4-1],[MQTT-2.3.1-6]
        return;

    default:
        session.dispose(true); // [MQTT-3.3.1-4]
        return;
    }
}

From source file:org.apache.activemq.artemis.core.protocol.mqtt.MQTTProtocolHandler.java

License:Apache License

void handlePublish(MqttPublishMessage message) throws Exception {
    session.getMqttPublishManager().handleMessage(message.variableHeader().packetId(),
            message.variableHeader().topicName(), message.fixedHeader().qosLevel().value(), message.payload(),
            message.fixedHeader().isRetain());
}

From source file:org.thingsboard.mqtt.MqttChannelHandler.java

License:Apache License

private void handlePublish(Channel channel, MqttPublishMessage message) {
    switch (message.fixedHeader().qosLevel()) {
    case AT_MOST_ONCE:
        invokeHandlersForIncomingPublish(message);
        break;/*w  w  w .  j a  v  a  2s.  c o  m*/

    case AT_LEAST_ONCE:
        invokeHandlersForIncomingPublish(message);
        if (message.variableHeader().messageId() != -1) {
            MqttFixedHeader fixedHeader = new MqttFixedHeader(MqttMessageType.PUBACK, false,
                    MqttQoS.AT_MOST_ONCE, false, 0);
            MqttMessageIdVariableHeader variableHeader = MqttMessageIdVariableHeader
                    .from(message.variableHeader().messageId());
            channel.writeAndFlush(new MqttPubAckMessage(fixedHeader, variableHeader));
        }
        break;

    case EXACTLY_ONCE:
        if (message.variableHeader().messageId() != -1) {
            MqttFixedHeader fixedHeader = new MqttFixedHeader(MqttMessageType.PUBREC, false,
                    MqttQoS.AT_MOST_ONCE, false, 0);
            MqttMessageIdVariableHeader variableHeader = MqttMessageIdVariableHeader
                    .from(message.variableHeader().messageId());
            MqttMessage pubrecMessage = new MqttMessage(fixedHeader, variableHeader);

            MqttIncomingQos2Publish incomingQos2Publish = new MqttIncomingQos2Publish(message, pubrecMessage);
            this.client.getQos2PendingIncomingPublishes().put(message.variableHeader().messageId(),
                    incomingQos2Publish);
            message.payload().retain();
            incomingQos2Publish.startPubrecRetransmitTimer(this.client.getEventLoop().next(),
                    this.client::sendAndFlushPacket);

            channel.writeAndFlush(pubrecMessage);
        }
        break;
    }
}