Skip to content

Commit 3ac4f8a

Browse files
authored
Implements MQTT java Implementation (#2)
* Implements MQTT java Implementation * Remove Java assets and .Net xpz
1 parent 9f1d8ed commit 3ac4f8a

32 files changed

+1104
-0
lines changed

java/README.md

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
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+
![](./res/MQTT_Exo.png)
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+
![](./res/MqttConfig.png)
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+
![](./res/MqttStatus.png)
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.

java/pom.xml

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
6+
<modelVersion>4.0.0</modelVersion>
7+
8+
<artifactId>mqttjavaexo</artifactId>
9+
<groupId>com.genexus</groupId>
10+
<version>1.0-SNAPSHOT</version>
11+
12+
<properties>
13+
<maven.compiler.source>15</maven.compiler.source>
14+
<maven.compiler.target>15</maven.compiler.target>
15+
<junit.version>4.13.1</junit.version>
16+
<log4j.version>2.17.1</log4j.version>
17+
<paho.version>1.2.5</paho.version>
18+
<jar.version>3.2.0</jar.version>
19+
</properties>
20+
21+
<dependencies>
22+
<dependency>
23+
<groupId>junit</groupId>
24+
<artifactId>junit</artifactId>
25+
<version>${junit.version}</version>
26+
<scope>test</scope>
27+
</dependency>
28+
<dependency>
29+
<groupId>org.apache.logging.log4j</groupId>
30+
<artifactId>log4j-core</artifactId>
31+
<version>${log4j.version}</version>
32+
</dependency>
33+
<dependency>
34+
<groupId>org.eclipse.paho</groupId>
35+
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
36+
<version>${paho.version}</version>
37+
</dependency>
38+
<dependency>
39+
<groupId>commons-codec</groupId>
40+
<artifactId>commons-codec</artifactId>
41+
<version>1.15</version>
42+
</dependency>
43+
<dependency>
44+
<groupId>org.bouncycastle</groupId>
45+
<artifactId>bcpkix-jdk15on</artifactId>
46+
<version>1.70</version>
47+
</dependency>
48+
<dependency>
49+
<groupId>org.bouncycastle</groupId>
50+
<artifactId>bcprov-jdk15on</artifactId>
51+
<version>1.70</version>
52+
</dependency>
53+
<dependency>
54+
<groupId>org.json</groupId>
55+
<artifactId>json</artifactId>
56+
<version>20211205</version>
57+
</dependency>
58+
<dependency>
59+
<groupId>com.fasterxml.jackson.core</groupId>
60+
<artifactId>jackson-databind</artifactId>
61+
<version>2.10.4</version>
62+
</dependency>
63+
<dependency>
64+
<groupId>${project.groupId}</groupId>
65+
<artifactId>gxclassR</artifactId>
66+
<version>2.6-SNAPSHOT</version>
67+
</dependency>
68+
<dependency>
69+
<groupId>${project.groupId}</groupId>
70+
<artifactId>gxcommon</artifactId>
71+
<version>2.6-SNAPSHOT</version>
72+
</dependency>
73+
<dependency>
74+
<groupId>${project.groupId}</groupId>
75+
<artifactId>gxwrapperjavax</artifactId>
76+
<version>2.6-SNAPSHOT</version>
77+
</dependency>
78+
<dependency>
79+
<groupId>${project.groupId}</groupId>
80+
<artifactId>gxwrappercommon</artifactId>
81+
<version>2.6-SNAPSHOT</version>
82+
</dependency>
83+
</dependencies>
84+
85+
<build>
86+
87+
<plugins>
88+
89+
<plugin>
90+
<groupId>org.apache.maven.plugins</groupId>
91+
<artifactId>maven-jar-plugin</artifactId>
92+
<version>${jar.version}</version>
93+
<configuration>
94+
<!-- DO NOT include log4j2.xml file in your Jar -->
95+
<excludes>
96+
<exclude>**/log4j2.xml</exclude>
97+
</excludes>
98+
<archive>
99+
</archive>
100+
</configuration>
101+
</plugin>
102+
<plugin>
103+
<groupId>org.apache.maven.plugins</groupId>
104+
<artifactId>maven-compiler-plugin</artifactId>
105+
<configuration>
106+
<source>7</source>
107+
<target>7</target>
108+
</configuration>
109+
</plugin>
110+
111+
</plugins>
112+
</build>
113+
114+
</project>

0 commit comments

Comments
 (0)