Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@
import software.amazon.awssdk.enhanced.dynamodb.model.PageIterable;
import software.amazon.awssdk.enhanced.dynamodb.model.QueryEnhancedRequest;
import software.amazon.awssdk.enhanced.dynamodb.model.ScanEnhancedRequest;
import software.amazon.awssdk.enhanced.dynamodb.model.UpdateItemEnhancedRequest;

/**
* Interface for simple DynamoDB template operations.
*
* @author Matej Nedic
* @author Marcus Voltolim
* @since 3.0.0
*/
public interface DynamoDbOperations {
Expand All @@ -45,6 +47,14 @@ public interface DynamoDbOperations {
*/
<T> T update(T entity);

/**
* Updates Entity with configurations like ignore null to DynamoDB table.
*
* @param request - UpdateItemEnhancedRequest with entity and configurations to be saved.
* @param <T> Type of Entity object.
*/
<T> T update(UpdateItemEnhancedRequest<T> request);

/**
* Deletes a record for a given Key.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,19 @@
import software.amazon.awssdk.enhanced.dynamodb.model.PageIterable;
import software.amazon.awssdk.enhanced.dynamodb.model.QueryEnhancedRequest;
import software.amazon.awssdk.enhanced.dynamodb.model.ScanEnhancedRequest;
import software.amazon.awssdk.enhanced.dynamodb.model.UpdateItemEnhancedRequest;

/**
* Default implementation of {@link DynamoDbOperations}.
*
* @author Matej Nedic
* @author Arun Patra
* @author Maciej Walkowiak
* @author Marcus Voltolim
* @since 3.0
*/
public class DynamoDbTemplate implements DynamoDbOperations {

private final DynamoDbEnhancedClient dynamoDbEnhancedClient;
private final DynamoDbTableSchemaResolver dynamoDbTableSchemaResolver;
private final DynamoDbTableNameResolver tableNameResolver;
Expand Down Expand Up @@ -66,6 +69,12 @@ public <T> T update(T entity) {
return prepareTable(entity).updateItem(entity);
}

@Override
public <T> T update(UpdateItemEnhancedRequest<T> request) {
Assert.notNull(request, "updateItemEnhancedRequest is required");
return prepareTable(request.item()).updateItem(request);
}

public <T> T delete(Key key, Class<T> clazz) {
Assert.notNull(key, "key is required");
Assert.notNull(clazz, "clazz is required");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Stream;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.model.*;
import software.amazon.awssdk.enhanced.dynamodb.model.PageIterable;
import software.amazon.awssdk.enhanced.dynamodb.model.QueryConditional;
import software.amazon.awssdk.enhanced.dynamodb.model.QueryEnhancedRequest;
Expand All @@ -40,6 +42,7 @@
* @author Matej Nedic
* @author Arun Patra
* @author Artem Bilan
* @author Marcus Voltolim
*/
public class DynamoDbTemplateIntegrationTest implements LocalstackContainerTest {

Expand All @@ -51,7 +54,7 @@ public class DynamoDbTemplateIntegrationTest implements LocalstackContainerTest
private static final String nameOfGSPK = "gsPk";

@BeforeAll
public static void createTable() {
static void createTable() {
DynamoDbClient dynamoDbClient = LocalstackContainerTest.dynamoDbClient();
DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder().dynamoDbClient(dynamoDbClient).build();

Expand Down Expand Up @@ -96,12 +99,36 @@ void dynamoDbTemplate_saveUpdateAndRead_entitySuccessful(DynamoDbTable<PersonEnt
PersonEntity personEntity = new PersonEntity(UUID.randomUUID(), "foo", "bar");
dynamoDbTemplate.save(personEntity);

personEntity.setName(null);
personEntity.setLastName("xxx");
dynamoDbTemplate.update(personEntity);

PersonEntity personEntity1 = dynamoDbTemplate
.load(Key.builder().partitionValue(personEntity.getUuid().toString()).build(), PersonEntity.class);
assertThat(personEntity1).isEqualTo(personEntity);
Key key = Key.builder().partitionValue(personEntity.getUuid().toString()).build();

assertThat(dynamoDbTemplate.load(key, PersonEntity.class))
.extracting(PersonEntity::getName, PersonEntity::getLastName).containsExactly(null, "xxx");

// clean up
cleanUp(dynamoDbTable, personEntity.getUuid());
}

@ParameterizedTest
@MethodSource("argumentSource")
void dynamoDbTemplate_saveUpdateIgnoreNullAndRead_entitySuccessful(DynamoDbTable<PersonEntity> dynamoDbTable,
DynamoDbTemplate dynamoDbTemplate) {
PersonEntity personEntity = new PersonEntity(UUID.randomUUID(), "foo", "bar");
dynamoDbTemplate.save(personEntity);

personEntity.setName(null);
personEntity.setLastName("xxx");
UpdateItemEnhancedRequest<PersonEntity> request = UpdateItemEnhancedRequest.builder(PersonEntity.class)
.item(personEntity).ignoreNullsMode(IgnoreNullsMode.SCALAR_ONLY).build();
dynamoDbTemplate.update(request);

Key key = Key.builder().partitionValue(personEntity.getUuid().toString()).build();

assertThat(dynamoDbTemplate.load(key, PersonEntity.class))
.extracting(PersonEntity::getName, PersonEntity::getLastName).containsExactly("foo", "xxx");

// clean up
cleanUp(dynamoDbTable, personEntity.getUuid());
Expand Down Expand Up @@ -299,16 +326,16 @@ public static void cleanUp(DynamoDbTable<PersonEntity> dynamoDbTable, UUID uuid)
dynamoDbTable.deleteItem(Key.builder().partitionValue(uuid.toString()).build());
}

private static java.util.stream.Stream<Arguments> argumentSource() {
return java.util.stream.Stream.of(Arguments.of(dynamoDbTable, dynamoDbTemplate),
private static Stream<Arguments> argumentSource() {
return Stream.of(Arguments.of(dynamoDbTable, dynamoDbTemplate),
Arguments.of(prefixedDynamoDbTable, prefixedDynamoDbTemplate));
}

private static void describeAndCreateTable(DynamoDbClient dynamoDbClient, @Nullable String tablePrefix) {
ArrayList<AttributeDefinition> attributeDefinitions = new ArrayList<AttributeDefinition>();
ArrayList<AttributeDefinition> attributeDefinitions = new ArrayList<>();
attributeDefinitions.add(AttributeDefinition.builder().attributeName("uuid").attributeType("S").build());
attributeDefinitions.add(AttributeDefinition.builder().attributeName(nameOfGSPK).attributeType("S").build());
ArrayList<KeySchemaElement> tableKeySchema = new ArrayList<KeySchemaElement>();
ArrayList<KeySchemaElement> tableKeySchema = new ArrayList<>();
tableKeySchema.add(KeySchemaElement.builder().attributeName("uuid").keyType(KeyType.HASH).build());
List<KeySchemaElement> indexKeySchema = new ArrayList<>();
indexKeySchema.add(KeySchemaElement.builder().attributeName(nameOfGSPK).keyType(KeyType.HASH).build());
Expand All @@ -332,4 +359,5 @@ private static void describeAndCreateTable(DynamoDbClient dynamoDbClient, @Nulla
// table already exists, do nothing
}
}

}