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; 6 7 import software.amazon.awssdk.crt.http.HttpProxyOptions; 8 import software.amazon.awssdk.crt.io.ClientBootstrap; 9 import software.amazon.awssdk.crt.io.SocketOptions; 10 import software.amazon.awssdk.crt.io.TlsContext; 11 import software.amazon.awssdk.crt.io.ExponentialBackoffRetryOptions.JitterMode; 12 13 import software.amazon.awssdk.crt.mqtt5.packets.ConnectPacket; 14 import software.amazon.awssdk.crt.mqtt.MqttConnectionConfig; 15 16 import java.util.Map; 17 import java.util.function.Function; 18 import java.util.stream.Collectors; 19 import java.util.stream.Stream; 20 import java.util.function.Consumer; 21 22 /** 23 * Configuration for the creation of Mqtt5Clients 24 */ 25 public class Mqtt5ClientOptions { 26 27 private String hostName; 28 private Long port; 29 private ClientBootstrap bootstrap; 30 private SocketOptions socketOptions; 31 private TlsContext tlsContext; 32 private HttpProxyOptions httpProxyOptions; 33 private ConnectPacket connectOptions; 34 private ClientSessionBehavior sessionBehavior = ClientSessionBehavior.DEFAULT; 35 private ExtendedValidationAndFlowControlOptions extendedValidationAndFlowControlOptions = ExtendedValidationAndFlowControlOptions.NONE; 36 private ClientOfflineQueueBehavior offlineQueueBehavior = ClientOfflineQueueBehavior.DEFAULT; 37 private JitterMode retryJitterMode = JitterMode.Default; 38 private Long minReconnectDelayMs; 39 private Long maxReconnectDelayMs; 40 private Long minConnectedTimeToResetReconnectDelayMs; 41 private Long pingTimeoutMs; 42 private Long connackTimeoutMs; 43 private Long ackTimeoutSeconds; 44 private LifecycleEvents lifecycleEvents; 45 private Consumer<Mqtt5WebsocketHandshakeTransformArgs> websocketHandshakeTransform; 46 private PublishEvents publishEvents; 47 private TopicAliasingOptions topicAliasingOptions; 48 49 /** 50 * Returns the host name of the MQTT server to connect to. 51 * 52 * @return Host name of the MQTT server to connect to. 53 */ getHostName()54 public String getHostName() 55 { 56 return this.hostName; 57 } 58 59 /** 60 * Returns the network port of the MQTT server to connect to. 61 * 62 * @return Network port of the MQTT server to connect to. 63 */ getPort()64 public Long getPort() 65 { 66 return this.port; 67 } 68 69 /** 70 * Returns the Client bootstrap used. 71 * 72 * @return The Client bootstrap used 73 */ getBootstrap()74 public ClientBootstrap getBootstrap() 75 { 76 return this.bootstrap; 77 } 78 79 /** 80 * Returns the socket properties of the underlying MQTT connections made by the client. 81 * 82 * @return the socket properties of the underlying MQTT connections made by the client or null if defaults are used. 83 */ getSocketOptions()84 public SocketOptions getSocketOptions() 85 { 86 return this.socketOptions; 87 } 88 89 /** 90 * Returns the TLS context for secure socket connections. 91 * If null, then a plaintext connection will be used. 92 * 93 * @return TLS context for secure socket connections. 94 */ getTlsContext()95 public TlsContext getTlsContext() 96 { 97 return this.tlsContext; 98 } 99 100 /** 101 * Returns the (tunneling) HTTP proxy usage when establishing MQTT connections 102 * 103 * @return (tunneling) HTTP proxy usage when establishing MQTT connections 104 */ getHttpProxyOptions()105 public HttpProxyOptions getHttpProxyOptions() 106 { 107 return this.httpProxyOptions; 108 } 109 110 /** 111 * Returns all configurable options with respect to the CONNECT packet sent by the client, including the will. These 112 * connect properties will be used for every connection attempt made by the client. 113 * 114 * @return all configurable options with respect to the CONNECT packet sent by the client, including the will 115 */ getConnectOptions()116 public ConnectPacket getConnectOptions() 117 { 118 return this.connectOptions; 119 } 120 121 /** 122 * Returns how the Mqtt5Client should behave with respect to MQTT sessions. 123 * 124 * @return How the Mqtt5Client should behave with respect to MQTT sessions. 125 */ getSessionBehavior()126 public ClientSessionBehavior getSessionBehavior() 127 { 128 return this.sessionBehavior; 129 } 130 131 /** 132 * Returns the additional controls for client behavior with respect to operation validation and flow control; 133 * these checks go beyond the base MQTT5 spec to respect limits of specific MQTT brokers. 134 * 135 * @return The additional controls for client behavior with respect to operation validation and flow control 136 */ getExtendedValidationAndFlowControlOptions()137 public ExtendedValidationAndFlowControlOptions getExtendedValidationAndFlowControlOptions() 138 { 139 return this.extendedValidationAndFlowControlOptions; 140 } 141 142 /** 143 * Returns how disconnects affect the queued and in-progress operations tracked by the client. Also controls 144 * how new operations are handled while the client is not connected. In particular, if the client is not connected, 145 * then any operation that would be failed on disconnect (according to these rules) will also be rejected. 146 * 147 * @return How disconnects affect the queued and in-progress operations tracked by the client. 148 */ getOfflineQueueBehavior()149 public ClientOfflineQueueBehavior getOfflineQueueBehavior() 150 { 151 return this.offlineQueueBehavior; 152 } 153 154 /** 155 * Returns how the reconnect delay is modified in order to smooth out the distribution of reconnection attempt 156 * time points for a large set of reconnecting clients. 157 * 158 * @return how the reconnect delay is modified in order to smooth out the distribution of reconnection attempt 159 * time points for a large set of reconnecting clients. 160 */ getRetryJitterMode()161 public JitterMode getRetryJitterMode() 162 { 163 return this.retryJitterMode; 164 } 165 166 /** 167 * Returns the minimum amount of time to wait to reconnect after a disconnect. 168 * Exponential back-off is performed with jitter after each connection failure. 169 * 170 * @return The minimum amount of time to wait to reconnect after a disconnect. 171 */ getMinReconnectDelayMs()172 public Long getMinReconnectDelayMs() { 173 return this.minReconnectDelayMs; 174 } 175 176 /** 177 * Returns the maximum amount of time to wait to reconnect after a disconnect. Exponential back-off is performed with jitter 178 * after each connection failure. 179 * 180 * @return The maximum amount of time to wait to reconnect after a disconnect 181 */ getMaxReconnectDelayMs()182 public Long getMaxReconnectDelayMs() { 183 return this.maxReconnectDelayMs; 184 } 185 186 /** 187 * Returns the amount of time that must elapse with an established connection before the reconnect delay is reset to the minimum. 188 * This helps alleviate bandwidth-waste in fast reconnect cycles due to permission failures on operations. 189 * 190 * @return The amount of time that must elapse with an established connection before the reconnect delay is reset to the minimum 191 */ getMinConnectedTimeToResetReconnectDelayMs()192 public Long getMinConnectedTimeToResetReconnectDelayMs() { 193 return this.minConnectedTimeToResetReconnectDelayMs; 194 } 195 196 /** 197 * Returns the time interval to wait after sending a PINGREQ for a PINGRESP to arrive. If one does not arrive, the client will 198 * close the current connection. 199 * 200 * @return time interval to wait after sending a PINGREQ for a PINGRESP to arrive. 201 */ getPingTimeoutMs()202 public Long getPingTimeoutMs() { 203 return this.pingTimeoutMs; 204 } 205 206 /** 207 * Returns the time interval to wait after sending a CONNECT request for a CONNACK to arrive. If one does not arrive, the 208 * connection will be shut down. 209 * 210 * @return Time interval to wait after sending a CONNECT request for a CONNACK to arrive 211 */ getConnackTimeoutMs()212 public Long getConnackTimeoutMs() { 213 return this.connackTimeoutMs; 214 } 215 216 /** 217 * Returns the time interval to wait for an ack after sending a QoS 1+ PUBLISH, SUBSCRIBE, or UNSUBSCRIBE before 218 * failing the operation. 219 * 220 * @return the time interval to wait for an ack after sending a QoS 1+ PUBLISH, SUBSCRIBE, or UNSUBSCRIBE before 221 * failing the operation. 222 */ getAckTimeoutSeconds()223 public Long getAckTimeoutSeconds() { 224 return this.ackTimeoutSeconds; 225 } 226 227 /** 228 * Returns the LifecycleEvents interface that will be called when the client gets a LifecycleEvent. 229 * 230 * @return The LifecycleEvents interface that will be called when the client gets a LifecycleEvent 231 */ getLifecycleEvents()232 public LifecycleEvents getLifecycleEvents() { 233 return this.lifecycleEvents; 234 } 235 236 /** 237 * Returns the callback that allows a custom transformation of the HTTP request which acts as the websocket handshake. 238 * Websockets will be used if this is set to a valid transformation callback. To use websockets but not perform 239 * a transformation, just set this as a trivial completion callback. If null, the connection will be made 240 * with direct MQTT. 241 * 242 * @return The custom transformation of the HTTP request that acts as the websocket handshake or null. 243 */ getWebsocketHandshakeTransform()244 public Consumer<Mqtt5WebsocketHandshakeTransformArgs> getWebsocketHandshakeTransform() { 245 return this.websocketHandshakeTransform; 246 } 247 248 /** 249 * Returns the PublishEvents interface that will be called when the client gets a message. 250 * 251 * @return PublishEvents interface that will be called when the client gets a message. 252 */ getPublishEvents()253 public PublishEvents getPublishEvents() { 254 return this.publishEvents; 255 } 256 257 /** 258 * Returns the topic aliasing options to be used by the client 259 * 260 * @return the topic aliasing options to be used by the client 261 */ getTopicAliasingOptions()262 public TopicAliasingOptions getTopicAliasingOptions() { 263 return this.topicAliasingOptions; 264 } 265 266 /** 267 * Creates a Mqtt5ClientOptionsBuilder instance 268 * @param builder The builder to get the Mqtt5ClientOptions values from 269 */ Mqtt5ClientOptions(Mqtt5ClientOptionsBuilder builder)270 public Mqtt5ClientOptions(Mqtt5ClientOptionsBuilder builder) { 271 this.hostName = builder.hostName; 272 this.port = builder.port; 273 this.bootstrap = builder.bootstrap; 274 this.socketOptions = builder.socketOptions; 275 this.tlsContext = builder.tlsContext; 276 this.httpProxyOptions = builder.httpProxyOptions; 277 this.connectOptions = builder.connectOptions; 278 this.sessionBehavior = builder.sessionBehavior; 279 this.extendedValidationAndFlowControlOptions = builder.extendedValidationAndFlowControlOptions; 280 this.offlineQueueBehavior = builder.offlineQueueBehavior; 281 this.retryJitterMode = builder.retryJitterMode; 282 this.minReconnectDelayMs = builder.minReconnectDelayMs; 283 this.maxReconnectDelayMs = builder.maxReconnectDelayMs; 284 this.minConnectedTimeToResetReconnectDelayMs = builder.minConnectedTimeToResetReconnectDelayMs; 285 this.pingTimeoutMs = builder.pingTimeoutMs; 286 this.connackTimeoutMs = builder.connackTimeoutMs; 287 this.ackTimeoutSeconds = builder.ackTimeoutSeconds; 288 this.lifecycleEvents = builder.lifecycleEvents; 289 this.websocketHandshakeTransform = builder.websocketHandshakeTransform; 290 this.publishEvents = builder.publishEvents; 291 this.topicAliasingOptions = builder.topicAliasingOptions; 292 } 293 294 /******************************************************************************* 295 * lifecycle methods 296 ******************************************************************************/ 297 298 /** 299 * An interface that defines all of the functions the Mqtt5Client will call when it receives a lifecycle event. 300 */ 301 public interface LifecycleEvents { 302 /** 303 * Called when the client begins a connection attempt 304 * 305 * @param client The client associated with the event 306 * @param onAttemptingConnectReturn The data associated with the onAttemptingConnect event. 307 */ onAttemptingConnect(Mqtt5Client client, OnAttemptingConnectReturn onAttemptingConnectReturn)308 public void onAttemptingConnect(Mqtt5Client client, OnAttemptingConnectReturn onAttemptingConnectReturn); 309 310 /** 311 * Called when the client successfully establishes an MQTT connection 312 * 313 * @param client The client associated with the event 314 * @param onConnectionSuccessReturn The data associated with the onConnectionSuccess event. 315 */ onConnectionSuccess(Mqtt5Client client, OnConnectionSuccessReturn onConnectionSuccessReturn)316 public void onConnectionSuccess(Mqtt5Client client, OnConnectionSuccessReturn onConnectionSuccessReturn); 317 318 /** 319 * Called when the client fails to establish an MQTT connection 320 * 321 * @param client The client associated with the event 322 * @param onConnectionFailureReturn The data associated with the onConnectionFailure event. 323 */ onConnectionFailure(Mqtt5Client client, OnConnectionFailureReturn onConnectionFailureReturn)324 public void onConnectionFailure(Mqtt5Client client, OnConnectionFailureReturn onConnectionFailureReturn); 325 326 /** 327 * Called when the client's current MQTT connection is closed 328 * 329 * @param client The client associated with the event 330 * @param onDisconnectionReturn The data associated with the onDisconnection event. 331 */ onDisconnection(Mqtt5Client client, OnDisconnectionReturn onDisconnectionReturn)332 public void onDisconnection(Mqtt5Client client, OnDisconnectionReturn onDisconnectionReturn); 333 334 /** 335 * Called when the client reaches the 'Stopped' state as a result of the user invoking .stop() 336 * 337 * @param client The client associated with the event 338 * @param onStoppedReturn The data associated with the onStopped event. 339 */ onStopped(Mqtt5Client client, OnStoppedReturn onStoppedReturn)340 public void onStopped(Mqtt5Client client, OnStoppedReturn onStoppedReturn); 341 } 342 343 /** 344 * An interface that defines all of the publish functions the Mqtt5Client will call when it receives a publish packet. 345 */ 346 public interface PublishEvents { 347 /** 348 * Called when an MQTT PUBLISH packet is received by the client 349 * 350 * @param client The client that has received the message 351 * @param publishReturn All of the data that was received from the server 352 */ onMessageReceived(Mqtt5Client client, PublishReturn publishReturn)353 public void onMessageReceived(Mqtt5Client client, PublishReturn publishReturn); 354 } 355 356 /******************************************************************************* 357 * builder 358 ******************************************************************************/ 359 360 /** 361 * Controls how the Mqtt5Client should behave with respect to MQTT sessions. 362 */ 363 public enum ClientSessionBehavior { 364 365 /** 366 * Default client session behavior. Maps to CLEAN. 367 */ 368 DEFAULT(0), 369 370 /** 371 * Always ask for a clean session when connecting 372 */ 373 CLEAN(1), 374 375 /** 376 * Always attempt to rejoin an existing session after an initial connection success. 377 * 378 * Session rejoin requires an appropriate non-zero session expiry interval in the client's CONNECT options. 379 */ 380 REJOIN_POST_SUCCESS(2), 381 382 /** 383 * Always attempt to rejoin an existing session. Since the client does not yet support durable session persistence, 384 * this option is not guaranteed to be spec compliant because any unacknowledged qos1 publishes (which are 385 * part of the client session state) will not be present on the initial connection. Until we support 386 * durable session resumption, this option is technically spec-breaking, but useful. 387 */ 388 REJOIN_ALWAYS(3); 389 390 private int type; 391 ClientSessionBehavior(int code)392 private ClientSessionBehavior(int code) { 393 type = code; 394 } 395 396 /** 397 * @return The native enum integer value associated with this enum value 398 */ getValue()399 public int getValue() { 400 return type; 401 } 402 403 /** 404 * Creates a ClientSessionBehavior enum value from a native integer value. 405 * 406 * @param value native integer value for the Client Session Behavior Type 407 * @return a new ClientSessionBehavior value 408 */ getEnumValueFromInteger(int value)409 public static ClientSessionBehavior getEnumValueFromInteger(int value) { 410 ClientSessionBehavior enumValue = enumMapping.get(value); 411 if (enumValue != null) { 412 return enumValue; 413 } 414 throw new RuntimeException("Illegal ClientSessionBehavior"); 415 } 416 buildEnumMapping()417 private static Map<Integer, ClientSessionBehavior> buildEnumMapping() { 418 return Stream.of(ClientSessionBehavior.values()) 419 .collect(Collectors.toMap(ClientSessionBehavior::getValue, Function.identity())); 420 } 421 422 private static Map<Integer, ClientSessionBehavior> enumMapping = buildEnumMapping(); 423 } 424 425 /** 426 * Additional controls for client behavior with respect to operation validation and flow control; these checks 427 * go beyond the MQTT5 spec to respect limits of specific MQTT brokers. 428 */ 429 public enum ExtendedValidationAndFlowControlOptions { 430 431 /** 432 * Do not do any additional validation or flow control 433 */ 434 NONE(0), 435 436 /** 437 * Apply additional client-side validation and operational flow control that respects the 438 * default AWS IoT Core limits. 439 * 440 * Currently applies the following additional validation: 441 * 442 * <ol> 443 * <li> No more than 8 subscriptions per SUBSCRIBE packet </li> 444 * <li> Topics and topic filters have a maximum of 7 slashes (8 segments), not counting any AWS rules prefix </li> 445 * <li> Topics must be 256 bytes or less in length </li> 446 * <li> Client id must be 128 or less bytes in length </li> 447 * </ol> 448 * 449 * Also applies the following flow control: 450 * 451 * <ol> 452 * <li> Outbound throughput throttled to 512KB/s </li> 453 * <li> Outbound publish TPS throttled to 100 </li> 454 * </ol> 455 */ 456 AWS_IOT_CORE_DEFAULTS(1); 457 458 private int type; 459 ExtendedValidationAndFlowControlOptions(int code)460 private ExtendedValidationAndFlowControlOptions(int code) { 461 type = code; 462 } 463 464 /** 465 * @return The native enum integer value associated with this Java enum value 466 */ getValue()467 public int getValue() { 468 return type; 469 } 470 471 /** 472 * Creates a Java ExtendedValidationAndFlowControlOptions enum value from a native integer value. 473 * 474 * @param value native integer value for the extended validation and flow control options 475 * @return a new ExtendedValidationAndFlowControlOptions value 476 */ getEnumValueFromInteger(int value)477 public static ExtendedValidationAndFlowControlOptions getEnumValueFromInteger(int value) { 478 ExtendedValidationAndFlowControlOptions enumValue = enumMapping.get(value); 479 if (enumValue != null) { 480 return enumValue; 481 } 482 throw new RuntimeException("Illegal ExtendedValidationAndFlowControlOptions"); 483 } 484 buildEnumMapping()485 private static Map<Integer, ExtendedValidationAndFlowControlOptions> buildEnumMapping() { 486 return Stream.of(ExtendedValidationAndFlowControlOptions.values()) 487 .collect(Collectors.toMap(ExtendedValidationAndFlowControlOptions::getValue, Function.identity())); 488 } 489 490 private static Map<Integer, ExtendedValidationAndFlowControlOptions> enumMapping = buildEnumMapping(); 491 } 492 493 /** 494 * Controls how disconnects affect the queued and in-progress operations tracked by the client. Also controls 495 * how operations are handled while the client is not connected. In particular, if the client is not connected, 496 * then any operation that would be failed on disconnect (according to these rules) will be rejected. 497 */ 498 public enum ClientOfflineQueueBehavior { 499 500 /** 501 * Default client operation queue behavior. Maps to FAIL_QOS0_PUBLISH_ON_DISCONNECT. 502 */ 503 DEFAULT(0), 504 505 /** 506 * Re-queues QoS 1+ publishes on disconnect; un-acked publishes go to the front while unprocessed publishes stay 507 * in place. All other operations (QoS 0 publishes, subscribe, unsubscribe) are failed. 508 */ 509 FAIL_NON_QOS1_PUBLISH_ON_DISCONNECT(1), 510 511 /** 512 * QoS 0 publishes that are not complete at the time of disconnection are failed. Un-acked QoS 1+ publishes are 513 * re-queued at the head of the line for immediate retransmission on a session resumption. All other operations 514 * are requeued in original order behind any retransmissions. 515 */ 516 FAIL_QOS0_PUBLISH_ON_DISCONNECT(2), 517 518 /** 519 * All operations that are not complete at the time of disconnection are failed, except operations that 520 * the MQTT5 spec requires to be retransmitted (un-acked QoS1+ publishes). 521 */ 522 FAIL_ALL_ON_DISCONNECT(3); 523 524 private int type; 525 ClientOfflineQueueBehavior(int code)526 private ClientOfflineQueueBehavior(int code) { 527 type = code; 528 } 529 530 /** 531 * @return The native enum integer value associated with this Java enum value 532 */ getValue()533 public int getValue() { 534 return type; 535 } 536 537 /** 538 * Creates a Java ClientOfflineQueueBehavior enum value from a native integer value. 539 * 540 * @param value native integer value for the client operation queue behavior type 541 * @return a new ClientOfflineQueueBehavior value 542 */ getEnumValueFromInteger(int value)543 public static ClientOfflineQueueBehavior getEnumValueFromInteger(int value) { 544 ClientOfflineQueueBehavior enumValue = enumMapping.get(value); 545 if (enumValue != null) { 546 return enumValue; 547 } 548 throw new RuntimeException("Illegal ClientOfflineQueueBehavior"); 549 } 550 buildEnumMapping()551 private static Map<Integer, ClientOfflineQueueBehavior> buildEnumMapping() { 552 return Stream.of(ClientOfflineQueueBehavior.values()) 553 .collect(Collectors.toMap(ClientOfflineQueueBehavior::getValue, Function.identity())); 554 } 555 556 private static Map<Integer, ClientOfflineQueueBehavior> enumMapping = buildEnumMapping(); 557 } 558 559 /** 560 * All of the options for a Mqtt5Client. This includes the settings to make a connection, as well as the 561 * event callbacks, publish callbacks, and more. 562 */ 563 static final public class Mqtt5ClientOptionsBuilder { 564 565 private String hostName; 566 private Long port; 567 private ClientBootstrap bootstrap; 568 private SocketOptions socketOptions; 569 private TlsContext tlsContext; 570 private HttpProxyOptions httpProxyOptions; 571 private ConnectPacket connectOptions; 572 private ClientSessionBehavior sessionBehavior = ClientSessionBehavior.DEFAULT; 573 private ExtendedValidationAndFlowControlOptions extendedValidationAndFlowControlOptions = ExtendedValidationAndFlowControlOptions.NONE; 574 private ClientOfflineQueueBehavior offlineQueueBehavior = ClientOfflineQueueBehavior.DEFAULT; 575 private JitterMode retryJitterMode = JitterMode.Default; 576 private Long minReconnectDelayMs; 577 private Long maxReconnectDelayMs; 578 private Long minConnectedTimeToResetReconnectDelayMs; 579 private Long pingTimeoutMs; 580 private Long connackTimeoutMs; 581 private Long ackTimeoutSeconds; 582 private LifecycleEvents lifecycleEvents; 583 private Consumer<Mqtt5WebsocketHandshakeTransformArgs> websocketHandshakeTransform; 584 private PublishEvents publishEvents; 585 private TopicAliasingOptions topicAliasingOptions; 586 587 /** 588 * Sets the host name of the MQTT server to connect to. 589 * 590 * @param hostName Host name of the MQTT server to connect to. 591 * @return The Mqtt5ClientOptionsBuilder after setting the host name 592 */ withHostName(String hostName)593 public Mqtt5ClientOptionsBuilder withHostName(String hostName) 594 { 595 this.hostName = hostName; 596 return this; 597 } 598 599 /** 600 * Sets the network port of the MQTT server to connect to. 601 * 602 * @param port Network port of the MQTT server to connect to. 603 * @return The Mqtt5ClientOptionsBuilder after setting the port 604 */ withPort(Long port)605 public Mqtt5ClientOptionsBuilder withPort(Long port) 606 { 607 this.port = port; 608 return this; 609 } 610 611 /** 612 * Sets the ClientBootstrap to use. In almost all cases, this should be left null. 613 * 614 * @param bootstrap The ClientBootstrap to use 615 * @return The Mqtt5ClientOptionsBuilder after setting the ClientBootstrap 616 */ withBootstrap(ClientBootstrap bootstrap)617 public Mqtt5ClientOptionsBuilder withBootstrap(ClientBootstrap bootstrap) 618 { 619 this.bootstrap = bootstrap; 620 return this; 621 } 622 623 /** 624 * Sets the socket properties of the underlying MQTT connections made by the client. Leave null to use 625 * defaults (no TCP keep alive, 10 second socket timeout). 626 * 627 * @param socketOptions The socket properties of the underlying MQTT connections made by the client. 628 * @return The Mqtt5ClientOptionsBuilder after setting the socket options 629 */ withSocketOptions(SocketOptions socketOptions)630 public Mqtt5ClientOptionsBuilder withSocketOptions(SocketOptions socketOptions) 631 { 632 this.socketOptions = socketOptions; 633 return this; 634 } 635 636 /** 637 * Sets the TLS context for secure socket connections. 638 * If null, then a plaintext connection will be used. 639 * 640 * @param tlsContext The TLS context for secure socket connections. 641 * @return The Mqtt5ClientOptionsBuilder after setting the TlsContext 642 */ withTlsContext(TlsContext tlsContext)643 public Mqtt5ClientOptionsBuilder withTlsContext(TlsContext tlsContext) 644 { 645 this.tlsContext = tlsContext; 646 return this; 647 } 648 649 /** 650 * Sets the (tunneling) HTTP proxy usage when establishing MQTT connection. 651 * 652 * @param httpProxyOptions the (tunneling) HTTP proxy usage when establishing MQTT connection. 653 * @return The Mqtt5ClientOptionsBuilder after setting the HttpProxyOptions 654 */ withHttpProxyOptions(HttpProxyOptions httpProxyOptions)655 public Mqtt5ClientOptionsBuilder withHttpProxyOptions(HttpProxyOptions httpProxyOptions) 656 { 657 this.httpProxyOptions = httpProxyOptions; 658 return this; 659 } 660 661 /** 662 * Sets all configurable options with respect to the CONNECT packet sent by the client, including the Will. These 663 * connect properties will be used for every connection attempt made by the client. 664 * 665 * @param connectOptions Configurable options with respect to the CONNECT packet sent by the client, including the Will. 666 * @return The Mqtt5ClientOptionsBuilder after setting the connect options 667 */ withConnectOptions(ConnectPacket connectOptions)668 public Mqtt5ClientOptionsBuilder withConnectOptions(ConnectPacket connectOptions) 669 { 670 this.connectOptions = connectOptions; 671 return this; 672 } 673 674 /** 675 * Sets how the Mqtt5Client should behave with respect to MQTT sessions. 676 * 677 * @param sessionBehavior How the Mqtt5Client should behave with respect to MQTT sessions. 678 * @return The Mqtt5ClientOptionsBuilder after setting the ClientSessionBehavior 679 */ withSessionBehavior(ClientSessionBehavior sessionBehavior)680 public Mqtt5ClientOptionsBuilder withSessionBehavior(ClientSessionBehavior sessionBehavior) 681 { 682 this.sessionBehavior = sessionBehavior; 683 return this; 684 } 685 686 /** 687 * Sets the additional controls for client behavior with respect to operation validation and flow control; these checks 688 * go beyond the base MQTT5 spec to respect limits of specific MQTT brokers. 689 * 690 * @param extendedValidationAndFlowControlOptions Additional controls for client behavior with respect to operation validation and flow control 691 * @return The Mqtt5ClientOptionsBuilder after setting the ExtendedValidationAndFlowControlOptions 692 */ withExtendedValidationAndFlowControlOptions(ExtendedValidationAndFlowControlOptions extendedValidationAndFlowControlOptions)693 public Mqtt5ClientOptionsBuilder withExtendedValidationAndFlowControlOptions(ExtendedValidationAndFlowControlOptions extendedValidationAndFlowControlOptions) 694 { 695 this.extendedValidationAndFlowControlOptions = extendedValidationAndFlowControlOptions; 696 return this; 697 } 698 699 /** 700 * Sets how disconnects affect the queued and in-progress operations tracked by the client. Also controls 701 * how new operations are handled while the client is not connected. In particular, if the client is not connected, 702 * then any operation that would be failed on disconnect (according to these rules) will also be rejected. 703 * 704 * @param offlineQueueBehavior How disconnects affect the queued and in-progress operations tracked by the client 705 * @return The Mqtt5ClientOptionsBuilder after setting the ClientOfflineQueueBehavior 706 */ withOfflineQueueBehavior(ClientOfflineQueueBehavior offlineQueueBehavior)707 public Mqtt5ClientOptionsBuilder withOfflineQueueBehavior(ClientOfflineQueueBehavior offlineQueueBehavior) 708 { 709 this.offlineQueueBehavior = offlineQueueBehavior; 710 return this; 711 } 712 713 /** 714 * Sets how the reconnect delay is modified in order to smooth out the distribution of reconnection attempt 715 * time points for a large set of reconnecting clients. 716 * 717 * @param retryJitterMode How the reconnect delay is modified in order to smooth out the distribution of reconnection attempt 718 * time points for a large set of reconnecting clients. 719 * @return The Mqtt5ClientOptionsBuilder after setting the JitterMode 720 */ withRetryJitterMode(JitterMode retryJitterMode)721 public Mqtt5ClientOptionsBuilder withRetryJitterMode(JitterMode retryJitterMode) 722 { 723 this.retryJitterMode = retryJitterMode; 724 return this; 725 } 726 727 /** 728 * Sets the minimum amount of time to wait to reconnect after a disconnect. Exponential back-off is performed with jitter 729 * after each connection failure. 730 * 731 * @param minReconnectDelayMs The minimum amount of time to wait to reconnect after a disconnect. 732 * @return The Mqtt5ClientOptionsBuilder after setting the minimum reconnect delay 733 */ withMinReconnectDelayMs(Long minReconnectDelayMs)734 public Mqtt5ClientOptionsBuilder withMinReconnectDelayMs(Long minReconnectDelayMs) 735 { 736 this.minReconnectDelayMs = minReconnectDelayMs; 737 return this; 738 } 739 740 /** 741 * Sets the maximum amount of time to wait to reconnect after a disconnect. Exponential back-off is performed with jitter 742 * after each connection failure. 743 * 744 * @param maxReconnectDelayMs The maximum amount of time to wait to reconnect after a disconnect 745 * @return The Mqtt5ClientOptionsBuilder after setting the maximum reconnect delay 746 */ withMaxReconnectDelayMs(Long maxReconnectDelayMs)747 public Mqtt5ClientOptionsBuilder withMaxReconnectDelayMs(Long maxReconnectDelayMs) 748 { 749 this.maxReconnectDelayMs = maxReconnectDelayMs; 750 return this; 751 } 752 753 /** 754 * Sets the minimum time needed to pass to reset the reconnect delay in milliseconds used when the Mqtt5Client connects. 755 * 756 * @param minConnectedTimeToResetReconnectDelayMs The minimum time needed to pass to reset the reconnect delay 757 * @return The Mqtt5ClientOptionsBuilder after setting the minimum time needed to pass to reset the reconnect delay 758 */ withMinConnectedTimeToResetReconnectDelayMs(Long minConnectedTimeToResetReconnectDelayMs)759 public Mqtt5ClientOptionsBuilder withMinConnectedTimeToResetReconnectDelayMs(Long minConnectedTimeToResetReconnectDelayMs) 760 { 761 this.minConnectedTimeToResetReconnectDelayMs = minConnectedTimeToResetReconnectDelayMs; 762 return this; 763 } 764 765 /** 766 * Sets the time interval to wait after sending a PINGREQ for a PINGRESP to arrive. If one does not arrive, the client will 767 * close the current connection. 768 * 769 * @param pingTimeoutMs The time interval to wait after sending a PINGREQ for a PINGRESP to arrive. 770 * @return The Mqtt5ClientOptionsBuilder after setting the ping timeout time 771 */ withPingTimeoutMs(Long pingTimeoutMs)772 public Mqtt5ClientOptionsBuilder withPingTimeoutMs(Long pingTimeoutMs) 773 { 774 this.pingTimeoutMs = pingTimeoutMs; 775 return this; 776 } 777 778 /** 779 * Sets the time interval to wait after sending a CONNECT request for a CONNACK to arrive. If one does not arrive, the 780 * connection will be shut down. 781 * 782 * @param connackTimeoutMs The time interval to wait after sending a CONNECT request for a CONNACK to arrive. 783 * @return The Mqtt5ClientOptionsBuilder after setting the timeout in milliseconds for getting a ConnAckPacket from the server 784 */ withConnackTimeoutMs(Long connackTimeoutMs)785 public Mqtt5ClientOptionsBuilder withConnackTimeoutMs(Long connackTimeoutMs) 786 { 787 this.connackTimeoutMs = connackTimeoutMs; 788 return this; 789 } 790 791 /** 792 * Sets the time interval to wait for an ack after sending a QoS 1+ PUBLISH, SUBSCRIBE, or UNSUBSCRIBE before 793 * failing the operation. 794 * 795 * @param ackTimeoutSeconds The time interval to wait for an ack after sending a QoS 1+ PUBLISH, SUBSCRIBE, or UNSUBSCRIBE before 796 * failing the operation. 797 * @return The Mqtt5ClientOptionsBuilder after setting the timeout in milliseconds for getting an ACK packet 798 * from the server when performing an operation 799 */ withAckTimeoutSeconds(Long ackTimeoutSeconds)800 public Mqtt5ClientOptionsBuilder withAckTimeoutSeconds(Long ackTimeoutSeconds) 801 { 802 this.ackTimeoutSeconds = ackTimeoutSeconds; 803 return this; 804 } 805 806 /** 807 * Sets the Lifecycle Events interface that will be called when the client gets a LifecycleEvent. 808 * 809 * @param lifecycleEvents The LifecycleEvents interface that will be called 810 * @return The Mqtt5ClientOptionsBuilder after setting the Lifecycle Events interface 811 */ withLifecycleEvents(LifecycleEvents lifecycleEvents)812 public Mqtt5ClientOptionsBuilder withLifecycleEvents(LifecycleEvents lifecycleEvents) { 813 this.lifecycleEvents = lifecycleEvents; 814 return this; 815 } 816 817 /** 818 * Sets the callback that allows a custom transformation of the HTTP request that acts as the websocket handshake. 819 * Websockets will be used if this is set to a valid transformation callback. To use websockets but not perform 820 * a transformation, just set this as a trivial completion callback. If null, the connection will be made 821 * with direct MQTT. 822 * 823 * @param handshakeTransform Callback that allows a custom transformation of the HTTP request that acts as the websocket handshake. 824 * @return The Mqtt5ClientOptionsBuilder after setting the websocket handshake transform callback 825 */ withWebsocketHandshakeTransform(Consumer<Mqtt5WebsocketHandshakeTransformArgs> handshakeTransform)826 public Mqtt5ClientOptionsBuilder withWebsocketHandshakeTransform(Consumer<Mqtt5WebsocketHandshakeTransformArgs> handshakeTransform) { 827 this.websocketHandshakeTransform = handshakeTransform; 828 return this; 829 } 830 831 /** 832 * Sets the PublishEvents interface that will be called when the client gets a message. 833 * 834 * @param publishEvents The PublishEvents interface that will be called when the client gets a message. 835 * @return The Mqtt5ClientOptionsBuilder after setting the PublishEvents interface 836 */ withPublishEvents(PublishEvents publishEvents)837 public Mqtt5ClientOptionsBuilder withPublishEvents(PublishEvents publishEvents) { 838 this.publishEvents = publishEvents; 839 return this; 840 } 841 842 /** 843 * Sets the topic aliasing options for clients constructed from this builder 844 * 845 * @param options topic aliasing options that the client should use 846 * @return The Mqtt5ClientOptionsBuilder object 847 */ withTopicAliasingOptions(TopicAliasingOptions options)848 public Mqtt5ClientOptionsBuilder withTopicAliasingOptions(TopicAliasingOptions options) { 849 this.topicAliasingOptions = options; 850 return this; 851 } 852 853 /** 854 * Creates a new Mqtt5ClientOptionsBuilder instance 855 * 856 * @param hostName The host name of the MQTT server to connect to. 857 * @param port The port of the MQTT server to connect to. 858 */ Mqtt5ClientOptionsBuilder(String hostName, Long port)859 public Mqtt5ClientOptionsBuilder(String hostName, Long port) { 860 this.hostName = hostName; 861 this.port = port; 862 } 863 864 /** 865 * Returns a Mqtt5ClientOptions class configured with all of the options set in the Mqtt5ClientOptionsBuilder. 866 * This can then be used to make a new Mqtt5Client. 867 * 868 * @return A configured Mqtt5ClientOptions 869 */ build()870 public Mqtt5ClientOptions build() 871 { 872 return new Mqtt5ClientOptions(this); 873 } 874 } 875 876 } 877