Groovy Amazon DynamoDB Simple Example

The following is a two class example of Amazon’s DynamoDB. The first class is just a Dao (yes, I still prefer Daos over ARs).


package wookets.dynamo

import com.amazonaws.auth.AWSCredentials
import com.amazonaws.auth.PropertiesCredentials
import com.amazonaws.services.dynamodb.AmazonDynamoDBClient
import com.amazonaws.services.dynamodb.model.AttributeValue
import com.amazonaws.services.dynamodb.model.ComparisonOperator
import com.amazonaws.services.dynamodb.model.DeleteItemRequest
import com.amazonaws.services.dynamodb.model.DeleteItemResult
import com.amazonaws.services.dynamodb.model.GetItemRequest
import com.amazonaws.services.dynamodb.model.GetItemResult
import com.amazonaws.services.dynamodb.model.Key
import com.amazonaws.services.dynamodb.model.PutItemRequest
import com.amazonaws.services.dynamodb.model.PutItemResult

class DynamoDao {

AmazonDynamoDBClient client

DynamoDao() {
InputStream credentialsAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(“AwsCredentials.properties”);
AWSCredentials credentials = new PropertiesCredentials(credentialsAsStream);
client = new AmazonDynamoDBClient(credentials);
}

// save
def save(Object resource) {
String tableName = resource._type
if(resource._type == null) {
throw new RuntimeException(“You need to specify a _type to be able to save data under”)
}

def item = [:]
resource.each { key, value ->
if(key == “_type”) return;
if(value instanceof Number) {
item.put(key, new AttributeValue().withN(value))
} else if(value instanceof String) {
item.put(key, new AttributeValue().withS(value))
} else if(value instanceof List) {
if(value[0] instanceof Number) {
item.put(key, new AttributeValue().withNS(value))
} else if(value[0] instanceof String) {
item.put(key, new AttributeValue().withSS(value))
}
} else {
throw new RuntimeException(“Unsupported data type for property ${resource._type}.${key}“)
}
}

PutItemRequest putItemRequest = new PutItemRequest().withTableName(tableName).withItem(item)
PutItemResult result = client.putItem(putItemRequest)
}

// read
def load(String resourceType, String resourceId) {
Key lookupKey = new Key().withHashKeyElement(new AttributeValue().withS(resourceId))
GetItemRequest getItemRequest = new GetItemRequest().withTableName(resourceType).withKey(lookupKey)

def item = [_type: resourceType, id: resourceId]
GetItemResult result = client.getItem(getItemRequest);
result.item.each { propName, value ->
if(value.getS() != null) {
item[propName] = value.getS()
} else if(value.getN() != null) {
item[propName] = value.getN()
} else if(value.getSS() != null) {
item[propName] = value.getSS()
} else if(value.getNS() != null) {
item[propName] = value.getNS()
}
}
return item
}

// delete
def delete(String resourceType, String resourceId) {
Key key = new Key().withHashKeyElement(new AttributeValue().withS(resourceId));
DeleteItemRequest deleteItemRequest = new DeleteItemRequest().withTableName(resourceType).withKey(key)
DeleteItemResult result = client.deleteItem(deleteItemRequest);
}

}



The next class is the test harness.
package test.dynamo;

import static org.junit.Assert.*

import java.text.SimpleDateFormat

import org.junit.Test

import wookets.dynamo.DynamoDao

class TestDynamoDao {

DynamoDao dynamoDao = new DynamoDao()

static SimpleDateFormat dateFormatter = new SimpleDateFormat(“yyyy-MM-dd’T’HH:mm:ss.SSS’Z’“);

@Test
void testSave() {
def mock = [_type:“dynamomock”, id: “MOCK1”, name: “Namer”, lister: [“Some1”, “Like”, “U”]]
dynamoDao.save(mock)
}

@Test
void testLoad() {
def mock = dynamoDao.load(“dynamomock”, “MOCK1”)
mock.each { prop, value ->
print “${prop}: ${value}, “
}
println “”
}

@Test
void testDelete() {
dynamoDao.delete(“dynamomock”, “MOCK1”)
}

@Test
void testSaveAll() {
dynamoDao.save([_type:“dynamomock”, id: “MOCK1”, name: “Namer”])
dynamoDao.save([_type:“dynamomock”, id: “MOCK2”, name: “Namer2”])
dynamoDao.save([_type:“dynamomock”, id: “MOCK3”, name: “Namer3”])
dynamoDao.save([_type:“dynamomock”, id: “MOCK4”, name: “Namer4”])
dynamoDao.save([_type:“dynamomock”, id: “MOCK5”, name: “Namer5”])
}
@Test
void testLoadAll() {
[“MOCK1”, “MOCK2”, “MOCK3”, “MOCK4”, “MOCK5”].each {
def mock = dynamoDao.load(“dynamomock”, it)
mock.each { prop, value ->
print “${prop}: ${value}, “
}
println “”
}
}
}


Obviously this is a simple use case, but might help you in your travels…

Btw, the properties (credentials file) looks like…

secretKey=
accessKey=



Published by and tagged Code using 436 words.