/** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ package software.amazon.awssdk.crt.mqtt5.packets; import software.amazon.awssdk.crt.mqtt5.QOS; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; /** * Data model of an MQTT5 PUBLISH packet */ public class PublishPacket { private byte[] payload; private QOS packetQOS; private Boolean retain; private String topic; private PayloadFormatIndicator payloadFormat; private Long messageExpiryIntervalSeconds; private Long topicAlias; private String responseTopic; private byte[] correlationData; private List subscriptionIdentifiers; private String contentType; private List userProperties; /** * Returns the payload of the publish message. * * See MQTT5 Publish Payload * * @return The payload of the publish message. */ public byte[] getPayload() { return this.payload; } /** * Sent publishes - Returns the MQTT quality of service level this message should be delivered with. * * Received publishes - Returns the MQTT quality of service level this message was delivered at. * * See MQTT5 QoS * * @return The MQTT quality of service associated with this PUBLISH packet. */ public QOS getQOS() { return this.packetQOS; } /** * Returns true if this is a retained message, false otherwise. * * Always set on received publishes; on sent publishes, null implies false. * * See MQTT5 Retain * * @return True if this is a retained message, false otherwise. */ public Boolean getRetain() { return this.retain; } /** * Sent publishes - Returns the topic this message should be published to. * * Received publishes - Returns the topic this message was published to. * * See MQTT5 Topic Name * @return The topic associated with this PUBLISH packet. */ public String getTopic() { return this.topic; } /** * Returns the property specifying the format of the payload data. The Mqtt5Client does not enforce or use this * value in a meaningful way. * * See MQTT5 Payload Format Indicator * * @return Property specifying the format of the payload data. */ public PayloadFormatIndicator getPayloadFormat() { return this.payloadFormat; } /** * Sent publishes - Returns the maximum amount of time allowed to elapse for message delivery before the server * should instead delete the message (relative to a recipient). * * Received publishes - Returns the remaining amount of time (from the server's perspective) before the message would * have been deleted relative to the subscribing client. * * If left null, indicates no expiration timeout. * * See MQTT5 Message Expiry Interval * * @return The message expiry interval associated with this PublishPacket. */ public Long getMessageExpiryIntervalSeconds() { return this.messageExpiryIntervalSeconds; } /** * Sent publishes - topic alias to use, if possible, when encoding this packet. Only used if the * client's outbound topic aliasing mode is set to Manual. * * Received publishes - topic alias used by the server when transmitting the publish to the client. * * See MQTT5 Topic Alias * * @return The topic alias associated with this PublishPacket. */ public Long getTopicAlias() { return this.topicAlias; } /** * Returns a opaque topic string intended to assist with request/response implementations. Not internally meaningful to * MQTT5 or this client. * * See MQTT5 Response Topic * * @return Opaque topic string intended to assist with request/response implementations. */ public String getResponseTopic() { return this.responseTopic; } /** * Returns a opaque binary data used to correlate between publish messages, as a potential method for request-response * implementation. Not internally meaningful to MQTT5. * * See MQTT5 Correlation Data * * @return Opaque binary data used to correlate between publish messages. */ public byte[] getCorrelationData() { return this.correlationData; } /** * Returns a property specifying the content type of the payload. Not internally meaningful to MQTT5. * * See MQTT5 Content Type * * @return Property specifying the content type of the payload. */ public String getContentType() { return this.contentType; } /** * Returns a list of MQTT5 user properties included with the packet. * * See MQTT5 User Property * * @return List of MQTT5 user properties included with the packet. */ public List getUserProperties() { return this.userProperties; } /** * Sent publishes - Ignored * * Received publishes - Returns the subscription identifiers of all the subscriptions this message matched. * * See MQTT5 Subscription Identifier * * @return the subscription identifiers of all the subscriptions this message matched. */ public List getSubscriptionIdentifiers() { return this.subscriptionIdentifiers; } /** * Creates a Mqtt5Client options instance * @throws CrtRuntimeException If the system is unable to allocate space for a native MQTT client structure */ private PublishPacket(PublishPacketBuilder builder) { this.payload = builder.payload; this.packetQOS = builder.packetQOS; this.retain = builder.retain; this.topic = builder.topic; this.payloadFormat = builder.payloadFormat; this.messageExpiryIntervalSeconds = builder.messageExpiryIntervalSeconds; this.topicAlias = builder.topicAlias; this.responseTopic = builder.responseTopic; this.correlationData = builder.correlationData; this.contentType = builder.contentType; this.userProperties = builder.userProperties; } private PublishPacket() {} /** * A native, JNI-only helper function for more easily setting the QOS * @param QOSValue A int representing the QoS */ private void nativeSetQOS(int QOSValue) { this.packetQOS = QOS.getEnumValueFromInteger(QOSValue); } /** * A native, JNI-only helper function for more easily setting the payload format indicator * @param payloadFormatIndicator A int representing the payload format */ private void nativeSetPayloadFormatIndicator(int payloadFormatIndicator) { this.payloadFormat = PayloadFormatIndicator.getEnumValueFromInteger(payloadFormatIndicator); } /******************************************************************************* * builder ******************************************************************************/ /** * Optional property describing a PublishPacket payload's format. * * Enum values match MQTT5 spec encoding values. */ public enum PayloadFormatIndicator { /** * The payload is arbitrary binary data */ BYTES(0), /** * The payload is a well-formed utf-8 string value. */ UTF8(1); private int indicator; private PayloadFormatIndicator(int value) { indicator = value; } /** * @return The native enum integer value associated with this Java enum value */ public int getValue() { return indicator; } /** * Creates a Java PayloadFormatIndicator enum value from a native integer value. * * @param value native integer value for PayloadFormatIndicator * @return a new PayloadFormatIndicator value */ public static PayloadFormatIndicator getEnumValueFromInteger(int value) { PayloadFormatIndicator enumValue = enumMapping.get(value); if (enumValue != null) { return enumValue; } throw new RuntimeException("Illegal PayloadFormatIndicator"); } private static Map buildEnumMapping() { return Stream.of(PayloadFormatIndicator.values()) .collect(Collectors.toMap(PayloadFormatIndicator::getValue, Function.identity())); } private static Map enumMapping = buildEnumMapping(); } /** * A class to that allows for the creation of a PublishPacket. Set all of the settings you want in the * packet and then use the build() function to get a PublishPacket populated with the settings * defined in the builder. */ static final public class PublishPacketBuilder { private byte[] payload; private QOS packetQOS; private Boolean retain; private String topic; private PayloadFormatIndicator payloadFormat; private Long messageExpiryIntervalSeconds; private Long topicAlias; private String responseTopic; private byte[] correlationData; private String contentType; private List userProperties; /** * Sets the payload for the publish message. * * See MQTT5 Publish Payload * * @param payload The payload for the publish message. * @return The PublishPacketBuilder after setting the payload. */ public PublishPacketBuilder withPayload(byte[] payload) { this.payload = payload; return this; } /** * Sets the MQTT quality of service level the message should be delivered with. * * See MQTT5 QoS * * @param packetQOS The MQTT quality of service level the message should be delivered with. * @return The PublishPacketBuilder after setting the QOS. */ public PublishPacketBuilder withQOS(QOS packetQOS) { this.packetQOS = packetQOS; return this; } /** * Sets if this should be a retained message. * Null implies false. * * See MQTT5 Retain * * @param retain if this is a retained message. * @return The PublishPacketBuilder after setting the retain setting. */ public PublishPacketBuilder withRetain(Boolean retain) { this.retain = retain; return this; } /** * Sets the topic this message should be published to. * * See MQTT5 Topic Name * * @param topic The topic this message should be published to. * @return The PublishPacketBuilder after setting the topic. */ public PublishPacketBuilder withTopic(String topic) { this.topic = topic; return this; } /** * Sets the property specifying the format of the payload data. The Mqtt5Client does not enforce or use this * value in a meaningful way. * * See MQTT5 Payload Format Indicator * * @param payloadFormat Property specifying the format of the payload data * @return The PublishPacketBuilder after setting the payload format. */ public PublishPacketBuilder withPayloadFormat(PayloadFormatIndicator payloadFormat) { this.payloadFormat = payloadFormat; return this; } /** * Sets the maximum amount of time allowed to elapse for message delivery before the server * should instead delete the message (relative to a recipient). * * If left null, indicates no expiration timeout. * * See MQTT5 Message Expiry Interval * * @param messageExpiryIntervalSeconds The maximum amount of time allowed to elapse for message delivery before the server * should instead delete the message (relative to a recipient). * @return The PublishPacketBuilder after setting the message expiry interval. */ public PublishPacketBuilder withMessageExpiryIntervalSeconds(Long messageExpiryIntervalSeconds) { this.messageExpiryIntervalSeconds = messageExpiryIntervalSeconds; return this; } /** * Sets the topic alias to use when sending this publish. Will only be used if the outbound topic aliasing * behavior has been set to Manual. * * See MQTT5 Topic Alias * * @param topicAlias alias value to use. Must be greater than 0 and less than 65536. * * @return The PublishPacketBuilder after setting the topic alias. */ public PublishPacketBuilder withTopicAlias(long topicAlias) { this.topicAlias = topicAlias; return this; } /** * Sets the opaque topic string intended to assist with request/response implementations. Not internally meaningful to * MQTT5 or this client. * * See MQTT5 Response Topic * @param responseTopic Topic string intended to assist with request/response implementations * @return The PublishPacketBuilder after setting the response topic. */ public PublishPacketBuilder withResponseTopic(String responseTopic) { this.responseTopic = responseTopic; return this; } /** * Sets the opaque binary data used to correlate between publish messages, as a potential method for request-response * implementation. Not internally meaningful to MQTT5. * * See MQTT5 Correlation Data * * @param correlationData Opaque binary data used to correlate between publish messages * @return The PublishPacketBuilder after setting the correlation data. */ public PublishPacketBuilder withCorrelationData(byte[] correlationData) { this.correlationData = correlationData; return this; } /** * Sets the property specifying the content type of the payload. Not internally meaningful to MQTT5. * * See MQTT5 Content Type * * @param contentType Property specifying the content type of the payload * @return The PublishPacketBuilder after setting the content type. */ public PublishPacketBuilder withContentType(String contentType) { this.contentType = contentType; return this; } /** * Sets the list of MQTT5 user properties included with the packet. * * See MQTT5 User Property * * @param userProperties List of MQTT5 user properties included with the packet. * @return The PublishPacketBuilder after setting the user properties. */ public PublishPacketBuilder withUserProperties(List userProperties) { this.userProperties = userProperties; return this; } /** * Creates a new PublishPacketBuilder so a PublishPacket can be created. */ public PublishPacketBuilder() {} /** * Creates a new PublishPacket using the settings set in the builder. * * @return The PublishPacket created from the builder */ public PublishPacket build() { return new PublishPacket(this); } } }