How to do it...

Let's discuss the steps to read data from Lambda without repeating the common steps we already discussed:

  1. Create a Maven project for the Lambda with the common parent and the DynamoDB Java SDK dependency.
  2. Define the Request and Response domain objects.

The Request object for the lambda-dynamodb-read-item lambda is defined as follows:

@Data
public class Request {
private String tableName;
private String partitionKey;
private String sortKey;
private String partitionKeyValue;
private String sortKeyValue; // Will be stored integer.
private boolean waitForActive;
private Map<String, String> filterData;
}

The filterData map will contain the attributes to create filter expressions and their corresponding values. The Response object is common for all Lambdas, as discussed in the Using the DynamoDB SDK from Lambda recipe. 

  1. Create the service implementation.

The service class will have implementations for get-item, query, and scan operations. Reading items using get-item can be done as follows:

Table table = dynamoDB.getTable(request.getTableName());
Item item = table.getItem(new PrimaryKey()
.addComponent(request.getPartitionKey(), request.getPartitionKeyValue())
.addComponent(request.getSortKey(), Integer.parseInt(request.getSortKeyValue())));

Reading using a query can be done as follows:

Table table = dynamoDB.getTable(request.getTableName());
final String keyConditionExpression = request.getPartitionKey() + "=:" + request.getPartitionKey();
QuerySpec querySpec = new QuerySpec()
.withKeyConditionExpression(keyConditionExpression);
final Map<String, Object> valueMap = new HashMap<>();
StringBuilder filterExpressionBuilder;
if (request.getFilterData() != null) {
filterExpressionBuilder = new StringBuilder();
processFilterData(request, filterExpressionBuilder, valueMap);
querySpec.withFilterExpression(filterExpressionBuilder.toString());
}
valueMap.put(":" + request.getPartitionKey(), request.getPartitionKeyValue());
querySpec.withValueMap(valueMap);
ItemCollection<QueryOutcome> items = table.query(querySpec);

You can also supply both the keys, instead of just the partition key. More examples are provided with the code files.

Reading using a scan can be done as follows:

final Table table = dynamoDB.getTable(request.getTableName());
final String projectionExpression = request.getPartitionKey() + " , " + request.getSortKey();
final ScanSpec scanSpec = new ScanSpec()
.withProjectionExpression(projectionExpression);
StringBuilder filterExpressionBuilder;
Map<String, Object> valueMap;
if (request.getFilterData() != null) {
filterExpressionBuilder = new StringBuilder();
valueMap = new HashMap<>();
processFilterData(request, filterExpressionBuilder, valueMap);
scanSpec.withFilterExpression(filterExpressionBuilder.toString());
scanSpec.withValueMap(valueMap);
}
ItemCollection<ScanOutcome> scanItems = table.scan(scanSpec);

The processFilter data method creates the filter expression and value map iterating through the filterData map:

private void processFilterData(final Request request,
final StringBuilder filterExpressionBuilder,
final Map<String, Object> valueMap) {

request.getFilterData().forEach((k, v) -> {
final String var = ":" + k;
if (!filterExpressionBuilder.toString().isEmpty()) {
filterExpressionBuilder.append(" and ");
}
filterExpressionBuilder.append(k + "=" + var);
valueMap.put(var, v);
});
}

Instead of using the DynamoDB wrapper client, you can also use the AmazonDynamoDB client to do get-item, query, and scan. The complete code with both the options is available with the code files. 

  1. Define Lambda handler to call the service method and return a response.

I have modified the Lambda handler implementation to call get-item, query, or scan as follows: if both key parameters have values, I call get-item; if only the partition key has a value, I call query; and if both keys' values are missing, I call scan. This is not a requirement, but only a convenient way to demonstrate.

  1. Package and deploy Lambda.
  2. Define the CloudFormation template.

In the CloudFormation template, add permissions for Lambda to execute get-item, query, and scan:

- Effect: Allow
Action:
- dynamodb:GetItem
- dynamodb:Query
- dynamodb:Scan
Resource:
- Fn::Sub: arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/*
  1. Deploy the CloudFormation template.
  2. Invoke Lambda and test it.

Invoke the Lambda, providing both keys to execute the get-item method:

aws lambda invoke 
--invocation-type RequestResponse
--function-name lambda-dynamodb-read-item
--log-type Tail
--payload '{
"tableName":"my_table",
"partitionKey": "id",
"sortKey": "dateandtime",
"partitionKeyValue": "p1",
"sortKeyValue": 1537963031,
"waitForActive": false
}'
--region us-east-1
--profile admin
outputfile.txt

Invoke Lambda, passing the partition key and a filter to execute the query method:

aws lambda invoke 
--invocation-type RequestResponse
--function-name lambda-dynamodb-read-item
--log-type Tail
--payload '{
"tableName":"my_table",
"partitionKey": "id",
"sortKey": "dateandtime",
"partitionKeyValue": "p1",
"waitForActive": false,
"filterData" : {
"s1": "v1",
"s2": "v2"
}
}'
--region us-east-1
--profile admin
outputfile.txt

The filter expression is optional. Though not shown in this recipe, a query can accept both the keys, along with a filter. 

Finally, we can invoke a scan as follows:

aws lambda invoke 
--invocation-type RequestResponse
--function-name lambda-dynamodb-read-item
--log-type Tail
--payload '{
"tableName":"my_table",
"partitionKey": "id",
"sortKey": "dateandtime",
"waitForActive": false,
"filterData" : {
"s1": "v1",
"s2": "v2"
}
}'
--region us-east-1
--profile admin
outputfile.txt

The filter expression is optional. DynamoDB will always do a full table scan. I have added more examples in the code files than shown in the book.

The version 2 service implementation can be executed after updating the API_VERSION Lambda environment variable to V2

aws lambda update-function-configuration 
--function-name lambda-dynamodb-read-item
--environment Variables={API_VERSION=V2}
--region us-east-1
--profile admin
  1. Clean up the resources.

There is no cleanup required after reading data. However, you should have set up the data following the previous recipe or an earlier one. You may either delete that data or the whole table itself.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.136.233.153