Skip to content

Commit 14d1458

Browse files
authored
Update Service Client Sample to Use Mqtt5 Client (#425)
* update service client to use mqtt5 * update ci and identity sample * improve logs * setup client id for mqtt5 client * setup connectProperties * more service client notes * update readme
1 parent 24e2ab3 commit 14d1458

File tree

11 files changed

+340
-26
lines changed

11 files changed

+340
-26
lines changed

.github/workflows/ci.yml

+12
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,9 @@ jobs:
245245
- name: run Shadow sample
246246
run: |
247247
python3 ./aws-iot-device-sdk-js-v2/utils/run_sample_ci.py --file ./aws-iot-device-sdk-js-v2/.github/workflows/ci_run_shadow_cfg.json
248+
- name: run Mqtt5 Shadow sample
249+
run: |
250+
python3 ./aws-iot-device-sdk-js-v2/utils/run_sample_ci.py --file ./aws-iot-device-sdk-js-v2/.github/workflows/ci_run_shadow_mqtt5_cfg.json
248251
- name: configure AWS credentials (Jobs)
249252
uses: aws-actions/configure-aws-credentials@v1
250253
with:
@@ -253,6 +256,9 @@ jobs:
253256
- name: run Jobs sample
254257
run: |
255258
python3 ./aws-iot-device-sdk-js-v2/utils/run_sample_ci.py --file ./aws-iot-device-sdk-js-v2/.github/workflows/ci_run_jobs_cfg.json
259+
- name: run Mqtt5 Jobs sample
260+
run: |
261+
python3 ./aws-iot-device-sdk-js-v2/utils/run_sample_ci.py --file ./aws-iot-device-sdk-js-v2/.github/workflows/ci_run_jobs_mqtt5_cfg.json
256262
- name: configure AWS credentials (Fleet provisioning)
257263
uses: aws-actions/configure-aws-credentials@v1
258264
with:
@@ -264,6 +270,12 @@ jobs:
264270
Sample_UUID=$(python3 -c "import uuid; print (uuid.uuid4())")
265271
python3 ./aws-iot-device-sdk-js-v2/utils/run_sample_ci.py --file ./aws-iot-device-sdk-js-v2/.github/workflows/ci_run_fleet_provisioning_cfg.json --input_uuid ${Sample_UUID}
266272
python3 ./aws-iot-device-sdk-js-v2/utils/delete_iot_thing_ci.py --thing_name "Fleet_Thing_${Sample_UUID}" --region "us-east-1"
273+
- name: run Mqtt5 Fleet Provisioning sample
274+
run: |
275+
echo "Generating UUID for IoT thing"
276+
Sample_UUID=$(python3 -c "import uuid; print (uuid.uuid4())")
277+
python3 ./aws-iot-device-sdk-js-v2/utils/run_sample_ci.py --file ./aws-iot-device-sdk-js-v2/.github/workflows/ci_run_fleet_provisioning_mqtt5_cfg.json --input_uuid ${Sample_UUID}
278+
python3 ./aws-iot-device-sdk-js-v2/utils/delete_iot_thing_ci.py --thing_name "Fleet_Thing_${Sample_UUID}" --region "us-east-1"
267279
- name: configure AWS credentials (MQTT5 PubSub)
268280
uses: aws-actions/configure-aws-credentials@v1
269281
with:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"language": "Javascript",
3+
"sample_file": "./aws-iot-device-sdk-js-v2/samples/node/fleet_provisioning",
4+
"sample_region": "us-east-1",
5+
"sample_main_class": "",
6+
"arguments": [
7+
{
8+
"name": "--endpoint",
9+
"secret": "ci/endpoint"
10+
},
11+
{
12+
"name": "--cert",
13+
"secret": "ci/FleetProvisioning/cert",
14+
"filename": "tmp_certificate.pem"
15+
},
16+
{
17+
"name": "--key",
18+
"secret": "ci/FleetProvisioning/key",
19+
"filename": "tmp_key.pem"
20+
},
21+
{
22+
"name": "--template_name",
23+
"data": "CI_FleetProvisioning_Template"
24+
},
25+
{
26+
"name": "--template_parameters",
27+
"data": "{\"SerialNumber\":\"$INPUT_UUID\"}"
28+
},
29+
{
30+
"name": "--mqtt5",
31+
"data": "true"
32+
}
33+
]
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"language": "Javascript",
3+
"sample_file": "./aws-iot-device-sdk-js-v2/samples/node/jobs",
4+
"sample_region": "us-east-1",
5+
"sample_main_class": "",
6+
"arguments": [
7+
{
8+
"name": "--endpoint",
9+
"secret": "ci/endpoint"
10+
},
11+
{
12+
"name": "--cert",
13+
"secret": "ci/Jobs/cert",
14+
"filename": "tmp_certificate.pem"
15+
},
16+
{
17+
"name": "--key",
18+
"secret": "ci/Jobs/key",
19+
"filename": "tmp_key.pem"
20+
},
21+
{
22+
"name": "--thing_name",
23+
"data": "CI_Jobs_Thing"
24+
},
25+
{
26+
"name": "--mqtt5",
27+
"data": "true"
28+
}
29+
]
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"language": "Javascript",
3+
"sample_file": "./aws-iot-device-sdk-js-v2/samples/node/shadow",
4+
"sample_region": "us-east-1",
5+
"sample_main_class": "",
6+
"arguments": [
7+
{
8+
"name": "--endpoint",
9+
"secret": "ci/endpoint"
10+
},
11+
{
12+
"name": "--cert",
13+
"secret": "ci/Shadow/cert",
14+
"filename": "tmp_certificate.pem"
15+
},
16+
{
17+
"name": "--key",
18+
"secret": "ci/Shadow/key",
19+
"filename": "tmp_key.pem"
20+
},
21+
{
22+
"name": "--thing_name",
23+
"data": "CI_Shadow_Thing"
24+
},
25+
{
26+
"name": "--is_ci",
27+
"data": "true"
28+
},
29+
{
30+
"name": "--mqtt5",
31+
"data": "true"
32+
}
33+
]
34+
}

samples/node/fleet_provisioning/README.md

+50
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,13 @@ npm install
7979
node ./index.js --endpoint <endpoint> --cert <file> --key <file> --template_name <template name> --template_parameters <template parameters>
8080
```
8181

82+
You can also run the sample with `--mqtt5` to run it with Mqtt5 Client
83+
``` sh
84+
# from the node/fleet_provisioning folder
85+
npm install
86+
node ./index.js --endpoint <endpoint> --cert <file> --key <file> --template_name <template name> --template_parameters <template parameters> --mqtt5
87+
```
88+
8289
You can also pass a Certificate Authority file (CA) if your certificate and key combination requires it:
8390

8491
``` sh
@@ -314,3 +321,46 @@ npm install
314321
node ./index.js --endpoint <endpoint> --cert <file> --key <file> --template_name <template name> --template_parameters '{\"SerialNumber\":\"1\",\"DeviceLocation\":\"Seattle\"}' --csr <path to csr file>
315322
```
316323

324+
## Service Client Notes
325+
### Differences between MQTT5 and MQTT311
326+
The service client with Mqtt5 client is almost identical to Mqtt3 one. The only difference is that you would need setup up a Mqtt5 Client and pass it to the service client.
327+
For how to setup a Mqtt5 Client, please refer to [MQTT5 User Guide](https://github.com/awslabs/aws-crt-nodejs/blob/main/MQTT5-UserGuide.md) and [MQTT5 PubSub Sample](../pub_sub_mqtt5/README.md)
328+
329+
<table>
330+
<tr>
331+
<th>Create a IoTIdentityClient with Mqtt5</th>
332+
<th>Create a IoTIdentityClient with Mqtt311</th>
333+
</tr>
334+
<tr>
335+
<td>
336+
337+
```js
338+
// Create a Mqtt5 Client
339+
config_builder = iot.AwsIotMqtt5ClientConfigBuilder.newDirectMqttBuilderWithMtlsFromPath(argv.endpoint, argv.cert, argv.key);
340+
client = new mqtt5.Mqtt5Client(config_builder.build());
341+
342+
// Create the identity client from Mqtt5 Client
343+
identity = iotidentity.IotIdentityClient.newFromMqtt5Client(client5);
344+
```
345+
346+
</td>
347+
<td>
348+
349+
```js
350+
// Create a Mqtt311 Connection from the command line data
351+
config_builder = iot.AwsIotMqttConnectionConfigBuilder.new_mtls_builder_from_path(argv.cert, argv.key);
352+
config_builder.with_client_id(argv.client_id || "test-" + Math.floor(Math.random() * 100000000));
353+
config_builder.with_endpoint(argv.endpoint);
354+
client = new mqtt.MqttClient();
355+
connection = client.new_connection(config);
356+
357+
// Create the shadow client from Mqtt311 Connection
358+
identity = new iotidentity.IotIdentityClient(connection);
359+
```
360+
361+
</td>
362+
</tr>
363+
</table>
364+
365+
### mqtt5.QoS v.s. mqtt.QoS
366+
As the service client interface is unchanged for both Mqtt3 Connection and Mqtt5 Client,the service client will use mqtt.QoS instead of mqtt5.QoS even with a Mqtt5 Client.

samples/node/fleet_provisioning/index.ts

+35-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55

66
import { mqtt, iotidentity } from 'aws-iot-device-sdk-v2';
7+
import { once } from "events"
78

89
type Args = { [index: string]: any };
910
const fs = require('fs')
@@ -229,14 +230,33 @@ async function execute_csr(identity: iotidentity.IotIdentityClient, argv: Args)
229230
async function main(argv: Args) {
230231
common_args.apply_sample_arguments(argv);
231232

232-
const connection = common_args.build_connection_from_cli_args(argv);
233+
var connection;
234+
var client5;
235+
var identity;
236+
var timer;
233237

234-
const identity = new iotidentity.IotIdentityClient(connection);
238+
console.log("Connecting...");
239+
if (argv.mqtt5) {
240+
client5 = common_args.build_mqtt5_client_from_cli_args(argv);
241+
identity = iotidentity.IotIdentityClient.newFromMqtt5Client(client5);
235242

236-
// force node to wait 60 seconds before killing itself, promises do not keep node alive
237-
const timer = setTimeout(() => { }, 60 * 1000);
243+
const connectionSuccess = once(client5, "connectionSuccess");
244+
client5.start();
245+
246+
// force node to wait 60 seconds before killing itself, promises do not keep node alive
247+
timer = setTimeout(() => { }, 60 * 1000);
248+
await connectionSuccess;
249+
console.log("Connected with Mqtt5 Client!");
250+
} else {
251+
connection = common_args.build_connection_from_cli_args(argv);
252+
identity = new iotidentity.IotIdentityClient(connection);
253+
254+
// force node to wait 60 seconds before killing itself, promises do not keep node alive
255+
timer = setTimeout(() => { }, 60 * 1000);
256+
await connection.connect()
257+
console.log("Connected with Mqtt3 Client!");
258+
}
238259

239-
await connection.connect();
240260

241261
if (argv.csr_file) {
242262
//Csr workflow
@@ -248,7 +268,16 @@ async function main(argv: Args) {
248268
await execute_register_thing(identity, token as string, argv);
249269
}
250270

251-
await connection.disconnect();
271+
console.log("Disconnecting...");
272+
if (connection) {
273+
await connection.disconnect();
274+
} else {
275+
let stopped = once(client5, "stopped");
276+
client5.stop();
277+
await stopped;
278+
client5.close();
279+
}
280+
console.log("Disconnected");
252281
// Allow node to die if the promise above resolved
253282
clearTimeout(timer);
254283
}

samples/node/jobs/README.md

+50
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,59 @@ npm install
7676
node dist/index --endpoint <endpoint> --cert <path to certificate> --key <path to private key> --thing_name <thing name>
7777
```
7878

79+
You can also pass `--mqtt5` to run the sample with Mqtt5 Client
80+
```sh
81+
npm install
82+
node dist/index --endpoint <endpoint> --cert <path to certificate> --key <path to private key> --thing_name <thing name> --mqtt5
83+
```
84+
7985
You can also pass a Certificate Authority file (CA) if your certificate and key combination requires it:
8086

8187
``` sh
8288
npm install
8389
node dist/index --endpoint <endpoint> --cert <path to certificate> --key <path to private key> --thing_name <thing name> --ca_file <path to root CA>
8490
```
91+
92+
## Service Client Notes
93+
### Differences between MQTT5 and MQTT311
94+
The service client with Mqtt5 client is almost identical to Mqtt3 one. The only difference is that you would need setup up a Mqtt5 Client and pass it to the service client.
95+
For how to setup a Mqtt5 Client, please refer to [MQTT5 User Guide](https://github.com/awslabs/aws-crt-nodejs/blob/main/MQTT5-UserGuide.md) and [MQTT5 PubSub Sample](../pub_sub_mqtt5/README.md)
96+
97+
<table>
98+
<tr>
99+
<th>Create a IotJobsClient with Mqtt5</th>
100+
<th>Create a IotJobsClient with Mqtt311</th>
101+
</tr>
102+
<tr>
103+
<td>
104+
105+
```js
106+
// Create a Mqtt5 Client
107+
config_builder = iot.AwsIotMqtt5ClientConfigBuilder.newDirectMqttBuilderWithMtlsFromPath(argv.endpoint, argv.cert, argv.key);
108+
client = new mqtt5.Mqtt5Client(config_builder.build());
109+
110+
// Create the jobs client from Mqtt5 Client
111+
jobs = iotjobs.IotJobsClient.newFromMqtt5Client(client5);
112+
```
113+
114+
</td>
115+
<td>
116+
117+
```js
118+
// Create a Mqtt311 Connection from the command line data
119+
config_builder = iot.AwsIotMqttConnectionConfigBuilder.new_mtls_builder_from_path(argv.cert, argv.key);
120+
config_builder.with_client_id(argv.client_id || "test-" + Math.floor(Math.random() * 100000000));
121+
config_builder.with_endpoint(argv.endpoint);
122+
client = new mqtt.MqttClient();
123+
connection = client.new_connection(config);
124+
125+
// Create the jobs client from Mqtt311 Connection
126+
jobs = new iotjobs.IotJobsClient(connection);
127+
```
128+
129+
</td>
130+
</tr>
131+
</table>
132+
133+
### mqtt5.QoS v.s. mqtt.QoS
134+
As the service client interface is unchanged for both Mqtt3 Connection and Mqtt5 Client,the service client will use mqtt.QoS instead of mqtt5.QoS even with a Mqtt5 Client.

samples/node/jobs/index.ts

+27-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { mqtt, iotjobs } from 'aws-iot-device-sdk-v2';
2+
import {once} from "events";
23

34
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
45

@@ -114,12 +115,26 @@ async function on_start_next_pending_job_execution_accepted(error? : iotjobs.Iot
114115
async function main(argv: Args) {
115116
common_args.apply_sample_arguments(argv);
116117

117-
const connection = common_args.build_connection_from_cli_args(argv);
118-
const jobs = new iotjobs.IotJobsClient(connection);
118+
var connection;
119+
var client5;
120+
var jobs;
119121

120122
console.log("Connecting...");
121-
await connection.connect()
122-
console.log("Connected!");
123+
if (argv.mqtt5) {
124+
client5 = common_args.build_mqtt5_client_from_cli_args(argv);
125+
jobs = iotjobs.IotJobsClient.newFromMqtt5Client(client5);
126+
127+
const connectionSuccess = once(client5, "connectionSuccess");
128+
client5.start();
129+
await connectionSuccess;
130+
console.log("Connected with Mqtt5 Client!");
131+
} else {
132+
connection = common_args.build_connection_from_cli_args(argv);
133+
jobs = new iotjobs.IotJobsClient(connection);
134+
135+
await connection.connect()
136+
console.log("Connected with Mqtt3 Client!");
137+
}
123138

124139
// Subscribe to necessary topics and get pending jobs
125140
try {
@@ -257,9 +272,14 @@ async function main(argv: Args) {
257272
}
258273

259274
console.log("Disconnecting...");
260-
await connection.disconnect();
261-
// force node to wait a second before quitting to finish any promises
262-
await sleep(1000);
275+
if (connection) {
276+
await connection.disconnect();
277+
} else {
278+
let stopped = once(client5, "stopped");
279+
client5.stop();
280+
await stopped;
281+
client5.close();
282+
}
263283
console.log("Disconnected");
264284
// Quit NodeJS
265285
process.exit(0);

0 commit comments

Comments
 (0)