• 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 java.util.ArrayList;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.function.Function;
11 import java.util.stream.Collectors;
12 import java.util.stream.Stream;
13 
14 import software.amazon.awssdk.crt.mqtt5.QOS;
15 
16 /**
17  * Data model of an <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901161">MQTT5 SUBSCRIBE</a> packet.
18  */
19 public class SubscribePacket {
20 
21     private List<Subscription> subscriptions;
22     private Long subscriptionIdentifier;
23     private List<UserProperty> userProperties;
24 
SubscribePacket(SubscribePacketBuilder builder)25     private SubscribePacket(SubscribePacketBuilder builder) {
26         this.subscriptions = builder.subscriptions;
27         this.subscriptionIdentifier = builder.subscriptionIdentifier;
28         this.userProperties = builder.userProperties;
29     }
30 
31     /**
32      * Returns the list of subscriptions that the client wishes to listen to
33      *
34      * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901168">MQTT5 Subscribe Payload</a>
35      *
36      * @return List of subscriptions that the client wishes to listen to
37      */
getSubscriptions()38     public List<Subscription> getSubscriptions() {
39         return this.subscriptions;
40     }
41 
42     /**
43      * Returns the positive long to associate with all subscriptions in this request.  Publish packets that match
44      * a subscription in this request should include this identifier in the resulting message.
45      *
46      * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901166">MQTT5 Subscription Identifier</a>
47      *
48      * @return A positive long to associate with all subscriptions in this request.
49      */
getSubscriptionIdentifier()50     public Long getSubscriptionIdentifier() {
51         return this.subscriptionIdentifier;
52     }
53 
54     /**
55      * Returns the list of MQTT5 user properties included with the packet.
56      *
57      * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901167">MQTT5 User Property</a>
58      *
59      * @return List of MQTT5 user properties included with the packet.
60      */
getUserProperties()61     public List<UserProperty> getUserProperties() {
62         return this.userProperties;
63     }
64 
65     /**
66      * Configures how retained messages should be handled when subscribing with a subscription that matches topics with
67      * associated retained messages.
68      *
69      * Enum values match <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901169">MQTT5 spec</a> encoding values.
70      */
71     public enum RetainHandlingType {
72 
73         /**
74          * The server should always send all retained messages on topics that match a subscription's filter.
75          */
76         SEND_ON_SUBSCRIBE(0),
77 
78         /**
79          * The server should send retained messages on topics that match the subscription's filter, but only for the
80          * first matching subscription, per session.
81          */
82         SEND_ON_SUBSCRIBE_IF_NEW(1),
83 
84         /**
85          * Subscriptions must not trigger any retained message publishes from the server.
86          */
87         DONT_SEND(2);
88 
89         private int type;
90 
RetainHandlingType(int code)91         private RetainHandlingType(int code) {
92             type = code;
93         }
94 
95         /**
96          * @return The native enum integer value associated with this Java enum value
97          */
getValue()98         public int getValue() {
99             return type;
100         }
101 
102         /**
103          * Creates a Java RetainHandlingType enum value from a native integer value.
104          *
105          * @param value native integer value for RetainHandlingType
106          * @return a new RetainHandlingType value
107          */
getEnumValueFromInteger(int value)108         public static RetainHandlingType getEnumValueFromInteger(int value) {
109             RetainHandlingType enumValue = enumMapping.get(value);
110             if (enumValue != null) {
111                 return enumValue;
112             }
113             throw new RuntimeException("Illegal RetainHandlingType");
114         }
115 
buildEnumMapping()116         private static Map<Integer, RetainHandlingType> buildEnumMapping() {
117             return Stream.of(RetainHandlingType.values())
118                 .collect(Collectors.toMap(RetainHandlingType::getValue, Function.identity()));
119         }
120 
121         private static Map<Integer, RetainHandlingType> enumMapping = buildEnumMapping();
122     }
123 
124     /**
125      * Configures a single subscription within a Subscribe operation
126      *
127      * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901169">MQTT5 Subscription Options</a>
128      */
129     static final public class Subscription {
130 
131         private String topicFilter;
132         private QOS qos;
133         private Boolean noLocal;
134         private Boolean retainAsPublished;
135         private RetainHandlingType retainHandlingType;
136 
137         /**
138          * Creates a new subscription within a subscribe operation
139          *
140          * @param topicFilter The topic filter to subscribe to
141          * @param qos The maximum QoS on which the subscriber will accept publish messages
142          * @param noLocal Whether the server will not send publishes to a client when that client was the one who
143          * sent the publish
144          * @param retainAsPublished Whether messages sent due to this subscription keep the retain flag preserved
145          * on the message
146          * @param retainHandlingType Whether retained messages on matching topics be sent in reaction to this subscription
147          */
Subscription(String topicFilter, QOS qos, Boolean noLocal, Boolean retainAsPublished, RetainHandlingType retainHandlingType)148         Subscription(String topicFilter, QOS qos, Boolean noLocal, Boolean retainAsPublished, RetainHandlingType retainHandlingType) {
149             this.topicFilter = topicFilter;
150             this.qos = qos;
151             this.noLocal = noLocal;
152             this.retainAsPublished = retainAsPublished;
153             this.retainHandlingType = retainHandlingType;
154         }
155 
156         /**
157          * Creates a new subscription within a subscribe operation
158          *
159          * @param topicFilter The topic filter to subscribe to
160          * @param qos The maximum QoS on which the subscriber will accept publish messages
161          */
Subscription(String topicFilter, QOS qos)162         Subscription(String topicFilter, QOS qos) {
163             this.topicFilter = topicFilter;
164             this.qos = qos;
165             // Defaults:
166             this.noLocal = false;
167             this.retainAsPublished = false;
168             this.retainHandlingType = RetainHandlingType.SEND_ON_SUBSCRIBE;
169         }
170 
171         /**
172          * Returns the topic filter to subscribe to
173          *
174          * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901169">MQTT5 Subscription Options</a>
175          *
176          * @return The topic filter to subscribe to
177          */
getTopicFilter()178         public String getTopicFilter() {
179             return this.topicFilter;
180         }
181 
182         /**
183          * Returns the maximum QoS on which the subscriber will accept publish messages.  Negotiated QoS may be different.
184          *
185          * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901169">MQTT5 Subscription Options</a>
186          *
187          * @return The maximum QoS on which the subscriber will accept publish messages
188          */
getQOS()189         public QOS getQOS() {
190             return this.qos;
191         }
192 
193         /**
194          * Returns whether the server should not send publishes to a client when that client was the one who sent the publish.  If
195          * null, this is assumed to be false.
196          *
197          * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901169">MQTT5 Subscription Options</a>
198          *
199          * @return Whether the server will not send publishes to a client when that client was the one who sent the publish
200          */
getNoLocal()201         public Boolean getNoLocal() {
202             return this.noLocal;
203         }
204 
205         /**
206          * Returns whether messages sent due to this subscription keep the retain flag preserved on the message.  If null,
207          * this is assumed to be false.
208          *
209          * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901169">MQTT5 Subscription Options</a>
210          *
211          * @return Whether messages sent due to this subscription keep the retain flag preserved on the message
212          */
getRetainAsPublished()213         public Boolean getRetainAsPublished() {
214             return this.retainAsPublished;
215         }
216 
217         /**
218          * Returns whether retained messages on matching topics be sent in reaction to this subscription.  If null,
219          * this is assumed to be RetainHandlingType.SendOnSubscribe.
220          *
221          * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901169">MQTT5 Subscription Options</a>
222          *
223          * @return Whether retained messages on matching topics be sent in reaction to this subscription
224          */
getRetainHandlingType()225         public RetainHandlingType getRetainHandlingType() {
226             return this.retainHandlingType;
227         }
228     }
229 
230     /**
231      * A class to that allows for the creation of a SubscribePacket. Set all of the settings you want in the
232      * packet and then use the build() function to get a SubscribePacket populated with the settings
233      * defined in the builder.
234      */
235     static final public class SubscribePacketBuilder {
236         private List<Subscription> subscriptions = new ArrayList<Subscription>();
237         Long subscriptionIdentifier;
238         private List<UserProperty> userProperties;
239 
240         /**
241          * Sets a single subscription within the SubscribePacket.
242          *
243          * @param subscription The subscription to add within the SubscribePacket.
244          * @return The SubscribePacketBuilder after setting the subscription.
245          */
withSubscription(Subscription subscription)246         public SubscribePacketBuilder withSubscription(Subscription subscription) {
247             this.subscriptions.add(subscription);
248             return this;
249         }
250 
251         /**
252          * Sets a single subscription within the SubscribePacket.
253          *
254          * @param topicFilter The topic filter to subscribe to
255          * @param qos The maximum QoS on which the subscriber will accept publish messages
256          * @param noLocal Whether the server will not send publishes to a client when that client was the one who
257          * sent the publish
258          * @param retainAsPublished Whether messages sent due to this subscription keep the retain flag preserved
259          * on the message
260          * @param retainHandlingType Whether retained messages on matching topics be sent in reaction to this subscription
261          * @return The SubscribePacketBuilder after setting the subscription.
262          */
withSubscription(String topicFilter, QOS qos, Boolean noLocal, Boolean retainAsPublished, RetainHandlingType retainHandlingType)263         public SubscribePacketBuilder withSubscription(String topicFilter, QOS qos, Boolean noLocal, Boolean retainAsPublished, RetainHandlingType retainHandlingType) {
264             return this.withSubscription(new Subscription(topicFilter, qos, noLocal, retainAsPublished, retainHandlingType));
265         }
266 
267         /**
268          * Sets a single subscription within the SubscribePacket.
269          *
270          * @param topicFilter The topic filter to subscribe to
271          * @param qos The maximum QoS on which the subscriber will accept publish messages
272          * @return The SubscribePacketBuilder after setting the subscription.
273          */
withSubscription(String topicFilter, QOS qos)274         public SubscribePacketBuilder withSubscription(String topicFilter, QOS qos) {
275             return this.withSubscription(new Subscription(topicFilter, qos));
276         }
277 
278         /**
279          * Sets the positive long to associate with all topic filters in this request.  Publish packets that match
280          * a subscription in this request should include this identifier in the resulting message.
281          *
282          * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901166">MQTT5 Subscription Identifier</a>
283          *
284          * @param subscriptionIdentifier A positive long to associate with all topic filters in this request.
285          * @return The SubscribePacketBuilder after setting the subscription identifier.
286          */
withSubscriptionIdentifier(long subscriptionIdentifier)287         public SubscribePacketBuilder withSubscriptionIdentifier(long subscriptionIdentifier) {
288             this.subscriptionIdentifier = subscriptionIdentifier;
289             return this;
290         }
291 
292         /**
293          * Sets the list of MQTT5 user properties included with the packet.
294          *
295          * See <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901167">MQTT5 User Property</a>
296          *
297          * @param userProperties List of MQTT5 user properties to be included with the packet.
298          * @return The SubscribePacketBuilder after setting the user properties.
299          */
withUserProperties(List<UserProperty> userProperties)300         public SubscribePacketBuilder withUserProperties(List<UserProperty> userProperties) {
301             this.userProperties = userProperties;
302             return this;
303         }
304 
305         /**
306          * Creates a new SubscribePacketBuilder so a SubscribePacket can be created.
307          */
SubscribePacketBuilder()308         public SubscribePacketBuilder() {}
309 
310         /**
311          * Creates a new SUBSCRIBE packet using the settings set in the builder.
312          * @return The SubscribePacket created from the builder
313          */
build()314         public SubscribePacket build() {
315             return new SubscribePacket(this);
316         }
317     }
318 
319 }
320