Skip to content

Commit

Permalink
Adding callback to thingShadow.register
Browse files Browse the repository at this point in the history
- Update the thing register function with a completion callback
- Add new test for the different states (ignoreDelta and persistentSubscribe)
- Updated README.md to reflect the new changes
  • Loading branch information
Torsph committed Aug 18, 2016
1 parent aaec88d commit d8b1007
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 16 deletions.
20 changes: 8 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,19 +130,12 @@ thingShadows.on('connect', function() {
// After connecting to the AWS IoT platform, register interest in the
// Thing Shadow named 'RGBLedLamp'.
//
thingShadows.register( 'RGBLedLamp' );
//
// 5 seconds after registering, update the Thing Shadow named
thingShadows.register( 'RGBLedLamp', function() {

// When the Thing Shadow is ready, update the Thing Shadow named
// 'RGBLedLamp' with the latest device state and save the clientToken
// so that we can correlate it with status or timeout events.
//
// Note that the delay is not required for subsequent updates; only
// the first update after a Thing Shadow registration using default
// parameters requires a delay. See API documentation for the update
// method for more details.
//
setTimeout( function() {
//
// Thing shadow state
//
var rgbLedLampState = {"state":{"desired":{"red":rval,"green":gval,"blue":bval}}};
Expand All @@ -160,7 +153,6 @@ thingShadows.on('connect', function() {
{
console.log('update shadow failed, operation still in progress');
}
}, 5000 );
});

thingShadows.on('status',
Expand Down Expand Up @@ -333,7 +325,7 @@ from each operation.
-------------------------------------------------------
<a name="register"></a>
### awsIot.thingShadow#register(thingName, [options] )
### awsIot.thingShadow#register(thingName, [options], [callback] )
Register interest in the Thing Shadow named `thingName`. The thingShadow class will
subscribe to any applicable topics, and will fire events for the Thing Shadow
Expand Down Expand Up @@ -364,6 +356,10 @@ AWS IoT maintains version numbers for each shadow, and will reject operations wh
contain the incorrect version; in applications where multiple clients update the same
shadow, clients can use versioning to avoid overwriting each other's changes.
The `callback` parameter are optional and will be called when the thingShadow is read for use.
*Ready for use* means when we have received subscription ACK on all needed topics.
The callback should be used when delete/get/update operations is needed right after the thingShadow is ready.
-------------------------------------------------------
<a name="unregister"></a>
### awsIot.thingShadow#unregister(thingName)
Expand Down
47 changes: 47 additions & 0 deletions test/thing-unit-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,53 @@ describe( "thing shadow class unit tests", function() {
});
});

describe( "register a thing shadow name should trigger callback", function() {
//
// Verify that the thing shadow invokes the register callback when subscription to all
// topics are finished. The callback is invoked based on the callback from the mqtt library.
//

var thingShadowsConfig = {
keyPath: 'test/data/private.pem.key',
certPath: 'test/data/certificate.pem.crt',
caPath: 'test/data/root-CA.crt',
clientId: 'dummy-client-1',
region: 'us-east-1'
};

it("when ignoreDeltas is true and persistentSubscribe is true", function() {
var thingShadows = thingShadow( thingShadowsConfig );
var fakeCallback = sinon.spy();
thingShadows.register( 'testShadow1', {ignoreDeltas:true, persistentSubscribe:true}, fakeCallback);

assert(fakeCallback.calledOnce);
});

it("when ignoreDeltas is false and persistentSubscribe is false", function() {
var thingShadows = thingShadow( thingShadowsConfig );
var fakeCallback = sinon.spy();
thingShadows.register( 'testShadow1', {ignoreDeltas:false, persistentSubscribe:false}, fakeCallback);

assert(fakeCallback.calledOnce);
});

it("when ignoreDeltas is true and persistentSubscribe is false", function() {
var thingShadows = thingShadow( thingShadowsConfig );
var fakeCallback = sinon.spy();
thingShadows.register( 'testShadow1', {ignoreDeltas:true, persistentSubscribe:false}, fakeCallback);

assert(fakeCallback.calledOnce);
});

it("when ignoreDeltas is false and persistentSubscribe is true", function() {
var thingShadows = thingShadow( thingShadowsConfig );
var fakeCallback = sinon.spy();
thingShadows.register( 'testShadow1', {ignoreDeltas:false, persistentSubscribe:true}, fakeCallback);

assert(fakeCallback.calledOnce);
});
});

describe( "subscribe to/unsubscribe from a non-thing topic", function() {
//
// Verify that the thing shadow module does not throw an exception
Expand Down
30 changes: 26 additions & 4 deletions thing/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ function ThingShadowsClient(deviceOptions, thingShadowOptions) {
return rc;
};

this.register = function(thingName, options) {
this.register = function(thingName, options, callback) {
if (!thingShadows.hasOwnProperty(thingName)) {
//
// Initialize the registration entry for this thing; because the version # is
Expand All @@ -477,15 +477,19 @@ function ThingShadowsClient(deviceOptions, thingShadowOptions) {
discardStale: true,
enableVersioning: true,
qos: 0,
pending: false
pending: false,
pendingDeltaSubscribe: true,
pendingPersistentSubscribe: true
};

if (!isUndefined(options)) {
if (!isUndefined(options.ignoreDeltas)) {
ignoreDeltas = options.ignoreDeltas;
thingShadows[thingName].pendingDeltaSubscribe = !ignoreDeltas;
}
if (!isUndefined(options.persistentSubscribe)) {
thingShadows[thingName].persistentSubscribe = options.persistentSubscribe;
thingShadows[thingName].pendingPersistentSubscribe = options.persistentSubscribe;
}
if (!isUndefined(options.debug)) {
thingShadows[thingName].debug = options.debug;
Expand All @@ -505,7 +509,14 @@ function ThingShadowsClient(deviceOptions, thingShadowOptions) {
//
if (ignoreDeltas === false) {
this._handleSubscriptions(thingName, ['update'], ['delta'],
'subscribe');
'subscribe', function () {
thingShadows[thingName].pendingDeltaSubscribe = false;
if (!thingShadows[thingName].pendingDeltaSubscribe && !thingShadows[thingName].pendingPersistentSubscribe) {
if (!isUndefined(callback)) {
callback();
}
}
});
}
//
// If we are persistently subscribing, we subscribe to everything we could ever
Expand All @@ -515,7 +526,18 @@ function ThingShadowsClient(deviceOptions, thingShadowOptions) {
//
if (thingShadows[thingName].persistentSubscribe === true) {
this._handleSubscriptions(thingName, ['update', 'get', 'delete'], ['accepted', 'rejected'],
'subscribe');
'subscribe', function () {
thingShadows[thingName].pendingPersistentSubscribe = false;
if (!thingShadows[thingName].pendingDeltaSubscribe && !thingShadows[thingName].pendingPersistentSubscribe) {
if (!isUndefined(callback)) {
callback();
}
}
});
}

if (ignoreDeltas === true && thingShadows[thingName].persistentSubscribe === false) {
callback();
}
} else {
if (deviceOptions.debug === true) {
Expand Down

0 comments on commit d8b1007

Please sign in to comment.