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