Visualizzazione post con etichetta DynamoDB. Mostra tutti i post
Visualizzazione post con etichetta DynamoDB. Mostra tutti i post

mercoledì 23 gennaio 2019

Persistenza delle variabili in Alexa Skills

La persistenza delle variabili in Alexa Skills con NodeJS si ottiene tramite PersistantAttributes che si appoggia su DynamoDB in modo trasparente



In questa prima fase viene settata una variabile (per semplicita' statica) in modo persistente. Se non e' settata crea una nuova stringa. Importante impostare la chiamata come asincrona

Da notare che le variabili sono relative ad un determinato account per cui ogni utente ritrovera' le proprie impostazioni

---------------------------------------------------------------------------
const LaunchRequestHandler = {
  canHandle(handlerInput) {
     return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
    
  },
  
  async handle(handlerInput) {    
    const attributesManager = handlerInput.attributesManager;
    var speechText = "Benvenuto nella skill ";

    const attributes = await attributesManager.getPersistentAttributes() || {};

    if (Object.keys(attributes).length === 0) {
      attributes.nameValue = "Luca";
      attributesManager.setPersistentAttributes(attributes);
      await attributesManager.savePersistentAttributes();
    }else {
      speechText = "Benvenuto  ${attributes.nameValue.toString()}";
    }
    
    return handlerInput.responseBuilder
      .speak(speechText)
      .withShouldEndSession(false)
      .getResponse();
  },
};
---------------------------------------------------------------------------


Con questo codice si puo' richiamare il valore della variabile da altra intent

---------------------------------------------------------------------------
 const attributesManager = handlerInput.attributesManager;
  const attributes = await attributesManager.getPersistentAttributes()
  var speechOutput =  attributes.nameValue.toString();
---------------------------------------------------------------------------

Per salvare i dati e' necessario impostare il nome della tabella in cui sono salvate le variabili e la possibilita' di creare in automatico la tabella ove non esista
---------------------------------------------------------------------------
const skillBuilder = Alexa.SkillBuilders.standard();

exports.handler = skillBuilder
  .addRequestHandlers(
    LaunchRequestHandler,
    YesHandler,
    geo,
    HelpHandler,
    ExitHandler,
    SessionEndedRequestHandler
  )
  .addErrorHandlers(ErrorHandler)
  .withTableName('alexa-data')
  .withAutoCreateTable(true)
  .lambda();
---------------------------------------------------------------------------


lunedì 7 gennaio 2019

Interagire con DynamoDB con Lambda e API Gateway

Un sistema per interagire con DynamoDB mediante una funzione Lambda triggerata da API Gateway




Prima prima cosa ho creato a mano una tabella in DynamoDB con due colonne nome (stringa) ed indice (numerico)

La funzione Lambda per interagire con DynamoDB necessita di permessi. Per rendere le cose piu' semplici ho usato i permessi piu' estesi che corrispondono al ruolo AmazonDyamoDBFullAccess (per creare il ruolo si va in consolle di AWS, si apre IAM, Ruolo, Crea Ruolo, si selezione il servizio Lambda e si spunta AmazonDyamoDBFullAccess) Dopo aver salvato il ruolo con un nome si modifica il Ruolo di Esecuzione nella finestra della funzione Lambda impostando il nuovo ruolo

La funzione Lambda di seguito mostra un insertItem ed un getItem condizionato al valore dell'indice numerico

================================================
var AWS = require('aws-sdk');
var DOC = require('dynamodb-doc');
var dynamo = new DOC.DynamoDB();

exports.handler = function(event, context) {
  
  var tableName = "bollettini";
var item = {
    nome: "Federico",
    indice: Number(4)
}
var params = {
    TableName: tableName,
    Item: item
};


    dynamo.putItem(params, function (err, data) {
        if (err) console.log(err, err.stack); // an error occurred
        else console.log(data);               // successful response
    });
  
  var cb = function(err, data) {
    if(err) {
      console.log('error getItem: ',err);
      context.done('Unable to getItem', null);
    } else {
      if(data.Item && data.Item.nome) {
        context.done(null, data.Item);
      } else {
        context.done(null, {});
      }
    }
  };
  dynamo.getItem({TableName:"bollettini", Key:{indice:2}}, cb);

};
================================================

A questo punto per eseguire la Lambda e' necessario impostare un trigger che nel mio caso e' API Gateway. Dalla consolle di AWS si sceglie API Gateway, si selezione Create API, si indica il nome, Nella pagina successiva si clicca sul menu' a tendina Actions e si sceglie GET. Si apre una pagina sulla destra in si inserisce  l'ARN della Lambda e si salva. A questo punto si pubblica la API e si avra' come risposta un link del tipo https:/xxxxxxxx.execute-api.eu-west-1.amazonaws.com/test/

Puntano il browser al link indicato si mettera' in esecuzione la funzione Lambda

giovedì 27 dicembre 2018

DynamoDB con NodeJS

per prima cosa si installa nel progetto AWS SDK per NodeJS con

npm install aws-sdk
si lancia poi DynamoDB in locale come visto qui 
per fare  il deploy sui server Amazon del DB si deve decommentare la riga evidenziata in giallo

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

AWS.config.update({region: "us-west-1",endpoint: "http://localhost:8000"});

// per fare il deploy su DynamoDB sui server Amazon
//AWS.config.update({endpoint: "https://dynamodb.us-west-2.amazonaws.com"});

var dynamodb = new AWS.DynamoDB();

var params = {
    TableName : "Informazioni",
    KeySchema: [
        { AttributeName: "indice", KeyType: "HASH"},  //Partition key
        { AttributeName: "title", KeyType: "RANGE" }  //Sort key
    ],
    AttributeDefinitions: [
        { AttributeName: "indice", AttributeType: "N" },
        { AttributeName: "title", AttributeType: "S" }
    ],
    ProvisionedThroughput: {
        ReadCapacityUnits: 10,
        WriteCapacityUnits: 10
    }
};



dynamodb.createTable(params, function(err, data) {
    if (err) {
        console.error("Unable to create table. Error JSON:", JSON.stringify(err, null, 2));
    } else {
        console.log("Created table. Table description JSON:", JSON.stringify(data, null, 2));
    }
});


//////////// INSERT ////////////////////////
var docClient = new AWS.DynamoDB.DocumentClient();
var table = "Informazioni";
var indice = 2015;
var title = "Il nome della rosa";

var params = {
    TableName:table,
    Item:{
        "indice": indice,
        "title": title,
    }
};

console.log("Adding a new item...");
docClient.put(params, function(err, data) {
    if (err) {
        console.error("Unable to add item. Error JSON:", JSON.stringify(err, null, 2));
    } else {
        console.log("Added item:", JSON.stringify(data, null, 2));
    }
});

//////////// QUERY ////////////////////////
var params = {
    TableName : table,
    KeyConditionExpression: "#yr = :yyyy",
    ExpressionAttributeNames:{
        "#yr": "indice"
    },
    ExpressionAttributeValues: {
        ":yyyy": 2015
    }
};

docClient.query(params, function(err, data) {
    if (err) {
        console.error("Unable to query. Error:", JSON.stringify(err, null, 2));
    } else {
        console.log("Query succeeded.");
        data.Items.forEach(function(item) {
            console.log(" -", item.indice + ": " + item.title);
        });
    }
});



//////////// DELETE ITEM ////////////////////////
var params = {
    TableName:table,
    Key:{
        "indice": indice,
        "title": title
    },
    ConditionExpression:"indice <= :val",
    ExpressionAttributeValues: {
        ":val": 2016
    }
};

console.log("Attempting a conditional delete...");
docClient.delete(params, function(err, data) {
    if (err) {
        console.error("Unable to delete item. Error JSON:", JSON.stringify(err, null, 2));
    } else {
        console.log("DeleteItem succeeded:", JSON.stringify(data, null, 2));
    }
});


var params = {
    TableName : table
};

//////////// DELETE TABLE////////////////////////

dynamodb.deleteTable(params, function(err, data) {
    if (err) {
        console.error("Unable to delete table. Error JSON:", JSON.stringify(err, null, 2));
    } else {
        console.log("Deleted table. Table description JSON:", JSON.stringify(data, null, 2));
    }
});

venerdì 21 dicembre 2018

DynamoDB su localhost

Per configurare DynamoDB in localhost si devono seguire un serie di passi

1) Si deve installare AWS Cli tramite pip install awscli

2) Si deve lanciare il comando aws configure per vedere se e' stata impostata la region (di solito e' su None). Nel mio caso ho impostato eu-west-1

3) da questo link si scarica la versione locale di DynamoDB. Si scompatta e si lancia il comando (viene aperto un server in ascolto sulla porta 8000, se la porta e' occupata si possono modificare le impostazioni)

java -D"java.library.path=./DynamoDBLocal_lib" -jar DynamoDBLocal.jar

4) a questo punto si apre un altro terminale si puo' iniziare ad interagire con DynamoDB per esempio con

aws dynamodb list-tables --endpoint-url http://localhost:8000

puo'essere necessario indicare la region usando aws configure

per creare una tabella (esempi da questo link)
Attenzione : se si lavora in locale si deve sempre utilizzare lo switch --endpoint-url http://localhost:8000 ed aggiungerlo ai comandi sottostanti

aws dynamodb create-table \ --table-name Music \ --attribute-definitions \ AttributeName=Artist,AttributeType=S \ AttributeName=SongTitle,AttributeType=S \ --key-schema AttributeName=Artist,KeyType=HASH AttributeName=SongTitle,KeyType=RANGE \ --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1

e per inserire una riga

aws dynamodb put-item \ --table-name Music \ --item \ '{"Artist": {"S": "No One You Know"}, "SongTitle": {"S": "Call Me Today"}, "AlbumTitle": {"S": "Somewhat Famous"}}' \ --return-consumed-capacity TOTAL


giovedì 6 dicembre 2018

Permssi DynamoDB per Alexa Skill

Prima di poter utilizzare DynamoDB in connessione con una Skill si devono settare i permessi del database tramite IAM. Si va quindi in IAM Roles e si ha la lista delle proprie skill. Si clicca su quella di interesse. Di default  c'e' solo il permesso per l'uso di Cloudwatch.

Si puo' procedere cliccando su Attach Policy e spuntando AmazonDynamoDBFullAccess
Altrimenti si puo' usare un approccio piu' granulare creando una inline policy  e selezionando quanto di interesse


Debugger integrato ESP32S3

Aggiornamento In realta' il Jtag USB funziona anche sui moduli cinesi Il problema risiede  nell'ID USB della porta Jtag. Nel modulo...