From 564483864fcb1bbb3a0e491f29b7ca6e5ab32382 Mon Sep 17 00:00:00 2001 From: sumitjat3 Date: Tue, 5 Nov 2024 19:07:38 +0530 Subject: [PATCH] Add support for the last will (#86) --- .../com/gojek/courier/app/ui/MainActivity.kt | 10 ++++++++++ mqtt-client/api/mqtt-client.api | 20 +++++++++++++++++++ .../mqtt/client/v3/impl/AndroidMqttClient.kt | 1 + .../gojek/mqtt/connection/MqttConnection.kt | 10 ++++++++++ .../gojek/mqtt/model/MqttConnectOptions.kt | 12 +++++++++++ .../main/java/com/gojek/mqtt/model/Will.kt | 10 ++++++++++ 6 files changed, 63 insertions(+) create mode 100644 mqtt-client/src/main/java/com/gojek/mqtt/model/Will.kt diff --git a/app/src/main/java/com/gojek/courier/app/ui/MainActivity.kt b/app/src/main/java/com/gojek/courier/app/ui/MainActivity.kt index 2c4e524c..09ee7a9b 100644 --- a/app/src/main/java/com/gojek/courier/app/ui/MainActivity.kt +++ b/app/src/main/java/com/gojek/courier/app/ui/MainActivity.kt @@ -29,6 +29,7 @@ import com.gojek.mqtt.model.AdaptiveKeepAliveConfig import com.gojek.mqtt.model.KeepAlive import com.gojek.mqtt.model.MqttConnectOptions import com.gojek.mqtt.model.ServerUri +import com.gojek.mqtt.model.Will import com.gojek.workmanager.pingsender.WorkManagerPingSenderConfig import com.gojek.workmanager.pingsender.WorkPingSenderFactory import kotlinx.android.synthetic.main.activity_main.brokerIP @@ -122,12 +123,21 @@ class MainActivity : AppCompatActivity() { } private fun connectMqtt(clientId: String, username: String, password: String, ip: String, port: Int) { + + val will = Will( + topic = "last/will/topic", + message = "Client disconnected unexpectedly", + qos = QoS.ZERO, + retained = false + ) + val connectOptions = MqttConnectOptions.Builder() .serverUris(listOf(ServerUri(ip, port, if (port == 443) "ssl" else "tcp"))) .clientId(clientId) .userName(username) .password(password) .cleanSession(false) + .will(will) .keepAlive(KeepAlive(timeSeconds = 30)) .build() diff --git a/mqtt-client/api/mqtt-client.api b/mqtt-client/api/mqtt-client.api index 382de056..7ea6b4b6 100644 --- a/mqtt-client/api/mqtt-client.api +++ b/mqtt-client/api/mqtt-client.api @@ -1054,6 +1054,7 @@ public final class com/gojek/mqtt/model/MqttConnectOptions { public final fun getUserPropertiesMap ()Ljava/util/Map; public final fun getUsername ()Ljava/lang/String; public final fun getVersion ()Lcom/gojek/mqtt/model/MqttVersion; + public final fun getWill ()Lcom/gojek/mqtt/model/Will; public final fun getX509TrustManager ()Ljavax/net/ssl/X509TrustManager; public final fun isCleanSession ()Z public final fun newBuilder ()Lcom/gojek/mqtt/model/MqttConnectOptions$Builder; @@ -1064,6 +1065,7 @@ public final class com/gojek/mqtt/model/MqttConnectOptions$Builder { public final fun alpnProtocols (Ljava/util/List;)Lcom/gojek/mqtt/model/MqttConnectOptions$Builder; public final fun build ()Lcom/gojek/mqtt/model/MqttConnectOptions; public final fun cleanSession (Z)Lcom/gojek/mqtt/model/MqttConnectOptions$Builder; + public final fun clearWill ()Lcom/gojek/mqtt/model/MqttConnectOptions$Builder; public final fun clientId (Ljava/lang/String;)Lcom/gojek/mqtt/model/MqttConnectOptions$Builder; public final fun connectionSpec (Lorg/eclipse/paho/client/mqttv3/ConnectionSpec;)Lcom/gojek/mqtt/model/MqttConnectOptions$Builder; public final fun keepAlive (Lcom/gojek/mqtt/model/KeepAlive;)Lcom/gojek/mqtt/model/MqttConnectOptions$Builder; @@ -1075,6 +1077,7 @@ public final class com/gojek/mqtt/model/MqttConnectOptions$Builder { public final fun sslSocketFactory (Ljavax/net/ssl/SSLSocketFactory;Ljavax/net/ssl/X509TrustManager;)Lcom/gojek/mqtt/model/MqttConnectOptions$Builder; public final fun userName (Ljava/lang/String;)Lcom/gojek/mqtt/model/MqttConnectOptions$Builder; public final fun userProperties (Ljava/util/Map;)Lcom/gojek/mqtt/model/MqttConnectOptions$Builder; + public final fun will (Lcom/gojek/mqtt/model/Will;)Lcom/gojek/mqtt/model/MqttConnectOptions$Builder; } public final class com/gojek/mqtt/model/MqttConnectOptions$Companion { @@ -1103,6 +1106,23 @@ public final class com/gojek/mqtt/model/ServerUri { public fun toString ()Ljava/lang/String; } +public final class com/gojek/mqtt/model/Will { + public fun (Ljava/lang/String;Ljava/lang/String;Lcom/gojek/courier/QoS;Z)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun component3 ()Lcom/gojek/courier/QoS; + public final fun component4 ()Z + public final fun copy (Ljava/lang/String;Ljava/lang/String;Lcom/gojek/courier/QoS;Z)Lcom/gojek/mqtt/model/Will; + public static synthetic fun copy$default (Lcom/gojek/mqtt/model/Will;Ljava/lang/String;Ljava/lang/String;Lcom/gojek/courier/QoS;ZILjava/lang/Object;)Lcom/gojek/mqtt/model/Will; + public fun equals (Ljava/lang/Object;)Z + public final fun getMessage ()Ljava/lang/String; + public final fun getQos ()Lcom/gojek/courier/QoS; + public final fun getRetained ()Z + public final fun getTopic ()Ljava/lang/String; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + public final class com/gojek/mqtt/network/ActiveNetInfo { public fun (ZZS)V public final fun component1 ()Z diff --git a/mqtt-client/src/main/java/com/gojek/mqtt/client/v3/impl/AndroidMqttClient.kt b/mqtt-client/src/main/java/com/gojek/mqtt/client/v3/impl/AndroidMqttClient.kt index 0807e68a..d22ec73e 100644 --- a/mqtt-client/src/main/java/com/gojek/mqtt/client/v3/impl/AndroidMqttClient.kt +++ b/mqtt-client/src/main/java/com/gojek/mqtt/client/v3/impl/AndroidMqttClient.kt @@ -522,6 +522,7 @@ internal class AndroidMqttClient( .keepAlive(keepAliveProvider.getKeepAlive(connectOptions)) .clientId(connectOptions.clientId + ":adaptive") .cleanSession(true) + .clearWill() .build() } else { connectOptions.newBuilder() diff --git a/mqtt-client/src/main/java/com/gojek/mqtt/connection/MqttConnection.kt b/mqtt-client/src/main/java/com/gojek/mqtt/connection/MqttConnection.kt index f436c559..066be881 100644 --- a/mqtt-client/src/main/java/com/gojek/mqtt/connection/MqttConnection.kt +++ b/mqtt-client/src/main/java/com/gojek/mqtt/connection/MqttConnection.kt @@ -184,6 +184,16 @@ internal class MqttConnection( connectionSpec = mqttConnectOptions.connectionSpec alpnProtocolList = mqttConnectOptions.protocols } + + mqttConnectOptions.will?.apply { + options!!.setWill( + topic, + message.toByteArray(), + qos.value, + retained + ) + } + // Setting some connection options which we need to reset on every connect logger.d(TAG, "MQTT connecting on : " + mqtt!!.serverURI) diff --git a/mqtt-client/src/main/java/com/gojek/mqtt/model/MqttConnectOptions.kt b/mqtt-client/src/main/java/com/gojek/mqtt/model/MqttConnectOptions.kt index d90d7c12..c22c8cea 100644 --- a/mqtt-client/src/main/java/com/gojek/mqtt/model/MqttConnectOptions.kt +++ b/mqtt-client/src/main/java/com/gojek/mqtt/model/MqttConnectOptions.kt @@ -41,6 +41,8 @@ class MqttConnectOptions private constructor( val protocols: List = builder.protocols + val will: Will? = builder.will + init { if (connectionSpec.isTls.not()) { this.sslSocketFactory = null @@ -77,6 +79,7 @@ class MqttConnectOptions private constructor( internal var x509TrustManagerOrNull: X509TrustManager? = null internal var connectionSpec: ConnectionSpec = DEFAULT_CONNECTION_SPECS internal var protocols: List = emptyList() + internal var will: Will? = null internal constructor(mqttConnectOptions: MqttConnectOptions) : this() { this.serverUris = mqttConnectOptions.serverUris @@ -93,6 +96,7 @@ class MqttConnectOptions private constructor( this.x509TrustManagerOrNull = mqttConnectOptions.x509TrustManager this.connectionSpec = mqttConnectOptions.connectionSpec this.protocols = mqttConnectOptions.protocols + this.will = mqttConnectOptions.will } fun serverUris(serverUris: List) = apply { @@ -204,6 +208,14 @@ class MqttConnectOptions private constructor( this.protocols = protocols } + fun will(will: Will) = apply { + this.will = will + } + + fun clearWill() = apply { + this.will = null + } + fun build(): MqttConnectOptions = MqttConnectOptions(this) } diff --git a/mqtt-client/src/main/java/com/gojek/mqtt/model/Will.kt b/mqtt-client/src/main/java/com/gojek/mqtt/model/Will.kt new file mode 100644 index 00000000..64941247 --- /dev/null +++ b/mqtt-client/src/main/java/com/gojek/mqtt/model/Will.kt @@ -0,0 +1,10 @@ +package com.gojek.mqtt.model + +import com.gojek.courier.QoS + +data class Will( + val topic: String, + val message: String, + val qos: QoS, + val retained: Boolean +)