Skip to content

Commit 8ba2dee

Browse files
committed
Version 1.0.10. Fixes issue #30, incorporates pull requests #28 and #29.
1 parent 45e6098 commit 8ba2dee

File tree

14 files changed

+947
-478
lines changed

14 files changed

+947
-478
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
## [1.0.10](https://github.com/aws/aws-iot-device-sdk-js/releases/tag/v1.0.10) (January 28, 2016)
2+
3+
Features:
4+
- Added support for WebSocket connections to AWS IoT
5+
6+
Bugfixes/Improvements
7+
- Incorporated github pull requests [#28](https://github.com/aws/aws-iot-device-sdk-js/pull/28) and [#29](https://github.com/aws/aws-iot-device-sdk-js/pull/29)
8+
- Fixes for github issues [#30](https://github.com/aws/aws-iot-device-sdk-js/issues/30)
9+
- Added unit tests to release
10+
- Updated documentation
11+
112
## [1.0.7](https://github.com/aws/aws-iot-device-sdk-js/releases/tag/v1.0.7) (October 30, 2015)
213

314
Bugfixes/Improvements:

README.md

Lines changed: 116 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# AWS IoT SDK for JavaScript
1+
# AWS IoT SDK for Node.js
22
The aws-iot-device-sdk.js package allows developers to write JavaScript
33
applications which access the AWS IoT Platform; it is intended for use in
44
embedded devices which support Node.js, but it can be used in other Node.js
@@ -8,8 +8,10 @@ environments as well.
88
* [Installation](#install)
99
* [Examples](#examples)
1010
* [API Documentation](#api)
11+
* [Connection Types](#connections)
1112
* [Example Programs](#programs)
1213
* [Troubleshooting](#troubleshooting)
14+
* [Unit Tests](#unittests)
1315
* [License](#license)
1416
* [Support](#support)
1517

@@ -19,9 +21,9 @@ This document provides instructions on how to install and configure the AWS
1921
IoT device SDK for Node.js and includes examples demonstrating use of the
2022
SDK APIs.
2123

22-
### MQTT connection
24+
### MQTT Connection
2325
This package is built on top of [mqtt.js](https://github.com/mqttjs/MQTT.js/blob/master/README.md) and provides two classes: 'device'
24-
and 'thingShadow'. The 'device' class loosely wraps [mqtt.js](https://github.com/mqttjs/MQTT.js/blob/master/README.md) to provide a
26+
and 'thingShadow'. The 'device' class wraps [mqtt.js](https://github.com/mqttjs/MQTT.js/blob/master/README.md) to provide a
2527
secure connection to the AWS IoT platform and expose the [mqtt.js](https://github.com/mqttjs/MQTT.js/blob/master/README.md) interfaces
2628
upward via an instance of the mqtt client.
2729

@@ -98,14 +100,16 @@ var thingShadows = awsIot.thingShadow({
98100
});
99101

100102
//
101-
// Thing shadow state
103+
// Client token value returned from thingShadows.update() operation
102104
//
103-
var rgbLedLampState = {"state":{"desired":{"red":187,"green":114,"blue":222}}};
105+
var clientTokenUpdate;
104106

105107
//
106-
// Client token value returned from thingShadows.update() operation
108+
// Simulated device values
107109
//
108-
var clientTokenUpdate;
110+
var rval = 187;
111+
var gval = 114;
112+
var bval = 222;
109113

110114
thingShadows.on('connect', function() {
111115
//
@@ -114,7 +118,7 @@ thingShadows.on('connect', function() {
114118
//
115119
thingShadows.register( 'RGBLedLamp' );
116120
//
117-
// 2 seconds after registering, update the Thing Shadow named
121+
// 5 seconds after registering, update the Thing Shadow named
118122
// 'RGBLedLamp' with the latest device state and save the clientToken
119123
// so that we can correlate it with status or timeout events.
120124
//
@@ -124,27 +128,58 @@ thingShadows.on('connect', function() {
124128
// method for more details.
125129
//
126130
setTimeout( function() {
131+
//
132+
// Thing shadow state
133+
//
134+
var rgbLedLampState = {"state":{"desired":{"red":rval,"green":gval,"blue":bval}}};
135+
127136
clientTokenUpdate = thingShadows.update('RGBLedLamp', rgbLedLampState );
128-
}, 2000 );
137+
//
138+
// The update method returns a clientToken; if non-null, this value will
139+
// be sent in a 'status' event when the operation completes, allowing you
140+
// to know whether or not the update was successful. If the update method
141+
// returns null, it's because another operation is currently in progress and
142+
// you'll need to wait until it completes (or times out) before updating the
143+
// shadow.
144+
//
145+
if (clientTokenUpdate === null)
146+
{
147+
console.log('update shadow failed, operation still in progress');
148+
}
149+
}, 5000 );
129150
});
130151

131152
thingShadows.on('status',
132153
function(thingName, stat, clientToken, stateObject) {
133154
console.log('received '+stat+' on '+thingName+': '+
134155
JSON.stringify(stateObject));
156+
//
157+
// These events report the status of update(), get(), and delete()
158+
// calls. The clientToken value associated with the event will have
159+
// the same value which was returned in an earlier call to get(),
160+
// update(), or delete(). Use status events to keep track of the
161+
// status of shadow operations.
162+
//
135163
});
136164

137165
thingShadows.on('delta',
138166
function(thingName, stateObject) {
139-
console.log('received delta '+' on '+thingName+': '+
167+
console.log('received delta on '+thingName+': '+
140168
JSON.stringify(stateObject));
141169
});
142170

143171
thingShadows.on('timeout',
144172
function(thingName, clientToken) {
145-
console.log('received timeout '+' on '+operation+': '+
146-
clientToken);
173+
console.log('received timeout on '+thingName+
174+
' with token: '+ clientToken);
175+
//
176+
// In the event that a shadow operation times out, you'll receive
177+
// one of these events. The clientToken value associated with the
178+
// event will have the same value which was returned in an earlier
179+
// call to get(), update(), or delete().
180+
//
147181
});
182+
148183
```
149184

150185
<a name="api"></a>
@@ -168,7 +203,7 @@ thingShadows.on('timeout',
168203

169204
Returns an instance of the [mqtt.Client()](https://github.com/mqttjs/MQTT.js/blob/master/README.md#client)
170205
class, configured for a TLS connection with the AWS IoT platform and with
171-
arguments as specified in `options`. The awsIot-specific arguments are as
206+
arguments as specified in `options`. The AWSIoT-specific arguments are as
172207
follows:
173208

174209
* `region`: the AWS IoT region you will operate in (default 'us-east-1')
@@ -179,6 +214,7 @@ follows:
179214
* `clientCert`: same as `certPath`, but can also accept a buffer containing client certificate data
180215
* `privateKey`: same as `keyPath`, but can also accept a buffer containing private key data
181216
* `caCert`: same as `caPath`, but can also accept a buffer containing CA certificate data
217+
* `protocol`: the connection type, either 'mqtts' (default) or 'wss' (WebSocket/TLS)
182218

183219
All certificates and keys must be in PEM format.
184220

@@ -302,7 +338,8 @@ the `clientToken` will be supplied as one of the parameters, allowing the
302338
application to keep track of the status of each operation. The caller may
303339
create their own `clientToken` value; if `stateObject` contains a `clientToken`
304340
property, that will be used rather than the internally generated value. Note
305-
that it should be of atomic type (i.e. numeric or string).
341+
that it should be of atomic type (i.e. numeric or string). This function
342+
returns 'null' if an operation is already in progress.
306343

307344
-------------------------------------------------------
308345
<a name="get"></a>
@@ -319,7 +356,8 @@ the `clientToken` will be supplied as one of the parameters, allowing the
319356
application to keep track of the status of each operation. The caller may
320357
supply their own `clientToken` value (optional); if supplied, the value of
321358
`clientToken` will be used rather than the internally generated value. Note
322-
that this value should be of atomic type (i.e. numeric or string).
359+
that this value should be of atomic type (i.e. numeric or string). This
360+
function returns 'null' if an operation is already in progress.
323361

324362
-------------------------------------------------------
325363
<a name="delete"></a>
@@ -336,7 +374,8 @@ the `clientToken` will be supplied as one of the parameters, allowing the
336374
application to keep track of the status of each operation. The caller may
337375
supply their own `clientToken` value (optional); if supplied, the value of
338376
`clientToken` will be used rather than the internally generated value. Note
339-
that this value should be of atomic type (i.e. numeric or string).
377+
that this value should be of atomic type (i.e. numeric or string). This
378+
function returns 'null' if an operation is already in progress.
340379

341380
-------------------------------------------------------
342381
<a name="publish"></a>
@@ -374,6 +413,18 @@ method on the MQTT connection owned by the `thingShadow` class. The `force`
374413
and `callback` parameters are optional and identical in function to the
375414
parameters in the [mqtt.Client#end()](https://github.com/mqttjs/MQTT.js/blob/master/README.md#end) method.
376415

416+
<a name="connections"></a>
417+
## Connection Types
418+
419+
This SDK supports two types of connections to the AWS IoT platform:
420+
421+
* MQTT over TLS with mutual certificate authentication using port 8883
422+
* MQTT over WebSocket/TLS with SigV4 authentication using port 443
423+
424+
The default connection type is MQTT over TLS with mutual certificate authentication; to
425+
configure a WebSocket/TLS connection, set the `protocol` option to `wss` when instantiating
426+
the [awsIot.device()](#device) or [awsIot.thingShadow()](#thingShadow) classes.
427+
377428
<a name="programs"></a>
378429
## Example Programs
379430

@@ -404,11 +455,34 @@ follows:
404455
```sh
405456
node examples/<EXAMPLE-PROGRAM> -h
406457
```
458+
<a name="websockets"></a>
459+
### WebSocket Configuration
460+
461+
The example programs can be configured to use a WebSocket/TLS connection to
462+
the AWS IoT platform by adding '--protocol=wss' to the command line to
463+
override the default setting of 'mqtts'.
464+
465+
```sh
466+
-P, --protocol=PROTOCOL connect using PROTOCOL (mqtts|wss)
467+
```
468+
469+
When using a WebSocket/TLS connection, you'll need to set the following environment
470+
variables:
471+
472+
```sh
473+
export AWS_ACCESS_KEY_ID=[a valid AWS access key ID]
474+
export AWS_SECRET_ACCESS_KEY=[a valid AWS secret access key]
475+
```
476+
477+
The values of `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` must contain valid
478+
AWS Identity and Access Management (IAM) credentials. For more information about AWS
479+
IAM, [visit the AWS IAM home page.](https://aws.amazon.com/iam/)
407480

408481
<a name="certificates"></a>
409-
### Certificates
482+
### Certificate Configuration
410483

411-
The example programs require certificates (created using either the [AWS
484+
When not configured to use a WebSocket/TLS connection, the example programs
485+
require a client certificate and private key (created using either the [AWS
412486
IoT Console](https://console.aws.amazon.com/iot) or the
413487
[AWS IoT CLI](https://aws.amazon.com/cli/)) in order to authenticate with
414488
AWS IoT. Each example program uses command line options to specify the
@@ -420,8 +494,8 @@ names and/or locations of certificates as follows:
420494
-f, --certificate-dir=DIR look in DIR for certificates
421495
```
422496

423-
The --certificate-dir (-f) option will read all certificates from the
424-
directory specified. Default certificate names are as follows:
497+
The --certificate-dir (-f) option will read all certificate and key files from the
498+
directory specified. Default certificate/key file names are as follows:
425499

426500
* certificate.pem.crt: your AWS IoT certificate
427501
* private.pem.key: the private key associated with your AWS IoT certificate
@@ -456,7 +530,7 @@ The configuration file is in JSON format, and may contain the following
456530
properties:
457531

458532
* host - the host name to connect to
459-
* port - the port number to use when connecting to the host (8883 for AWS IoT)
533+
* port - the port number to use when connecting to the host (8883 for AWS IoT with client certificate)
460534
* clientId - the client ID to use when connecting
461535
* privateKey - file containing the private key
462536
* clientCert - file containing the client certificate
@@ -480,7 +554,7 @@ each process performs. It's easiest to run each process in its own
480554
terminal window so that you can see the output generated by each. Note
481555
that in the following examples, all certificates are located in the
482556
~/certs directory and have the default names as specified in the
483-
[Certificates section](#certificates).
557+
[Certificate Configuration section](#certificates).
484558

485559
#### _Terminal Window 1_
486560
```sh
@@ -498,19 +572,19 @@ processes which communicate with one another via the AWS IoT platform.
498572
thing-example.js uses a Thing Shadow to synchronize state between the
499573
two processes, and the command line option '--test-mode (-t)' is used
500574
to set which role each process performs. As with device-example.js,
501-
it's best to run each process in its own terminal window. Note
502-
that in the following examples, all certificates are located in the
503-
~/certs directory and have the default names as specified in the
504-
[Certificates section](#certificates).
575+
it's best to run each process in its own terminal window or on separate
576+
hosts. In this example, the example programs are configured to use
577+
WebSocket/TLS connections to the AWS IoT platform as specified in the
578+
[WebSocket Configuration](#websockets).
505579

506580
#### _Terminal Window 1_
507581
```sh
508-
node examples/thing-example.js -f ~/certs --test-mode=1
582+
node examples/thing-example.js -P=wss --test-mode=1
509583
```
510584

511585
#### _Terminal Window 2_
512586
```sh
513-
node examples/thing-example.js -f ~/certs --test-mode=2
587+
node examples/thing-example.js -P=wss --test-mode=2
514588
```
515589

516590
### thing-passthrough-example.js
@@ -523,7 +597,7 @@ is used to set which role each process performs. As with thing-example.js,
523597
it's best to run each process in its own terminal window. Note
524598
that in the following examples, all certificates are located in the
525599
~/certs directory and have the default names as specified in the
526-
[Certificates section](#certificates).
600+
[Certificate Configuration section](#certificates).
527601

528602
#### _Terminal Window 1_
529603
```sh
@@ -561,7 +635,7 @@ Like thing-example.js, temperature-control.js runs in two
561635
separate terminal windows and is configured via command-line options;
562636
in the following example, all certificates are located in the ~/certs
563637
directory and have the default names as specified in the
564-
[Certificates section](#certificates). The process running
638+
[Certificate Configuration section](#certificates). The process running
565639
with '--test-mode=2' simulates an internet-connected temperature control
566640
device, and the process running with '--test-mode=1' simulates a mobile
567641
application which is monitoring/controlling it. The processes may be
@@ -677,6 +751,18 @@ but if you are using a [JSON configuration file](#configurationFile), you'll
677751
need to explictly specify client IDs for both programs using the '-i' command
678752
line option.
679753

754+
<a name="unittests"></a>
755+
## Unit Tests
756+
757+
This package includes unit tests which can be run as follows:
758+
759+
```sh
760+
npm test
761+
```
762+
763+
Running the unit tests will also generate code coverage data in the 'reports'
764+
directory.
765+
680766
<a name="license"></a>
681767
## License
682768

common/lib/is-undefined.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,5 @@
2828
* @access public
2929
*/
3030
module.exports = function(value) {
31-
if ((typeof(value) === 'undefined') || (typeof(value) === null)) {
32-
return true;
33-
}
34-
return false;
31+
return typeof value === 'undefined' || typeof value === null;
3532
};

0 commit comments

Comments
 (0)