List of usage examples for io.netty.handler.codec.mqtt MqttPublishMessage content
@Override
public ByteBuf content()
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); } }