aws iot 핸즈온 워크샵 - 실습 6. 긴급 데이터를 kinesis streams으로 보내기...

16
For this lab were going to look at a combination of systems to capture different kinds of data streams. We'll start with the usual AWS IoT system using rules to capture our data but during certain events, as determined by our rules we'll activate a Direct-To-Kinesis stream to capture realtime information. Why would you ever do this? AWS IoT has limits in place for the size of each message but also the number of transactions per second. When streaming realtime telemetry information, if you find you need more than 50TPS you would want to consider going to directly to Kinesis. Let's setup a Kinesis Shard. Let's setup a single shard to capture our stream when it is activated. Open the Kinesis dashboard and pick Kinesis Streams. Click Create Stream. Let's call this "iotshard", you'll enter just 1 shard. Lab 9 - Switch to Kinesis during critical events Step 1

Upload: amazon-web-services-korea

Post on 16-Apr-2017

344 views

Category:

Travel


0 download

TRANSCRIPT

Page 1: AWS IoT 핸즈온 워크샵 - 실습 6. 긴급 데이터를 Kinesis Streams으로 보내기 (김무현 솔루션즈 아키텍트)

For this lab were going to look at a combination of systems to capture different kinds of data streams. We'llstart with the usual AWS IoT system using rules to capture our data but during certain events, as determinedby our rules we'll activate a Direct-To-Kinesis stream to capture realtime information.

Why would you ever do this? AWS IoT has limits in place for the size of each message but also the number oftransactions per second. When streaming realtime telemetry information, if you find you need more than50TPS you would want to consider going to directly to Kinesis.

Let's setup a Kinesis Shard. Let's setup a single shard to capture our stream when it is activated.

Open the Kinesis dashboard and pick Kinesis Streams.Click Create Stream.Let's call this "iotshard", you'll enter just 1 shard.

Lab 9 - Switch to Kinesis during critical events

Step 1

Page 2: AWS IoT 핸즈온 워크샵 - 실습 6. 긴급 데이터를 Kinesis Streams으로 보내기 (김무현 솔루션즈 아키텍트)

We're going to setup some Lambda functions to handle logging for us so we can keep track of our "thing".

Open the Lambda dashboard.Click Create a lambda function.You can use the hello-world blue print.Let's call this function, "iotLambda2", accept the basics.You can also enter the code below to turn on some basic logging.

Step 2

Page 3: AWS IoT 핸즈온 워크샵 - 실습 6. 긴급 데이터를 Kinesis Streams으로 보내기 (김무현 솔루션즈 아키텍트)

Note: We are not creating these function in a VPC for this lab.

Next we need to create another Lambda function to capture our Kinesis stream data.

While in the Lambda dashboard, create a new function.Use the Kinesis-Process-Record blue print.Select the Kinesis Stream you created in step 1.Leave the other options as their defaults.We are going to call this iotLambda3.Make sure your role is a Kinesis Role.On the review screen, make sure you pick "Enable Now" so the event source is active.

Page 4: AWS IoT 핸즈온 워크샵 - 실습 6. 긴급 데이터를 Kinesis Streams으로 보내기 (김무현 솔루션즈 아키텍트)

Here is the code if you want to copy & paste:

console.log('Loading function');

exports.handler = function(event, context) { console.log('IoT Kinesis Event:', JSON.stringify(event, null, 2)); event.Records.forEach(function(record) { // Kinesis data is base64 encoded so decode here var payload = new Buffer(record.kinesis.data, 'base64').toString('ascii'); console.log('Decoded payload:', payload); }); context.succeed("Successfully processed " + event.Records.length + " records.");};

Lastly we need a Lambda function that can publish a change to our shadow state to turn on Kinesis for our"thing".

Create another new Lambda function, use the hello-world blue print.We will call this iotShadowUpdate.The code for this is shown below.

JavaScript

Page 5: AWS IoT 핸즈온 워크샵 - 실습 6. 긴급 데이터를 Kinesis Streams으로 보내기 (김무현 솔루션즈 아키텍트)

You will need to pick an execution role that has access to the IoT service.

Shadow Update Lambda code is as follows:

Page 6: AWS IoT 핸즈온 워크샵 - 실습 6. 긴급 데이터를 Kinesis Streams으로 보내기 (김무현 솔루션즈 아키텍트)

var aws = require('aws-sdk');var iotdata = new aws.IotData({endpoint: 'A3V8IRCN9H4H5T.iot.us-west-2.amazonaws.com'});

exports.handler = function(event, context) { console.log("Event to trigger Kinesis: " + JSON.stringify(event)); var shadow = { "state" : { "desired" : { "streamState": "on" } } }; var params = { topic: '$aws/things/thingtest/shadow/update', payload: JSON.stringify(shadow), qos: 0 }; iotdata.publish(params, function(err, data){ if(err){ console.log(err); context.fail(err); } else{ console.log("Shadow Updated"); context.succeed(true); } }); };

We're now going to setup a couple rules. The first rule will be to track critical data points to our Lambdafunction. The second rule will activate if values are outside the norm and will trigger a shadow state update toour "thing" which tells it to turn on the Kinesis stream. This is done by calling our iotShadowUpdate lambdafunction.

For this lab we're be using 2 new topics.

Step 3

JavaScript

Page 7: AWS IoT 핸즈온 워크샵 - 실습 6. 긴급 데이터를 Kinesis Streams으로 보내기 (김무현 솔루션즈 아키텍트)

Open the AWS IoT Dashboard.Click create resource and pick a new rule.Let's call this iotCritical.We'll select * from our iotCritical topic.Pick the default action as Lambda.Pick iotLambda2 that we created earlier.

Let's now create the Kinesis rule.

Click create resource and pick a new rule again.Let's call this iotKinesis.We'll select * again from our iotCritical topic.We want to add a condition this time, temperature > 100.Pick the default action as Lambda.Pick the iotShadowUpdate we created earlier.

Step 4

Page 8: AWS IoT 핸즈온 워크샵 - 실습 6. 긴급 데이터를 Kinesis Streams으로 보내기 (김무현 솔루션즈 아키텍트)

Our script will now connect and send regular AWS IoT messages but one of these will be a high temperaturevalue that will trigger our state change, once we detect the change we'll stream to Kinesis.

Let's create a new script for this lab. We'll call this "iotCritical.js". This script is going to be using the full AWSSDK. If you don't have that installed you can run

npm install aws-sdk

We are also using a sleep library to run this script a little slower:

npm install sleep

First, create your bootstrap connection code as follows:

note: You'll need to add your Kinesis stream endpoint.

Step 5

Bash

Bash

Page 9: AWS IoT 핸즈온 워크샵 - 실습 6. 긴급 데이터를 Kinesis Streams으로 보내기 (김무현 솔루션즈 아키텍트)

var awsIot = require('aws-iot-device-sdk');var aws = require('aws-sdk');var sleep = require('sleep');

var device = awsIot.device({ "host": "data.iot.us-west-2.amazonaws.com", "port": 8883, "clientId": "1234", "thingName": "thingtest", "caPath": "./root-CA.cer", "certPath": "./certificate.pem.crt", "keyPath": "./private.pem.key", "region": "us-west-2"});

var kinesis = new aws.Kinesis({ acessKeyId: "{ACCESS KEY}", secretAccessKey: "{SECRET KEY}",

var streamState = "off";var x = 0; // general purpose timersvar t = 1; // master kinesis timer

Next on startup we want to set our current shadow state so that our stream is considered off. Let's define ourshadow state.

var msg = { "state": { "reported": { "streamState": "off" }, "desired": { "streamState": "off" } }}

We also want to have some objects ready to modify as we run our test loops:

JavaScript

JavaScript

Page 10: AWS IoT 핸즈온 워크샵 - 실습 6. 긴급 데이터를 Kinesis Streams으로 보내기 (김무현 솔루션즈 아키텍트)

var normalMsg = { "temperature": 0, "seq": 0};

var kinesisMsg = { "x": 0, "y": 0, "z": 0, "id": 0}

Next we're going to add the function to handle our shadow changes, when we see a delta and it contains the"on" state we will trigger our Kinesis stream.

device.on('message', function(topic, message) { console.log('message', topic, message.toString()); if (topic == "$aws/things/thingtest/shadow/update/delta") { var shadow = JSON.parse(message); streamState = shadow.state.streamState; // report back our state change msg.state.reported.streamState = streamState; device.publish('$aws/things/thingtest/shadow/update', JSON.stringify(msg)); if (streamState == 'on') { //startStream(); setTimeout(function() { stream(); }, 2500); } }

// Start our main loop if (topic == '$aws/things/thingtest/shadow/update/accepted') { // Let's loop slowly with regular messages normalMsg.temperature = 75; normalMsg.seq = x; device.publish('iotCritical', JSON.stringify(normalMsg)); console.log("Our current stream state is " + streamState); console.log("Sent regular message " + x + " at temp: " + normalMsg.temperature ) sleep.sleep(1); // seconds }

if (topic == 'iotCritical') {

JavaScript

JavaScript

Page 11: AWS IoT 핸즈온 워크샵 - 실습 6. 긴급 데이터를 Kinesis Streams으로 보내기 (김무현 솔루션즈 아키텍트)

if (x<100) { x++; normalMsg.temperature = 75; normalMsg.seq = x; // on our 10th message we'll pass the threshold just once and see if our shadow changes if (x==10) normalMsg.temperature = 110; setTimeout(function() { device.publish('iotCritical', JSON.stringify(normalMsg)); }, 500);

console.log("Our current stream state is " + streamState); console.log("Sent regular message " + x + " at temp: " + normalMsg.temperature //sleep.sleep(1); // seconds } else { console.log('Done!'); } }});

The above is pretty simple. We're first checking our streaming state and after that we're using the callbackfunctionailty to trigger a slower loop to keep sending messages to AWS IoT.

Once the critical temp is sent (see the line setting our high temp on the 10th message) we see the shadowchange to turn on our Kinesis stream.

Let's now add the stream() function which just blasts data to Kinesis:

Page 12: AWS IoT 핸즈온 워크샵 - 실습 6. 긴급 데이터를 Kinesis Streams으로 보내기 (김무현 솔루션즈 아키텍트)

var stream = function() { console.log('Starting Kinesis Stream ...'); for(t=1;t<50;t++) { // Let's publish our telemtry data kinesisMsg.id = t; kinesisMsg.x = t; kinesisMsg.y = Math.random() * (5000 - 1) + 1; kinesisMsg.z = kinesisMsg.y/t; kinesis.putRecord({ StreamName : "iotshard", Data : JSON.stringify(kinesisMsg), PartitionKey : "id" }, function(err, data) { if (err) { console.log(err, err.stack); // an error occurred } else { console.log("Sent stream message to Kinesis: " + JSON.stringify } }); }}

Finally we setup our gateway device object as usual and subscribe to the relevant topics:

device.on('connect', function() { console.log('Connected!'); setTimeout(function() { device.subscribe('$aws/things/thingtest/shadow/update/delta'); device.subscribe('$aws/things/thingtest/shadow/update/accepted'); device.subscribe('iotCritical'); device.publish('$aws/things/thingtest/shadow/update', JSON.stringify(msg)); console.log("Set our thing shadow."); console.log('Waiting ...'); }, 2500);});

FULL SOURCE

// Lab 9// Watch our shadow state for kinesis triggers.

JavaScript

JavaScript

JavaScript

Page 13: AWS IoT 핸즈온 워크샵 - 실습 6. 긴급 데이터를 Kinesis Streams으로 보내기 (김무현 솔루션즈 아키텍트)

var awsIot = require('aws-iot-device-sdk');var aws = require('aws-sdk');var sleep = require('sleep');

var device = awsIot.device({ "host": "data.iot.us-west-2.amazonaws.com", "port": 8883, "clientId": "1234", "thingName": "thingtest", "caPath": "./root-CA.cer", "certPath": "./certificate.pem.crt", "keyPath": "./private.pem.key", "region": "us-west-2"});

var kinesis = new aws.Kinesis({ acessKeyId: "{Your Access Key}", secretAccessKey: "{Your Secret Key}"

var streamState = "off";

var x = 0;var t = 1;

var msg = { "state": { "reported": { "streamState": "off" }, "desired": { "streamState": "off" } }}

var normalMsg = { "temperature": 0, "seq": 0};

var kinesisMsg = { "x": 0, "y": 0, "z": 0, "id": 0}

Page 14: AWS IoT 핸즈온 워크샵 - 실습 6. 긴급 데이터를 Kinesis Streams으로 보내기 (김무현 솔루션즈 아키텍트)

device.on('message', function(topic, message) { console.log('message', topic, message.toString()); if (topic == "$aws/things/thingtest/shadow/update/delta") { var shadow = JSON.parse(message); streamState = shadow.state.streamState; // report back our state change msg.state.reported.streamState = streamState; device.publish('$aws/things/thingtest/shadow/update', JSON.stringify(msg)); if (streamState == 'on') { //startStream(); setTimeout(function() { stream(); }, 2500); } }

// Start our main loop if (topic == '$aws/things/thingtest/shadow/update/accepted') { // Let's loop slowly with regular messages normalMsg.temperature = 75; normalMsg.seq = x; device.publish('iotCritical', JSON.stringify(normalMsg)); console.log("Our current stream state is " + streamState); console.log("Sent regular message " + x + " at temp: " + normalMsg.temperature ) sleep.sleep(1); // seconds }

if (topic == 'iotCritical') { if (x<100) { x++; normalMsg.temperature = 75; normalMsg.seq = x; // on our 25th message we'll pass the threshold just once and see if our shadow changes if (x==10) normalMsg.temperature = 110; setTimeout(function() { device.publish('iotCritical', JSON.stringify(normalMsg)); }, 500);

console.log("Our current stream state is " + streamState); console.log("Sent regular message " + x + " at temp: " + normalMsg.temperature //sleep.sleep(1); // seconds } else { //process.exit(); console.log('Done!');

Page 15: AWS IoT 핸즈온 워크샵 - 실습 6. 긴급 데이터를 Kinesis Streams으로 보내기 (김무현 솔루션즈 아키텍트)

} }});

var stream = function() { console.log('Starting Kinesis Stream ...'); for(t=1;t<50;t++) { // Let's publish our telemtry data kinesisMsg.id = t; kinesisMsg.x = t; kinesisMsg.y = Math.random() * (5000 - 1) + 1; kinesisMsg.z = kinesisMsg.y/t; kinesis.putRecord({ StreamName : "iotshard", Data : JSON.stringify(kinesisMsg), PartitionKey : "id" }, function(err, data) { if (err) { console.log(err, err.stack); // an error occurred } else { console.log("Sent stream message to Kinesis: " + JSON.stringify } }); }}

device.on('connect', function() { console.log('Connected!'); setTimeout(function() { device.subscribe('$aws/things/thingtest/shadow/update/delta'); device.subscribe('$aws/things/thingtest/shadow/update/accepted'); device.subscribe('iotCritical'); device.publish('$aws/things/thingtest/shadow/update', JSON.stringify(msg)); console.log("Set our thing shadow."); console.log('Waiting ...'); }, 2500);});

You can run this now and you see the switch between AWS IoT and Kinesis.

node iotCritical.jsBash

Page 16: AWS IoT 핸즈온 워크샵 - 실습 6. 긴급 데이터를 Kinesis Streams으로 보내기 (김무현 솔루션즈 아키텍트)