CS4521:   Mobile and Topics in Web Programming

Step 3: Setup Lambda Functions --- the code (for creating a new user/biker in biker table)

    There are 4 steps

    Step 3.1: select CloudLogic for your Mobile Hub Project and create API(s) and Path(s) (each path = new lambda function created)

    Step 3.2: For EACH PATH you created in step 1 you must edit the autogenerated lambda code to do what you want.

    Step 3.3: For EACH lambda code, you must ONCE ONLY, edit your policys associated with the "Role" assigned to your lamdba code if this code need to do more than run --like it must access a DynamoDB table then you need to add the poicy.

    Step 3.4: TEST your Code and re edit it as desired

     

     

     

     

    NOW the CODE to Write to Database is what you seeing me create here. There are many options you can use but, I am going to do NodeJS. Note you can make code to do anything you want the database access is just one example.

     

    currently, when setting up the Lambda Function you setup an API (the gateway) and Lambda code in THIS ONE STEP
    *note this is new Nov., 2016 so be careful you don't read old tutorials

     

     

    Recall: Lambda (called serverless) - somewhere between a PAAS and SAAS. You deploy application (either NodeJS, Java, Python--see documentation), pay for calling to code not for deployment.

          So lets try to do just that add code in AWS Cloud Logic as to write to our biker table we created above.

          Amazon Lambda = event driven compute service for creating dynamic applications that connect to and use various Amazon Services (DynamoDB -database, S3 -file storage, and more). Events examples = update in DB, modified object in S3, or even custom event receive from another application (like your mobile app).

          scenario 1= update in DB (like addition of a new data record) cause publication of this record to say a social network like facebook.

          scenario 2= mobile application makes call to Lambda function creating event that passes data the Lamda code should take and use it to write new entry in DynamoDB database

           

 

STEP 3.1: select Cloud Logic in your AWS project and then add NEW API(s) and Path(s)


    >>>configuring the API called biker - which will represent the transactions with a biker database table in AmazonDB.

    FOR each PATH you create mobileHub will autogenerate a simple lambda function that is associated with it.

    >>below I am specifying 2 paths /createUser which will be tied to a lambda function that will create a new user(biker) database entry in the biker table. The second paht is /verifyUser that will be tied to a lambda function that will verify a user's login credentials

     

     

    Now I am create a second API dealing with transactions on ROUTES table in DynamoDB

    >> I have created 3 paths

    • /getRoutes that will retrieve the top 10 used routes.

    • /storeRoute that will take as input a new route and store it in the ROUTES table.

    • /useRoute that will return the details of Route given an ID from the ROUTES table and also increase the "Used" column of the ROUTES table for this Route (with this ID)


     

     

STEP 3.2: For EACH PATH you created in step 1 you must edit the autogenerated lambda code to do what you want.

      First go to the lambda backend code by next to each API selection Actions and you can then select to EDIT BACKEND CODE
      for the desired labmda code (associated with a path in that API)

I am going to edit the code for /createUser path in the biker API that is associated with the lambda function "createUserHandler"

This is NOT A COMPLETE MANUAL but, below I am making a Lambda Function that writes to the biker database table a new entry passed as the event informaiton. This is done in NodeJS but, Lamda also supports Java and Python.

YOU NEED at this point to pickup a Manual/ Tutorial on Writing Lamda code (either NodeJS, Python, Java) to access one of the services like NoSQL database on AWS (called DynamoDB) or the User Data storage (uses AWS S3) or whatever it is YOU want to do.

Here is the code I will use

    Basics of a Lambda function / code in NodeJS that will write a new entry (passed as event data) to the AmazonDB database

     

    'use strict';
     /*
     This code is used to create a new entry into the Database of  bikers for blindBike.  Notice that the
    format is JSON (java script object notation) which is commonly used for data exchange with web services
    input event example
                         "Item"  : {
                         "userId": "lynne123",
                         "date": "Mon Aug 29 2016 23:57:25 GMT+0000 (UTC)",
                         "password": "whateverIspassword123"
                         }
                         
                         TODO: extend this  code to make sure that the event parameters are not null and pass default  values if they 
                         NOTE: date is optional.   Should add processing the fields of firstName, lastName and date to complete all of the
    values possible in each entry of the biker database table */ console.log('Loading function');
    console.log('Loading function');
     var doc =  require('dynamodb-doc');  //require javascript package for DynamoDB access
     var db = new  doc.DynamoDB();   //create instance of DynamoDB access object
                 
    
    //This is the MAIN function that is called by Lambda system, passing event and context
    // see above for expected event data attributes that will be processed below to use as data want to enter into our bikers table        
    exports.handler = function(event, context) 
    {
          var userID  = event.userId;   //get userId from event
          var password =  event.password;  //get password from event
    
          //this version of code generates the date rather than reading from the event, this could be altered
          var datetime =  new Date().toString(); // OR can use new Date().getTime().toString();
          
          //simple log to see what is going on.
          console.log(userID  + "," + password +","+ datetime);
          
          var tableName =  "blindbike-mobilehub-1926030853-biker";  //this is the name of YOUR project's dynamoDB table
                         
    
          //this version of the code is creating a data entry only with the required userID and additional password and date
    // it is left as future work to add the other fields of firstName and lastName var item = { "userId": userID, "password":  password, "date": datetime }; var params = { TableName:tableName, Item: item }; console.log(params); //ADD TO database using putItem method - this code is obviously specific to the DynamoDB class that is specific to Lambda db.putItem(params,function(err,data){ if (err) console.log(err); else console.log(data); }); };

     

     

    Below is practically the same code as in the above but, have ADDED parsing the input (request) and a response
    AND have added code to handle POST/PUT and GET requests for reading in data

    Basics of a Lambda function / code in NodeJS that will write a new entry (passed as event data) to the AmazonDB database" __

    EXPECT data input from POST method call

    
    'use strict';
    /* This code is used to create a new entry into  the Database of  bikers for  blindBike.  Notice that the
    format is JSON (java script object notation) which is commonly used for data exchange with web services            input event example
                         "Item"  : {
                         "userId": "lynne123",
                         "password": "whateverIspassword123",                      "firstName" : "Lynne",                      "lastName": "Grewe"                      }
                         
                          TODO: extend  this  code to make sure that the event  parameters are not null and pass default   values if they 
                        NOTE: date is  optional.   Should add processing the  fields of firstName, lastName and date to complete all of the
                               values possible in  each entry of the biker database table"
                                date_lastAccess": "Mon Aug 29 2016 23:57:25 GMT+0000  (UTC)" //set by this server code not passed in                     
     */
     
    console.log('Loading function');
     var doc =   require('dynamodb-doc');   //require javascript package for DynamoDB access
     var db = new   doc.DynamoDB();   //create  instance of DynamoDB access object
     console.log('Loaded Database Object');
     
    exports.handler = function(event,  context, callback) {
         var responseCode = 200;
         var requestBody, pathParams, queryStringParams, headerParams, stage,
         stageVariables, cognitoIdentityId, httpMethod, sourceIp, userAgent,
         requestId, resourcePath;
         console.log("request: " + JSON.stringify(event));
     
         // Request Body
         requestBody = event.body;
         console.log("request body : " + requestBody);
     
         if (requestBody !== undefined && requestBody !== null) { 
             // Set 'test-status' field in the request to test sending a specific  response status code (e.g., 503)
             responseCode = JSON.parse(requestBody)['test-status'];
         }
         // Path Parameters
         pathParams = event.path; 
         // Query String Parameters
         queryStringParams = event.queryStringParameters; 
         // Header Parameters
         headerParams = event.headers;
         if (event.requestContext !== null && event.requestContext !==  undefined) {
              var requestContext = event.requestContext;
              // API Gateway Stage
              stage = requestContext.stage;
             // Unique Request ID
                 requestId = requestContext.requestId;
             // Resource Path
                  resourcePath =  requestContext.resourcePath;
              var identity = requestContext.identity; 
             // Amazon Cognito User Identity
             cognitoIdentityId = identity.cognitoIdentityId;
              // Source IP
            sourceIp = identity.sourceIp;
             // User-Agent
             userAgent = identity.userAgent;
         }
     
         // API Gateway Stage Variables
         stageVariables = event.stageVariables;
          // HTTP Method (e.g., POST, GET, HEAD)
         httpMethod = event.httpMethod;
        console.log("Http method = " +  httpMethod);
       //********************************************************************************************
       //business logic --read in input and create new user entry in biker  table
       var userID;
       var password;
       var firstName;
       var lastName; 
       //IF a PUT method get the JSON data from body and not from event
       if(httpMethod !== undefined && (httpMethod == "PUT" ||  httpMethod =="POST"))
         {   requestBody =  JSON.parse(requestBody); //expect input in JSON form
             userID = requestBody.userId;
             firstName = requestBody.firstName;
             lastName = requestBody.lastName;
             password = requestBody.password; }
       else if(httpMethod !== undefined && httpMethod ==  "GET")  //if GET method type
         {
            userID = queryStringParams.userId;
            firstName = queryStringParams.firstName;
            lastName = queryStringParams.lastName;
            password = queryStringParams.password;
            console.log("userid INPUT" + userID + " and method type =  " + httpMethod + "and queryParameters= " +  JSON.stringify(queryStringParams));
         }
       else  //if a not POST/PUT/GET
         {
           userID = event.userId;   //get userID  from event
           password =  event.password;  //get password from event
           firstName = event.firstName;
           lastName = event.lastName;
            console.log("userid INPUT" + userID + " and method type =  " + httpMethod + " password=" +password + "  firstName=" + firstName + " lastName=" + lastName + " and  queryParameters= " + JSON.stringify(queryStringParams));
         }
     
           //this version of code generates the date rather than reading from the  event, this could be altered
           var datetime =  new  Date().toString(); // OR can use new Date().getTime().toString();
           //simple log to see what is going on.
           console.log(userID  +  "," + password +","+ datetime);
            var tableName =   "blindbike-mobilehub-1926030853-biker";  //this is the name of YOUR project's dynamoDB  table
            //this version of the code is creating a data entry only with the  required userID and additional password and date
           // it is left as future work to add the other fields of firstName and  lastName
          var item = {
                         "userId":  userID,
                         "password":  password,
                         "date_lastAccess":  datetime,
                         "firstName":  firstName,
                         "lastName":  lastName
                      };
                         
            var params = {
                         TableName:tableName, 
                         Item: item
                      };   
            console.log(params);
            console.log("About to create new entry in Database table  biker"); 
            //ADD TO database using putItem method - this code is obviously specific  to the DynamoDB class that is specific to Lambda
            db.putItem(params,function(err,data){
                         if (err)  
                           {  console.log(err); context.fail("could  not add new user to biker database table"); }                      
                         else
                            { console.log("No  error putting to database"); console.log(data);                       
                               //*******************************************************************************
                                // For  demonstration purposes, we'll just echo these values back to the client
                                var responseBody =  {
                                    requestBody : requestBody,
                                    pathParams :  pathParams,
                                     queryStringParams : queryStringParams,
                                    headerParams :  headerParams,
                                    stage : stage,
                                    stageVariables  : stageVariables,
                                     cognitoIdentityId : cognitoIdentityId,
                                    httpMethod :  httpMethod,
                                    sourceIp : sourceIp,
                                    userAgent :  userAgent,
                                   requestId :  requestId,
                                    resourcePath :  resourcePath,
                                   userId: userID
                                };
                                var response = {
                                   statusCode:  responseCode,
                                    headers: {
                                         "x-custom-header" : "custom header value"
                                    },
                                    body:  JSON.stringify(responseBody)
                                };
                                 console.log("response: " + JSON.stringify(response));
                                console.log("Database new user  entry into biker table completed");
                                 context.succeed(response);
                            }
                       });
                  
    }; 
     

     

    normally at this step you would test and re-edit your code...BUT, you may have to do step 3.3 first before you can get it to run if you need to add policies

 

 

STEP 3.3: SETTING UP (one time for each lamda function's role) Role to add Policy so that you can read/write to database from this Lambda code

 

setup of : roles --to be able to have a role associated with executing the lamda code AND access to DynamoDB do the following

1) in Lambda console go to the configuration tab for your lambda code to see the currently assigned role.

2) go to IAM console https://console.aws.amazon.com/iam/home#/roles and look up this role (for me the MOBILEHUB***CPWZ*** one)

(NOTE: by default the policy for executing lambda is assigned.)

3) click on "Attach Policy" to edit the role to add access to DyanmoDB (find it and add it)

Now it has been added


STEP 3.4: TEST the code

 

NOW you should be able to TEST your code and have it write to the database

Here you can see the results --the enb user is added to our table

 

Running using AWS generated app

 
 

For mode Lambda code samples go to

Click here to see the /verifyUser path's lambda function code

Click here to see the /getRoutes path's lambda function code

Click here to see the /createRoute path's lambda function code

 

 

 


 

Special NOTE:

you can get plugins for the Eclipse editor to work with Lambda rather than typing in code in console, but, you need to investigate this on AWS

 

© Lynne Grewe