Reputation: 728
I am using AWS Lambda written in java to process DynamoDB Streams. Here is the code:
public class DDBEventProcessor implements
RequestHandler<DynamodbEvent, String> {
public String handleRequest(DynamodbEvent ddbEvent, Context context) {
for (DynamodbStreamRecord record : ddbEvent.getRecords()){
Map<String, AttributeValue> tmp = record.getDynamodb.getNewImage();
//convert tmp to Map<String, Object> here
}
}
}
I need to process the record further.
For that it needs to be converted to a Map<String, Object>
.
The data received will be of the format: { "id":{"s":"777"}}
.
But I want to convert it into {"id":"777"}
, so that I am able to parse the map object easily. But there are nested arrays and maps as well. Also the record is very complicated consisting of nested arrays and maps. How to achieve this?
Upvotes: 2
Views: 10192
Reputation: 10665
I understand you want to convert Map<String, AttributeValue>
to Map<String, Object>
, so what @knittl answered is correct if you want "Object" but you wanted to get the literal value of each field instead of simply casting AttributeValue
to Object
, if I understand you correctly.
So if you checkout the code for AttributeValue
:
public class AttributeValue implements Serializable, Cloneable {
private String s;
private String n;
private ByteBuffer b;
private List<String> sS;
private List<String> nS;
private List<ByteBuffer> bS;
private Map<String, AttributeValue> m;
private List<AttributeValue> l;
private Boolean nULLValue;
private Boolean bOOL;
...
You can see there are many type fields listed and they are used to enforce "typing". We will come back to this.
Because you get this as DynamoDB Stream Event we need a model class we can talk about :)
Let's say we have this simple model class:
public class Employee {
String name = "John";
int age = 25;
boolean isPermanent = true;
}
When you create/update a record of the above model, DynamoDB will generate an event which contains the old record(image) and the new one (this depends of course on your configuration).
Now coming back to the type check:
name
field is String
, this result in entry of key name
and value atrbValue.s = "John"
age
field is int
, this result in entry of key age
and value atrbValue.n = "25"
isPermanent
field is boolean
, this result in entry of key isPermanent
and value atrbValue.bOOL = true
So you can see there is no shortcut to how to convert Map<String, AttributeValue>
to Map<String, Object>
.
But you can do this:
Map<String, Object> result = new HashMap<String, Object>();
AttributeValue defaultValue = new AttributeValue();
result.put("name", image.getOrDefault("name", defaultValue).getS());
result.put("age", Integer.valueOf(image.getOrDefault("age", defaultValue).getN()));
result.put("isPermanent", image.getOrDefault("isPermanent", defaultValue).getBOOL());
More on AttributeValue
, checkout AWS documentation.
Upvotes: 3
Reputation: 728
This can be achieved easily with an inbuilt class ItemUtils. Check the implementation of toSimpleMapValue. The implementation is recursive in nature and it traverses over the schema of Map<String, AttributeValue> and converts it into a simple map object. I simply copied the required methods essential for the transformation.
Upvotes: 3
Reputation: 265221
If the types are compatible, you can create a copy of the map with the correct generic types:
final Map<String, AttributeValue> tmp = record.getDynamodb.getNewImage();
final Map<String, Object> map = new HashMap<>(tmp)
Upvotes: 1