• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  * SPDX-License-Identifier: Apache-2.0.
4  */
5 package software.amazon.awssdk.crt.mqtt5.packets;
6 
7 import software.amazon.awssdk.crt.mqtt5.QOS;
8 
9 import java.util.List;
10 import java.util.Map;
11 import java.util.function.Function;
12 import java.util.stream.Collectors;
13 import java.util.stream.Stream;
14 
15 /**
16  * Data model of an <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901100">MQTT5 PUBLISH</a> packet
17  */
18 public class PublishPacket {
19 
20     private byte[] payload;
21     private QOS packetQOS;
22     private Boolean retain;
23     private String topic;
24     private PayloadFormatIndicator payloadFormat;
25     private Long messageExpiryIntervalSeconds;
26     private Long topicAlias;
27     private String responseTopic;
28     private byte[] correlationData;
29     private List<Long> subscriptionIdentifiers;
30     private String contentType;
31     private List<UserProperty> userProperties;
32 
33     /**
34      * Returns the payload of the publish message.
35      *
36      * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901119">MQTT5 Publish Payload</a>
37      *
38      * @return The payload of the publish message.
39      */
getPayload()40     public byte[] getPayload() {
41         return this.payload;
42     }
43 
44     /**
45      * Sent publishes - Returns the MQTT quality of service level this message should be delivered with.
46      *
47      * Received publishes - Returns the MQTT quality of service level this message was delivered at.
48      *
49      * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901103">MQTT5 QoS</a>
50      *
51      * @return The MQTT quality of service associated with this PUBLISH packet.
52      */
getQOS()53     public QOS getQOS() {
54         return this.packetQOS;
55     }
56 
57     /**
58      * Returns true if this is a retained message, false otherwise.
59      *
60      * Always set on received publishes; on sent publishes, null implies false.
61      *
62      * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901104">MQTT5 Retain</a>
63      *
64      * @return True if this is a retained message, false otherwise.
65      */
getRetain()66     public Boolean getRetain() {
67         return this.retain;
68     }
69 
70     /**
71      * Sent publishes - Returns the topic this message should be published to.
72      *
73      * Received publishes - Returns the topic this message was published to.
74      *
75      * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901107">MQTT5 Topic Name</a>
76      * @return The topic associated with this PUBLISH packet.
77      */
getTopic()78     public String getTopic() {
79         return this.topic;
80     }
81 
82     /**
83      * Returns the property specifying the format of the payload data. The Mqtt5Client does not enforce or use this
84      * value in a meaningful way.
85      *
86      * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901111">MQTT5 Payload Format Indicator</a>
87      *
88      * @return Property specifying the format of the payload data.
89      */
getPayloadFormat()90     public PayloadFormatIndicator getPayloadFormat() {
91         return this.payloadFormat;
92     }
93 
94     /**
95      * Sent publishes - Returns the maximum amount of time allowed to elapse for message delivery before the server
96      * should instead delete the message (relative to a recipient).
97      *
98      * Received publishes - Returns the remaining amount of time (from the server's perspective) before the message would
99      * have been deleted relative to the subscribing client.
100      *
101      * If left null, indicates no expiration timeout.
102      *
103      * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901112">MQTT5 Message Expiry Interval</a>
104      *
105      * @return The message expiry interval associated with this PublishPacket.
106      */
getMessageExpiryIntervalSeconds()107     public Long getMessageExpiryIntervalSeconds() {
108         return this.messageExpiryIntervalSeconds;
109     }
110 
111     /**
112      * Sent publishes - topic alias to use, if possible, when encoding this packet.  Only used if the
113      * client's outbound topic aliasing mode is set to Manual.
114      *
115      * Received publishes - topic alias used by the server when transmitting the publish to the client.
116      *
117      * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901113">MQTT5 Topic Alias</a>
118      *
119      * @return The topic alias associated with this PublishPacket.
120      */
getTopicAlias()121     public Long getTopicAlias() {
122         return this.topicAlias;
123     }
124 
125     /**
126      * Returns a opaque topic string intended to assist with request/response implementations.  Not internally meaningful to
127      * MQTT5 or this client.
128      *
129      * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901114">MQTT5 Response Topic</a>
130      *
131      * @return Opaque topic string intended to assist with request/response implementations.
132      */
getResponseTopic()133     public String getResponseTopic() {
134         return this.responseTopic;
135     }
136 
137     /**
138      * Returns a opaque binary data used to correlate between publish messages, as a potential method for request-response
139      * implementation.  Not internally meaningful to MQTT5.
140      *
141      * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901115">MQTT5 Correlation Data</a>
142      *
143      * @return Opaque binary data used to correlate between publish messages.
144      */
getCorrelationData()145     public byte[] getCorrelationData() {
146         return this.correlationData;
147     }
148 
149     /**
150      * Returns a property specifying the content type of the payload.  Not internally meaningful to MQTT5.
151      *
152      * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901118">MQTT5 Content Type</a>
153      *
154      * @return Property specifying the content type of the payload.
155      */
getContentType()156     public String getContentType() {
157         return this.contentType;
158     }
159 
160     /**
161      * Returns a list of MQTT5 user properties included with the packet.
162      *
163      * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901116">MQTT5 User Property</a>
164      *
165      * @return List of MQTT5 user properties included with the packet.
166      */
getUserProperties()167     public List<UserProperty> getUserProperties() {
168         return this.userProperties;
169     }
170 
171     /**
172      * Sent publishes - Ignored
173      *
174      * Received publishes - Returns the subscription identifiers of all the subscriptions this message matched.
175      *
176      * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901117">MQTT5 Subscription Identifier</a>
177      *
178      * @return the subscription identifiers of all the subscriptions this message matched.
179      */
getSubscriptionIdentifiers()180     public List<Long> getSubscriptionIdentifiers() {
181         return this.subscriptionIdentifiers;
182     }
183 
184     /**
185      * Creates a Mqtt5Client options instance
186      * @throws CrtRuntimeException If the system is unable to allocate space for a native MQTT client structure
187      */
PublishPacket(PublishPacketBuilder builder)188     private PublishPacket(PublishPacketBuilder builder) {
189         this.payload = builder.payload;
190         this.packetQOS = builder.packetQOS;
191         this.retain = builder.retain;
192         this.topic = builder.topic;
193         this.payloadFormat = builder.payloadFormat;
194         this.messageExpiryIntervalSeconds = builder.messageExpiryIntervalSeconds;
195         this.topicAlias = builder.topicAlias;
196         this.responseTopic = builder.responseTopic;
197         this.correlationData = builder.correlationData;
198         this.contentType = builder.contentType;
199         this.userProperties = builder.userProperties;
200     }
201 
PublishPacket()202     private PublishPacket() {}
203 
204     /**
205      * A native, JNI-only helper function for more easily setting the QOS
206      * @param QOSValue A int representing the QoS
207      */
nativeSetQOS(int QOSValue)208     private void nativeSetQOS(int QOSValue) {
209         this.packetQOS = QOS.getEnumValueFromInteger(QOSValue);
210     }
211 
212     /**
213      * A native, JNI-only helper function for more easily setting the payload format indicator
214      * @param payloadFormatIndicator A int representing the payload format
215      */
nativeSetPayloadFormatIndicator(int payloadFormatIndicator)216     private void nativeSetPayloadFormatIndicator(int payloadFormatIndicator) {
217         this.payloadFormat = PayloadFormatIndicator.getEnumValueFromInteger(payloadFormatIndicator);
218     }
219 
220     /*******************************************************************************
221      * builder
222      ******************************************************************************/
223 
224     /**
225      * Optional property describing a PublishPacket payload's format.
226      *
227      * Enum values match <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901111">MQTT5 spec</a> encoding values.
228      */
229     public enum PayloadFormatIndicator {
230 
231         /**
232          * The payload is arbitrary binary data
233          */
234         BYTES(0),
235 
236         /**
237          * The payload is a well-formed utf-8 string value.
238          */
239         UTF8(1);
240 
241         private int indicator;
242 
PayloadFormatIndicator(int value)243         private PayloadFormatIndicator(int value) {
244             indicator = value;
245         }
246 
247         /**
248          * @return The native enum integer value associated with this Java enum value
249          */
getValue()250         public int getValue() {
251             return indicator;
252         }
253 
254         /**
255          * Creates a Java PayloadFormatIndicator enum value from a native integer value.
256          *
257          * @param value native integer value for PayloadFormatIndicator
258          * @return a new PayloadFormatIndicator value
259          */
getEnumValueFromInteger(int value)260         public static PayloadFormatIndicator getEnumValueFromInteger(int value) {
261             PayloadFormatIndicator enumValue = enumMapping.get(value);
262             if (enumValue != null) {
263                 return enumValue;
264             }
265             throw new RuntimeException("Illegal PayloadFormatIndicator");
266         }
267 
buildEnumMapping()268         private static Map<Integer, PayloadFormatIndicator> buildEnumMapping() {
269             return Stream.of(PayloadFormatIndicator.values())
270                 .collect(Collectors.toMap(PayloadFormatIndicator::getValue, Function.identity()));
271         }
272 
273         private static Map<Integer, PayloadFormatIndicator> enumMapping = buildEnumMapping();
274     }
275 
276     /**
277      * A class to that allows for the creation of a PublishPacket. Set all of the settings you want in the
278      * packet and then use the build() function to get a PublishPacket populated with the settings
279      * defined in the builder.
280      */
281     static final public class PublishPacketBuilder {
282 
283         private byte[] payload;
284         private QOS packetQOS;
285         private Boolean retain;
286         private String topic;
287         private PayloadFormatIndicator payloadFormat;
288         private Long messageExpiryIntervalSeconds;
289         private Long topicAlias;
290         private String responseTopic;
291         private byte[] correlationData;
292         private String contentType;
293         private List<UserProperty> userProperties;
294 
295         /**
296          * Sets the payload for the publish message.
297          *
298          * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901119">MQTT5 Publish Payload</a>
299          *
300          * @param payload The payload for the publish message.
301          * @return The PublishPacketBuilder after setting the payload.
302          */
withPayload(byte[] payload)303         public PublishPacketBuilder withPayload(byte[] payload) {
304             this.payload = payload;
305             return this;
306         }
307 
308         /**
309          * Sets the MQTT quality of service level the message should be delivered with.
310          *
311          * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901103">MQTT5 QoS</a>
312          *
313          * @param packetQOS The MQTT quality of service level the message should be delivered with.
314          * @return The PublishPacketBuilder after setting the QOS.
315          */
withQOS(QOS packetQOS)316         public PublishPacketBuilder withQOS(QOS packetQOS) {
317             this.packetQOS = packetQOS;
318             return this;
319         }
320 
321         /**
322          * Sets if this should be a retained message.
323          * Null implies false.
324          *
325          * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901104">MQTT5 Retain</a>
326          *
327          * @param retain if this is a retained message.
328          * @return The PublishPacketBuilder after setting the retain setting.
329          */
withRetain(Boolean retain)330         public PublishPacketBuilder withRetain(Boolean retain) {
331             this.retain = retain;
332             return this;
333         }
334 
335         /**
336          * Sets the topic this message should be published to.
337          *
338          * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901107">MQTT5 Topic Name</a>
339          *
340          * @param topic The topic this message should be published to.
341          * @return The PublishPacketBuilder after setting the topic.
342          */
withTopic(String topic)343         public PublishPacketBuilder withTopic(String topic) {
344             this.topic = topic;
345             return this;
346         }
347 
348         /**
349          * Sets the property specifying the format of the payload data. The Mqtt5Client does not enforce or use this
350          * value in a meaningful way.
351          *
352          * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901111">MQTT5 Payload Format Indicator</a>
353          *
354          * @param payloadFormat Property specifying the format of the payload data
355          * @return The PublishPacketBuilder after setting the payload format.
356          */
withPayloadFormat(PayloadFormatIndicator payloadFormat)357         public PublishPacketBuilder withPayloadFormat(PayloadFormatIndicator payloadFormat) {
358             this.payloadFormat = payloadFormat;
359             return this;
360         }
361 
362         /**
363          * Sets the maximum amount of time allowed to elapse for message delivery before the server
364          * should instead delete the message (relative to a recipient).
365          *
366          * If left null, indicates no expiration timeout.
367          *
368          * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901112">MQTT5 Message Expiry Interval</a>
369          *
370          * @param messageExpiryIntervalSeconds The maximum amount of time allowed to elapse for message delivery before the server
371          * should instead delete the message (relative to a recipient).
372          * @return The PublishPacketBuilder after setting the message expiry interval.
373          */
withMessageExpiryIntervalSeconds(Long messageExpiryIntervalSeconds)374         public PublishPacketBuilder withMessageExpiryIntervalSeconds(Long messageExpiryIntervalSeconds) {
375             this.messageExpiryIntervalSeconds = messageExpiryIntervalSeconds;
376             return this;
377         }
378 
379         /**
380          * Sets the topic alias to use when sending this publish.  Will only be used if the outbound topic aliasing
381          * behavior has been set to Manual.
382          *
383          * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901113">MQTT5 Topic Alias</a>
384          *
385          * @param topicAlias alias value to use.  Must be greater than 0 and less than 65536.
386          *
387          * @return The PublishPacketBuilder after setting the topic alias.
388          */
withTopicAlias(long topicAlias)389         public PublishPacketBuilder withTopicAlias(long topicAlias) {
390             this.topicAlias = topicAlias;
391             return this;
392         }
393 
394         /**
395          * Sets the opaque topic string intended to assist with request/response implementations.  Not internally meaningful to
396          * MQTT5 or this client.
397          *
398          * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901114">MQTT5 Response Topic</a>
399          * @param responseTopic Topic string intended to assist with request/response implementations
400          * @return The PublishPacketBuilder after setting the response topic.
401          */
withResponseTopic(String responseTopic)402         public PublishPacketBuilder withResponseTopic(String responseTopic) {
403             this.responseTopic = responseTopic;
404             return this;
405         }
406 
407         /**
408          * Sets the opaque binary data used to correlate between publish messages, as a potential method for request-response
409          * implementation.  Not internally meaningful to MQTT5.
410          *
411          * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901115">MQTT5 Correlation Data</a>
412          *
413          * @param correlationData Opaque binary data used to correlate between publish messages
414          * @return The PublishPacketBuilder after setting the correlation data.
415          */
withCorrelationData(byte[] correlationData)416         public PublishPacketBuilder withCorrelationData(byte[] correlationData) {
417             this.correlationData = correlationData;
418             return this;
419         }
420 
421         /**
422          * Sets the property specifying the content type of the payload.  Not internally meaningful to MQTT5.
423          *
424          * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901118">MQTT5 Content Type</a>
425          *
426          * @param contentType Property specifying the content type of the payload
427          * @return The PublishPacketBuilder after setting the content type.
428          */
withContentType(String contentType)429         public PublishPacketBuilder withContentType(String contentType) {
430             this.contentType = contentType;
431             return this;
432         }
433 
434         /**
435          * Sets the list of MQTT5 user properties included with the packet.
436          *
437          * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901116">MQTT5 User Property</a>
438          *
439          * @param userProperties List of MQTT5 user properties included with the packet.
440          * @return The PublishPacketBuilder after setting the user properties.
441          */
withUserProperties(List<UserProperty> userProperties)442         public PublishPacketBuilder withUserProperties(List<UserProperty> userProperties) {
443             this.userProperties = userProperties;
444             return this;
445         }
446 
447         /**
448          * Creates a new PublishPacketBuilder so a PublishPacket can be created.
449          */
PublishPacketBuilder()450         public PublishPacketBuilder() {}
451 
452         /**
453          * Creates a new PublishPacket using the settings set in the builder.
454          *
455          * @return The PublishPacket created from the builder
456          */
build()457         public PublishPacket build() {
458             return new PublishPacket(this);
459         }
460     }
461 }
462