|
| 1 | +# MQTT External Object |
| 2 | + |
| 3 | +This repository holds the implementation of a GeneXus [External Object](https://wiki.genexus.com/commwiki/servlet/wiki?6148) that allows you to include MQTT events in your Knowledge Base. |
| 4 | + |
| 5 | +=== This implementation is only for the Java generator === |
| 6 | + |
| 7 | +## How to use it |
| 8 | + |
| 9 | +First, add to the Knowledge Base the dependencies needed for the external object, provided in the [assets](./assets/) folder of this repository. Unzip the [MQTTLib.zip](./assets/MQTTLib.zip) file and add the two contained files (`genexus-mqtt-*.jar`, `eclipse-paho-mqttv3-1.2.5.jar`) into your Knowledge Base. Make sure you set the property [Extract for Java Generator](https://wiki.genexus.com/commwiki/servlet/wiki?39499,Extract+for+Java+Generator+property) to **True** for all of these files. |
| 10 | + |
| 11 | +In order to be able to import the external object, you need to add both jar files to your [classpath property](https://wiki.genexus.com/commwiki/servlet/wiki?9248,Classpath+property,). |
| 12 | + |
| 13 | +You also need to import the [MQTT_EXO.xpz](./assets/MQTT_EXO.xpz) file provided in this repository. This will import 3 different External Objects and a Domain. |
| 14 | + |
| 15 | +The MQTT External Object is the one holds the method for publishing and subscribing to MQTT events. |
| 16 | + |
| 17 | + |
| 18 | + |
| 19 | +The implementation is based on [Eclipse Paho](https://www.eclipse.org/paho/index.php?page=clients/java/index.php), *"an MQTT client library written in Java for developing applications."* |
| 20 | + |
| 21 | +### Connecting to an MQTT broker |
| 22 | + |
| 23 | +The first thing you need to do, either for publishing or subscribing is to connect to the desired broker. |
| 24 | + |
| 25 | +```genexus |
| 26 | +&mqttStatus = MQTT.Connect(&url, &mqttConfig) |
| 27 | +``` |
| 28 | + |
| 29 | +Where `&url` is the URL of the broker and `&mqttConfig` is an instance of the also provided `MqttConfig` External Object. |
| 30 | +The `MqttConfig` External Object has the needed properties to connect to your broker, whether you're using user and password or a certificate. Here are the properties that hold a default value. |
| 31 | + |
| 32 | +Name|Default value |
| 33 | +---|--- |
| 34 | +Port|1883 |
| 35 | +KeepAlive|0 |
| 36 | +ConnectionTimeout|5 |
| 37 | +MQTTConnectionName|mqtt_connection1 |
| 38 | +SSLConnection|false |
| 39 | +ProtocolVersion|0 |
| 40 | +CleanSession|true |
| 41 | +AllowWildcardsInTopicFilters|false |
| 42 | +AutoReconnectDelay|5 |
| 43 | +SessionExpiryInterval|0 |
| 44 | + |
| 45 | + |
| 46 | + |
| 47 | +### Publishing messages |
| 48 | + |
| 49 | +The publish method receives a GUID, which is the Key of the `MqttStatus` after connecting, a topic, the message itself, the [Quality of Service](https://assetwolf.com/learn/mqtt-qos-understanding-quality-of-service) (there's a domain called MqttQoS), a boolean indicating if the message should be retained and a numeric stating the expiry of the message (in seconds) |
| 50 | + |
| 51 | +```genexus |
| 52 | +&mqttStatus = MQTT.Publish(&mqttguid,&topic, &message, MqttQoS.AtMostOnce, true,30) |
| 53 | +``` |
| 54 | + |
| 55 | +Again, you'll get an instance of `MqttStatus` where you can check if everything went well. |
| 56 | + |
| 57 | +### Subscribing to topics |
| 58 | + |
| 59 | +To subscribe you need to call the Subscribe method which also receives the GUID of the connection, the topic you wish to subscribe to, the name of the Procedure that will be called once a message arrives, and again, the Quality of Service. |
| 60 | + |
| 61 | +```genexus |
| 62 | +&mqttStatus = MQTT.Subscribe(&mqttguid,&topic,"SaveMessage",MqttQoS.AtLeastOnce) |
| 63 | +``` |
| 64 | + |
| 65 | +The GeneXus procedure to be called when a message arrives must comply with the following requirements. |
| 66 | +1) Its [Main program property](https://wiki.genexus.com/commwiki/servlet/wiki?7407) must be set to **True** |
| 67 | +2) The parm rule must be exactly as follows. First, a Varchar that will be the topic, the second parameter (also Varchar) will be the message body itself, and a third parameter (DateTime) that's the timestamp when the message was received by the client. This DateTime is generated on the subscriber. |
| 68 | + |
| 69 | +```genexus |
| 70 | +parm(in:&topic,in:&message,in:&dateTime); |
| 71 | +``` |
| 72 | + |
| 73 | +Once a message for the subscribed topic is received, the Procedure will be called asynchronously. You will not have a status back from the execution unless you write the code yourself in your procedure. |
| 74 | + |
| 75 | +### Unsubscribing |
| 76 | + |
| 77 | +You can also unsubscribe from a specific topic. All you need is the GUID of the connection and the topic you wish to unsubscribe to. |
| 78 | + |
| 79 | +```genexus |
| 80 | +&mqttStatus = MQTT.Unsubscribe(&mqttguid,&topic) |
| 81 | +``` |
| 82 | + |
| 83 | +### Disconnecting |
| 84 | + |
| 85 | +To disconnect an established connection all you have to do is sending the connection GUID. |
| 86 | + |
| 87 | +```genexus |
| 88 | +&mqttStatus = MQTT.Disconnect(&mqttguid) |
| 89 | +``` |
| 90 | + |
| 91 | +There's also an `IsConnected` method that receives the GUID of the connection and a Boolean as an out parameter that will hold whether the connection is active or not. |
| 92 | + |
| 93 | +```genexus |
| 94 | +&mqttStatus = MQTT.IsConnected(&mqttguid,&connected) |
| 95 | +``` |
| 96 | + |
| 97 | +In every case, the returned `&mqttStatus` is an instance of the `MqttStatus` External Object that holds a `Key` (GUID), an `Error` (Boolean) and an `ErrorMessage` (VarChar) in case Error is True. |
| 98 | + |
| 99 | + |
| 100 | + |
| 101 | + |
| 102 | +## Testing |
| 103 | + |
| 104 | +There are a couple of unit tests that can be used for testing purposes. If you wish to test the implementation in your favourite Java IDE, make sure you copy from your GeneXus installation the gxclassR.jar, gxcommon.jar, gxwrapperjavax.jar, and gxwrappercommon.jar files to the [lib](./MQTTLib/lib) folder. |
| 105 | + |
| 106 | +Also, there's an application called [MQTT Box](https://www.microsoft.com/en-us/p/mqttbox/9nblggh55jzg) which you can install from the Windows Store to test your solution. |
| 107 | + |
| 108 | +## Running the client from a command line procedure |
| 109 | + |
| 110 | +When using the MQTT client from a command line main procedure, the JVM will not end until all MQTT clients are disconnected. If you run your command line procedure and it never finishes, double check if you are leaving open connections to the MQTT server. |
| 111 | + |
| 112 | +## Broker compatibility / support |
| 113 | + |
| 114 | +Depending on the broker used, some specific configurations may be done. |
| 115 | + |
| 116 | + |
| 117 | +### Connecting to a AWS IoT Core broker |
| 118 | + |
| 119 | +When connecting to an [AWS Iot Core](https://docs.aws.amazon.com/iot/latest/developerguide/mqtt.html) broker, some considerations should be taken into account: |
| 120 | + |
| 121 | +- Only [MQTT 3.1.1](https://docs.aws.amazon.com/iot/latest/developerguide/mqtt.html) version is supported. |
| 122 | +- The [port for connection](https://docs.aws.amazon.com/iot/latest/developerguide/protocols.html) is 8883, using SSL. |
| 123 | +- When connecting the AWS broker, a CA certificate, a client certificate, and a client private key must be obtained from AWS and provided in the `MqttConfig` options. |
| 124 | +- Only [QoS levels 0 and 1](https://docs.aws.amazon.com/iot/latest/developerguide/mqtt.html#mqtt-qos) are supported. |
| 125 | +- Many times an action (connect, publish, subscribe) is rejected because of missing permissions in the AWS policies related to the thing or the authenticated role. |
0 commit comments