Skip to content

Commit ae9b9c1

Browse files
author
Bret Ambrose
committed
Merge branch 'JsMqtt-4-EncodeDecode' into JsMqtt-5-Validation
2 parents 09d5340 + 444336a commit ae9b9c1

16 files changed

Lines changed: 324 additions & 300 deletions

lib/browser/aws_iot.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { SocketOptions } from "./io";
1414
import { MqttClientConnection, MqttConnectionConfig, MqttWill } from "./mqtt";
1515
import * as platform from "../common/platform";
1616
import * as iot_shared from "../common/aws_iot_shared"
17+
import { SDK_NAME } from "../common/mqtt_shared";
1718

1819
/**
1920
* Builder functions to create a {@link MqttConnectionConfig} which can then be used to create
@@ -328,12 +329,12 @@ export class AwsIotMqttConnectionConfigBuilder {
328329

329330
// Add the metrics string
330331
if (this.params.username == undefined || this.params.username == null || this.params.username == "") {
331-
this.params.username = "?SDK=NodeJSv2&Version="
332+
this.params.username = `?SDK=${SDK_NAME}&Version=`
332333
} else {
333334
if (this.params.username.indexOf("?") != -1) {
334-
this.params.username += "&SDK=NodeJSv2&Version="
335+
this.params.username += `&SDK=${SDK_NAME}&Version=`
335336
} else {
336-
this.params.username += "?SDK=NodeJSv2&Version="
337+
this.params.username += `?SDK=${SDK_NAME}&Version=`
337338
}
338339
}
339340
this.params.username += platform.crt_version()

lib/browser/mqtt.ts

Lines changed: 5 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import {
2525
Payload,
2626
MqttRequest,
2727
MqttSubscribeRequest,
28-
MqttWill,
2928
OnMessageCallback,
3029
MqttConnectionConnected,
3130
MqttConnectionDisconnected,
@@ -36,12 +35,13 @@ import {
3635
OnConnectionFailedResult,
3736
OnConnectionClosedResult
3837
} from "../common/mqtt";
39-
import {normalize_payload, normalize_payload_to_buffer} from "../common/mqtt_shared";
38+
import {normalize_payload, normalize_payload_to_buffer, MqttConnectionConfigBase} from "../common/mqtt_shared";
4039

4140
export {
4241
QoS, Payload, MqttRequest, MqttSubscribeRequest, MqttWill, OnMessageCallback, MqttConnectionConnected, MqttConnectionDisconnected,
4342
MqttConnectionResumed, OnConnectionSuccessResult, OnConnectionFailedResult, OnConnectionClosedResult
4443
} from "../common/mqtt";
44+
export { MqttConnectionConfigBase } from "../common/mqtt_shared";
4545

4646
/**
4747
* Listener signature for event emitted from an {@link MqttClientConnection} when an error occurs
@@ -110,88 +110,14 @@ export type AWSCredentials = auth.AWSCredentials;
110110
/**
111111
* Configuration options for an MQTT connection
112112
*
113+
* Extends {@link MqttConnectionConfigBase} with browser-specific options.
114+
*
113115
* @category MQTT
114116
*/
115-
export interface MqttConnectionConfig {
116-
/**
117-
* ID to place in CONNECT packet. Must be unique across all devices/clients.
118-
* If an ID is already in use, the other client will be disconnected.
119-
*/
120-
client_id: string;
121-
122-
/** Server name to connect to */
123-
host_name: string;
124-
125-
/** Server port to connect to */
126-
port: number;
127-
117+
export interface MqttConnectionConfig extends MqttConnectionConfigBase {
128118
/** Socket options, ignored in browser */
129119
socket_options: SocketOptions;
130120

131-
/**
132-
* Whether or not to start a clean session with each reconnect.
133-
* If True, the server will forget all subscriptions with each reconnect.
134-
* Set False to request that the server resume an existing session
135-
* or start a new session that may be resumed after a connection loss.
136-
* The `session_present` bool in the connection callback informs
137-
* whether an existing session was successfully resumed.
138-
* If an existing session is resumed, the server remembers previous subscriptions
139-
* and sends messages (with QoS1 or higher) that were published while the client was offline.
140-
*/
141-
clean_session?: boolean;
142-
143-
/**
144-
* The keep alive value, in seconds, to send in CONNECT packet.
145-
* A PING will automatically be sent at this interval.
146-
* The server will assume the connection is lost if no PING is received after 1.5X this value.
147-
* This duration must be longer than {@link ping_timeout}.
148-
*/
149-
keep_alive?: number;
150-
151-
/**
152-
* Milliseconds to wait for ping response before client assumes
153-
* the connection is invalid and attempts to reconnect.
154-
* This duration must be shorter than keep_alive_secs.
155-
* Alternatively, TCP keep-alive via :attr:`SocketOptions.keep_alive`
156-
* may accomplish this in a more efficient (low-power) scenario,
157-
* but keep-alive options may not work the same way on every platform and OS version.
158-
*/
159-
ping_timeout?: number;
160-
161-
/**
162-
* Milliseconds to wait for the response to the operation requires response by protocol.
163-
* Set to zero to disable timeout. Otherwise, the operation will fail if no response is
164-
* received within this amount of time after the packet is written to the socket.
165-
* It applied to PUBLISH (QoS>0) and UNSUBSCRIBE now.
166-
*/
167-
protocol_operation_timeout?: number;
168-
169-
/**
170-
* Minimum seconds to wait between reconnect attempts.
171-
* Must be <= {@link reconnect_max_sec}.
172-
* Wait starts at min and doubles with each attempt until max is reached.
173-
*/
174-
reconnect_min_sec?: number;
175-
176-
/**
177-
* Maximum seconds to wait between reconnect attempts.
178-
* Must be >= {@link reconnect_min_sec}.
179-
* Wait starts at min and doubles with each attempt until max is reached.
180-
*/
181-
reconnect_max_sec?: number;
182-
183-
/**
184-
* Will to send with CONNECT packet. The will is
185-
* published by the server when its connection to the client is unexpectedly lost.
186-
*/
187-
will?: MqttWill;
188-
189-
/** Username to connect with */
190-
username?: string;
191-
192-
/** Password to connect with */
193-
password?: string;
194-
195121
/** Options for the underlying websocket connection */
196122
websocket?: WebsocketOptions;
197123

lib/browser/mqtt5.ts

Lines changed: 4 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import * as auth from "./auth";
2525

2626
export * from "../common/mqtt5";
2727
export * from '../common/mqtt5_packet';
28+
export { Mqtt5ClientConfigBase } from "../common/mqtt_shared";
2829

2930
/**
3031
* Factory function that allows the user to completely control the url used to form the websocket handshake
@@ -124,66 +125,16 @@ export interface Mqtt5WebsocketConfig {
124125
/**
125126
* Configuration options for mqtt5 client creation.
126127
*/
127-
export interface Mqtt5ClientConfig {
128-
129-
/**
130-
* Host name of the MQTT server to connect to.
131-
*/
132-
hostName: string;
133-
134-
/**
135-
* Network port of the MQTT server to connect to.
136-
*/
137-
port: number;
138-
139-
/**
140-
* Controls how the MQTT5 client should behave with respect to MQTT sessions.
141-
*/
142-
sessionBehavior? : mqtt5.ClientSessionBehavior;
143-
144-
/**
145-
* Controls how the reconnect delay is modified in order to smooth out the distribution of reconnection attempt
146-
* timepoints for a large set of reconnecting clients.
147-
*/
148-
retryJitterMode? : mqtt5.RetryJitterType;
149-
150-
/**
151-
* Minimum amount of time to wait to reconnect after a disconnect. Exponential backoff is performed with jitter
152-
* after each connection failure.
153-
*/
154-
minReconnectDelayMs? : number;
155-
156-
/**
157-
* Maximum amount of time to wait to reconnect after a disconnect. Exponential backoff is performed with jitter
158-
* after each connection failure.
159-
*/
160-
maxReconnectDelayMs? : number;
161-
162-
/**
163-
* Amount of time that must elapse with an established connection before the reconnect delay is reset to the minimum.
164-
* This helps alleviate bandwidth-waste in fast reconnect cycles due to permission failures on operations.
165-
*/
166-
minConnectedTimeToResetReconnectDelayMs? : number;
167-
168-
/**
169-
* All configurable options with respect to the CONNECT packet sent by the client, including the will. These
170-
* connect properties will be used for every connection attempt made by the client.
171-
*/
172-
connectProperties?: mqtt5_packet.ConnectPacket;
128+
export interface Mqtt5ClientConfig extends mqtt_shared.Mqtt5ClientConfigBase {
173129

174130
/**
175131
* Overall time interval to wait to establish an MQTT connection. If a complete MQTT connection (from socket
176132
* establishment all the way up to CONNACK receipt) has not been established before this timeout expires,
177133
* the connection attempt will be considered a failure.
178-
*/
179-
connectTimeoutMs? : number;
180-
181-
/**
182-
* Additional controls for client behavior with respect to topic alias usage.
183134
*
184-
* If this setting is left undefined, then topic aliasing behavior will be disabled.
135+
* @group Browser-only
185136
*/
186-
topicAliasingOptions? : mqtt5.TopicAliasingOptions
137+
connectTimeoutMs? : number;
187138

188139
/**
189140
* Options for the underlying websocket connection

lib/common/aws_iot_shared.spec.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,36 @@
44
*/
55

66
import * as iot_shared from "./aws_iot_shared";
7+
import { SDK_NAME } from "./mqtt_shared";
78

89
jest.setTimeout(10000);
910

1011
test('Aws IoT Mqtt5 Username Construction - No Custom Auth', async () => {
1112
let finalUsername : string = iot_shared.buildMqtt5FinalUsername(undefined);
1213

13-
expect(finalUsername).toEqual(expect.stringContaining("?SDK=NodeJSv2&Version="));
14+
expect(finalUsername).toEqual(expect.stringContaining(`?SDK=${SDK_NAME}&Version=`));
1415
});
1516

1617
test('Aws IoT Mqtt5 Username Construction - Empty custom auth', async () => {
1718
let finalUsername : string = iot_shared.buildMqtt5FinalUsername({});
1819

19-
expect(finalUsername).toEqual(expect.stringContaining("?SDK=NodeJSv2&Version="));
20+
expect(finalUsername).toEqual(expect.stringContaining(`?SDK=${SDK_NAME}&Version=`));
2021
});
2122

22-
2323
test('Aws IoT Mqtt5 Username Construction - Simple username', async () => {
2424
let finalUsername : string = iot_shared.buildMqtt5FinalUsername({
2525
username: "Derp"
2626
});
2727

28-
expect(finalUsername).toEqual(expect.stringContaining("Derp?SDK=NodeJSv2&Version="));
28+
expect(finalUsername).toEqual(expect.stringContaining(`Derp?SDK=${SDK_NAME}&Version=`));
2929
});
3030

3131
test('Aws IoT Mqtt5 Username Construction - Query param username', async () => {
3232
let finalUsername : string = iot_shared.buildMqtt5FinalUsername({
3333
username: "Derp?Param1=Value1"
3434
});
3535

36-
expect(finalUsername).toEqual(expect.stringContaining("Derp?Param1=Value1&SDK=NodeJSv2&Version="));
36+
expect(finalUsername).toEqual(expect.stringContaining(`Derp?Param1=Value1&SDK=${SDK_NAME}&Version=`));
3737
});
3838

3939
test('Aws IoT Mqtt5 Username Construction - Authorizer Name', async () => {
@@ -42,7 +42,7 @@ test('Aws IoT Mqtt5 Username Construction - Authorizer Name', async () => {
4242
authorizerName: "MyAuthorizer"
4343
});
4444

45-
expect(finalUsername).toEqual(expect.stringContaining("Hello?x-amz-customauthorizer-name=MyAuthorizer&SDK=NodeJSv2&Version="));
45+
expect(finalUsername).toEqual(expect.stringContaining(`Hello?x-amz-customauthorizer-name=MyAuthorizer&SDK=${SDK_NAME}&Version=`));
4646
});
4747

4848
test('Aws IoT Mqtt5 Username Construction - Token Signing', async () => {
@@ -54,7 +54,7 @@ test('Aws IoT Mqtt5 Username Construction - Token Signing', async () => {
5454
tokenSignature: "SignedToken"
5555
});
5656

57-
expect(finalUsername).toEqual(expect.stringContaining("Hello?x-amz-customauthorizer-name=MyAuthorizer&MyToken=TheToken&x-amz-customauthorizer-signature=SignedToken&SDK=NodeJSv2&Version="));
57+
expect(finalUsername).toEqual(expect.stringContaining(`Hello?x-amz-customauthorizer-name=MyAuthorizer&MyToken=TheToken&x-amz-customauthorizer-signature=SignedToken&SDK=${SDK_NAME}&Version=`));
5858
});
5959

6060
test('Aws IoT Mqtt5 Username Construction Failure - Missing token key name', async () => {

lib/common/aws_iot_shared.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import * as platform from "./platform";
1616
import * as mqtt5_packet from "./mqtt5_packet";
1717
import * as utils from "./utils";
18+
import { SDK_NAME } from "./mqtt_shared";
1819

1920
/**
2021
* A helper function to add parameters to the username in with_custom_authorizer function
@@ -204,7 +205,7 @@ function addParam(paramName: string, paramValue: string | undefined, paramSet: [
204205
*
205206
* @internal
206207
*/
207-
export function buildMqtt5FinalUsername(customAuthConfig?: MqttConnectCustomAuthConfig) : string {
208+
export function buildMqtt5FinalUsername(customAuthConfig?: MqttConnectCustomAuthConfig): string {
208209

209210
let path : string = "";
210211
let paramList : [string, string][] = [];
@@ -241,7 +242,7 @@ export function buildMqtt5FinalUsername(customAuthConfig?: MqttConnectCustomAuth
241242
}
242243
}
243244

244-
paramList.push(["SDK", "NodeJSv2"]);
245+
paramList.push(["SDK", SDK_NAME]);
245246
paramList.push(["Version", platform.crt_version()]);
246247

247248
return (path ?? "") + "?" + paramList.map((value : [string, string]) => `${value[0]}=${value[1]}`).join("&");

lib/common/mqtt.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,4 +197,4 @@ export const DEFAULT_RECONNECT_MAX_SEC = 128;
197197
*
198198
* @category MQTT
199199
*/
200-
export const DEFAULT_RECONNECT_MIN_SEC = 1;
200+
export const DEFAULT_RECONNECT_MIN_SEC = 1;

0 commit comments

Comments
 (0)