Tutorial zu iX 8/2016 Tröpfchenweise – Abkehr vom monolithischen Enwickeln

Dieser Blog-Eintrag beschreibt im Detail die einzelnen Schritte zur Umsetzung des im iX-Artikel „Tröpfchenweise – Abkehr vom monolithischen Entwickeln“  (iX 8/2016) angeführten Szenarios.

Das Szenario setzt voraus, dass Sie bereits über einen AWS-Account verfügen. Genaue Informationen zum Anlegen eines Test-Accounts finden Sie hier (http://aws.amazon.com/free/).

Nach dem Anmelden an der AWS Console wählen Sie auf der Hauptseite den „Lambda“ – Dienst aus.

iX-L-1

Im nächsten Screenshot ist die Startseite des Lambda-Diensts sichtbar. Eine neue Lambda-Funktion kann durch Klicken auf „Get started now“ angelegt werden.

iX-L-2

Hier besteht die Möglichkeit, einen bestehenden Blueprint als Vorlage zu verwenden, oder diesen Schritt durch Klicken auf „Skip“ zu überspringen. In diesem Beispiel wird kein Blueprint verwendet. Klicken Sie daher auf Skip.

iX-L-3

In Step2: Configure function kann die Lambda-Funktion konfiguriert werden.

iX-L-4

Belassen Sie die Auswahl auf „Edit Code Inline“ und fügen das folgende Code-Fragment ein:

console.log('Loading function');

var AWS = require('aws-sdk');

var doc = require('dynamodb-doc');

var dynamo = new doc.DynamoDB();

var s3 = new AWS.S3();

exports.handler = function(event, context) {

console.log('Received event:', JSON.stringify(event, null, 2));

var params = {Bucket: event.Records[0].s3.bucket.name, Key: event.Records[0].s3.object.key};

var dynamoEvent = {};

s3.getObject(params, function(err, data) {

if (err) console.log(err, err.stack);

else   {

console.log(data);

var dynamoData = data.Body.toString('ascii');

var uid = event.Records[0].s3.object.key;

dynamoEvent = {TableName: "order", Item: { id:  uid, text: dynamoData }};

dynamo.putItem(dynamoEvent, context.done);

}

});

};

Im unteren Teil des Bildschirms ist das Feld „Role“ auszuwählen. Bitte wählen Sie „Basic with DynamoDB“ aus. Die Auswahl der Rolle weist der Lambda-Funktion Berechtigungen zu, in diesem Fall auf den DynamoDB-Dienst. Klicken Sie nach dieser Auswahl auf „Allow“. Das Feld Handler kann vorerst auf den Standard-Wert „index.handler“ belassen werden

iX-L-5

Gehen wir den Code im Detail durch. Bis zur Zeile Fünf bereiten wir nur die Verbindungen zu S3 und DynamoDB vor. In Zeile Sieben starten wir die Funktion, wobei „exports.X“ zum Handler weiter unten auf der Seite passen muss; „index.handler“ ruft „exports.handler“ auf. Die Funktionsparameter „event“ und „context“ enthalten alle relevanten Daten zum Start der Funktion, wobei sich „context“ um die Umgebung der Funktion kümmert und „event“ die Metadaten über das von S3 ausgelöste Event enthält. Der Inhalt des event-Objekts würde exemplarisch folgendermaßen aussehen:

{

"Records": [

{

"eventVersion": "2.0",

"eventTime": "1970-01-01T00:00:00.000Z",

"requestParameters": {

"sourceIPAddress": "127.0.0.1"

},

"s3": {

"configurationId": "testConfigRule",

"object": {

"eTag": "0123456789abcdef0123456789abcdef",

"sequencer": "0A1B2C3D4E5F678901",

"key": "HelloWorld.jpg",

"size": 1024

},

"bucket": {

"arn": "arn:aws:s3:::mybucket",

"name": "sourcebucket",

"ownerIdentity": {

"principalId": "EXAMPLE"

}

},

"s3SchemaVersion": "1.0"

},

"responseElements": {

"x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH",

"x-amz-request-id": "EXAMPLE123456789"

},

"awsRegion": "us-east-1",

"eventName": "ObjectCreated:Put",

"userIdentity": {

"principalId": "EXAMPLE"

},

"eventSource": "aws:s3"

}

]

}

Dieses JSON-Objekt enthält also „Records“ für jede neue Datei im S3-Bucket. Um diese Dateien auszulesen brauchen wir aus dem S3-Bereich innerhalb des Records den „bucket.name“ und den „object.key“, zusammen also:

var params = {Bucket: event.Records[0].s3.bucket.name, Key: event.Records[0].s3.object.key};

Dabei gehen wir vorerst davon aus, dass immer nur eine Datei gleichzeitig entsteht. Das können wir jetzt der S3.getObject-Funktion übergeben, um den Inhalt und die Metadaten der neu erstellten Datei zu erhalten;

s3.getObject(params, function(err, data) {

Wobei „data“ jetzt den Body, also den Inhalt der Datei enthält, den wir direkt wie er ist in die DynamoDB Tabelle schreiben. In unserem kleinen Beispiel gehen wir von einer Tabelle namens „order“ aus, die die beiden Spalten „id“ und „text“ enthält. Der Inhalt der Datei wird unter „text“ gespeichert mit dem Dateinamen als „id“:

dynamoEvent = {TableName: "order", Item: { id:  uid, text: dynamoData }};

dynamo.putItem(dynamoEvent, context.done);

Vorerst sind wir fertig mit der Funktion und können unten „Next“ und „Create Funktion“ klicken.

Was wir jetzt noch brauchen, ist das S3-Bucket-event. Dazu wählen Sie die neue Funktion noch einmal aus und gehen zum Tab „Event sources“.

iX-L-6

Dort erstellen Sie ein neues event per „Add event source“:

iX-L-7

Als „Event source type“ wählen Sie „S3“ aus, dazu den passenden S3-Bucket und als Event type „Object Created (All)“. Mit Prefix und Suffix könnte man die Objekte, die das event auslösen sollen anhand des Objektnamens noch genauer filtern. Klicken Sie hier auf Submit.

Im nächsten Schritt wird die DynamoDB – Tabelle erstellt, in der die zu verarbeitenden Daten eingefügt werden. Dazu gehen Sie oben unter Services auf DynamoDB.

iX-L-8

Dort klicken Sie auf „Create Table“ und geben als Namen „order“ und als Primary Key „id“ an. Klicken Sie dann auf „Create“.

iX-L-9

Testen der Lambda-Funktion

Zum Testen der Lambda-Funktion muss eine neue Datei in den S3-Bucket hochgeladen werden. Wechseln Sie dazu oben unter Services zu ihrem S3-Bucket und laden eine JSON-Datei hoch. Für dieses Beispiel können Sie den folgenden JSON-Code verwenden:

{ "name"   : "John Doe",

"product": { "name" : "present",

"price"  : 23.95 }

"shipTo" : { "name" : "Jane Doe",

"address" : "123 Maple Street",

"city" : "Pretendville",

"state" : "NY",

"zip"   : "12345" },

"billTo" : { "name" : "John Doe",

"address" : "123 Maple Street",

"city" : "Pretendville",

"state" : "NY",

"zip"   : "12345" }

}

iX-L-10

Falls die vorherigen Schritte korrekt konfiguriert worden, sollte ein neuer Eintrag in der DynamoDB – Datenbank angelegt worden sein (siehe Screenshot).

iX-L-11

Falls bei der Ausführung der Funktion Problem auftreten oder die Funktion nicht zum gewünschten Ergebnis führt, können im CloudWatch – Dienst die Log-Dateien eingesehen werden. Das untere Beispiel zeigt den Output einer erfolgreichen Funktions-Ausführung.

iX-L-12

Kommentar absenden

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert