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

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

Introduction

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

Prototype

@Override
    public ByteBuf content() 

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 ww  w . j a v  a 2  s  .  c om*/
 * 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);
    }
}