Skip to content

Commit 950920d

Browse files
committed
DDBEnhanced - Support to flatten a Map into top level attributes of the object
1 parent 28a1d7c commit 950920d

File tree

8 files changed

+204
-780
lines changed

8 files changed

+204
-780
lines changed

services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/functionaltests/FlattenMapTest.java

Lines changed: 199 additions & 83 deletions
Large diffs are not rendered by default.

services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/functionaltests/InvalidFlattenMapTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import org.junit.Test;
2020
import org.junit.rules.ExpectedException;
2121
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
22-
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.flattenmap.MultipleFlattenMapsOnRecordInvalidBean;
22+
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.flattenmap.FlattenMapInvalidBean;
2323

2424
public class InvalidFlattenMapTest extends LocalDynamoDbSyncTestBase {
2525

@@ -31,6 +31,6 @@ public void updateItemWithFlattenMap_withMultipleAnnotatedMaps_throwsIllegalArgu
3131
thrown.expect(IllegalArgumentException.class);
3232
thrown.expectMessage("More than one @DynamoDbFlattenMap annotation found on the same record");
3333

34-
TableSchema.fromClass(MultipleFlattenMapsOnRecordInvalidBean.class);
34+
TableSchema.fromClass(FlattenMapInvalidBean.class);
3535
}
3636
}

services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/mapper/BeanTableSchemaTest.java

Lines changed: 0 additions & 209 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import static software.amazon.awssdk.enhanced.dynamodb.internal.AttributeValues.nullAttributeValue;
2828
import static software.amazon.awssdk.enhanced.dynamodb.internal.AttributeValues.numberValue;
2929
import static software.amazon.awssdk.enhanced.dynamodb.internal.AttributeValues.stringValue;
30-
import static software.amazon.awssdk.enhanced.dynamodb.mapper.StaticAttributeTags.primaryPartitionKey;
3130

3231
import java.nio.charset.StandardCharsets;
3332
import java.util.Arrays;
@@ -36,25 +35,18 @@
3635
import java.util.LinkedHashSet;
3736
import java.util.Map;
3837
import java.util.Optional;
39-
import org.assertj.core.api.Assertions;
4038
import org.junit.Rule;
4139
import org.junit.Test;
4240
import org.junit.rules.ExpectedException;
4341
import org.junit.runner.RunWith;
4442
import org.mockito.junit.MockitoJUnitRunner;
4543
import software.amazon.awssdk.core.SdkBytes;
4644
import software.amazon.awssdk.enhanced.dynamodb.EnhancedType;
47-
import software.amazon.awssdk.enhanced.dynamodb.functionaltests.models.CompositeRecord;
48-
import software.amazon.awssdk.enhanced.dynamodb.functionaltests.models.FakeItem;
49-
import software.amazon.awssdk.enhanced.dynamodb.functionaltests.models.FakeItemComposedClass;
50-
import software.amazon.awssdk.enhanced.dynamodb.functionaltests.models.FlattenRecord;
51-
import software.amazon.awssdk.enhanced.dynamodb.functionaltests.models.NestedRecordWithUpdateBehavior;
5245
import software.amazon.awssdk.enhanced.dynamodb.internal.AttributeValues;
5346
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.AbstractBean;
5447
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.AbstractImmutable;
5548
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.AttributeConverterBean;
5649
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.AttributeConverterNoConstructorBean;
57-
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.flattenmap.BeanWithFlattenRecordAndFlattenMap;
5850
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.CommonTypesBean;
5951
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.DocumentBean;
6052
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.EmptyConverterProvidersInvalidBean;
@@ -63,8 +55,6 @@
6355
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.ExtendedBean;
6456
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.FlattenedBeanBean;
6557
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.FlattenedImmutableBean;
66-
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.flattenmap.FlattenMapValidBean;
67-
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.flattenmap.MultipleFlattenMapsOnRecordInvalidBean;
6858
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.FluentSetterBean;
6959
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.IgnoredAttributeBean;
7060
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.InvalidBean;
@@ -1186,203 +1176,4 @@ public void fluentSetterBean_correctlyMapsBeanAttributes() {
11861176

11871177
assertThat(beanTableSchema.mapToItem(itemMap), is(equalTo(fluentSetterBean)));
11881178
}
1189-
1190-
@Test
1191-
public void itemToMap_withFlattenedMapAndIgnoreNulls_flattensAndOmitNulls() {
1192-
StaticTableSchema<FakeItem> tableSchema = StaticTableSchema.builder(FakeItem.class)
1193-
.flatten("attributesMap",
1194-
FakeItem::getAttributesMap,
1195-
FakeItem::setAttributesMap)
1196-
.build();
1197-
1198-
FakeItem fakeItem = FakeItem.builder()
1199-
.testMap(new HashMap<String, String>() {{
1200-
put("mapAttribute1", "mapValue1");
1201-
put("mapAttribute2", null);
1202-
put("mapAttribute3", null);
1203-
}}).build();
1204-
1205-
Map<String, AttributeValue> itemMap = tableSchema.itemToMap(fakeItem, true);
1206-
1207-
assertThat(itemMap.size(), is(1));
1208-
assertThat(itemMap, hasEntry("mapAttribute1", stringValue("mapValue1")));
1209-
}
1210-
1211-
@Test
1212-
public void itemToMap_withFlattenedMapAndNotIgnoringNulls_flattensAndAndAddNullAttributes() {
1213-
StaticTableSchema<FakeItem> tableSchema = StaticTableSchema.builder(FakeItem.class)
1214-
.flatten("attributesMap",
1215-
FakeItem::getAttributesMap,
1216-
FakeItem::setAttributesMap)
1217-
.build();
1218-
1219-
FakeItem fakeItem = FakeItem.builder()
1220-
.testMap(new HashMap<String, String>() {{
1221-
put("mapAttribute1", "mapValue1");
1222-
put("mapAttribute2", null);
1223-
put("mapAttribute3", null);
1224-
}}).build();
1225-
1226-
Map<String, AttributeValue> itemMap = tableSchema.itemToMap(fakeItem, false);
1227-
1228-
assertThat(itemMap.size(), is(3));
1229-
assertThat(itemMap, hasEntry("mapAttribute1", stringValue("mapValue1")));
1230-
assertThat(itemMap, hasEntry("mapAttribute2", AttributeValue.builder().build()));
1231-
assertThat(itemMap, hasEntry("mapAttribute3", AttributeValue.builder().build()));
1232-
}
1233-
1234-
@Test
1235-
public void itemToMap_withMultipleAnnotatedMaps_throwsIllegalArgumentException() {
1236-
MultipleFlattenMapsOnRecordInvalidBean multipleFlattenMapsOnRecordInvalidBean = new MultipleFlattenMapsOnRecordInvalidBean();
1237-
multipleFlattenMapsOnRecordInvalidBean.setId("idValue");
1238-
multipleFlattenMapsOnRecordInvalidBean.setRootAttribute1("rootValue1");
1239-
multipleFlattenMapsOnRecordInvalidBean.setRootAttribute2("rootValue2");
1240-
1241-
multipleFlattenMapsOnRecordInvalidBean.setAttributesMap(new HashMap<String, String>() {{
1242-
put("mapAttribute1", "mapValue1");
1243-
put("mapAttribute2", "mapValue2");
1244-
put("mapAttribute3", "mapValue3");
1245-
}});
1246-
1247-
multipleFlattenMapsOnRecordInvalidBean.setSecondaryAttributesMap(new HashMap<String, String>() {{
1248-
put("secondaryMapAttribute1", "secondaryMapValue1");
1249-
put("secondaryMapAttribute2", "secondaryMapValue2");
1250-
put("secondaryMapAttribute3", "secondaryMapValue3");
1251-
}});
1252-
1253-
exception.expect(IllegalArgumentException.class);
1254-
exception.expectMessage("More than one @DynamoDbFlattenMap annotation found on the same record");
1255-
1256-
BeanTableSchema<MultipleFlattenMapsOnRecordInvalidBean> beanTableSchema = BeanTableSchema.create(MultipleFlattenMapsOnRecordInvalidBean.class);
1257-
beanTableSchema.itemToMap(multipleFlattenMapsOnRecordInvalidBean, false);
1258-
}
1259-
1260-
@Test
1261-
public void itemToMap_withFlattenRecordAndFlattenMap_mapsAttributes() {
1262-
BeanWithFlattenRecordAndFlattenMap beanWithFlattenRecordAndFlattenMap = new BeanWithFlattenRecordAndFlattenMap();
1263-
beanWithFlattenRecordAndFlattenMap.setRootAttribute1("rootValue1");
1264-
beanWithFlattenRecordAndFlattenMap.setRootAttribute2("rootValue2");
1265-
1266-
FlattenRecord flattenRecord = new FlattenRecord();
1267-
NestedRecordWithUpdateBehavior updateNestedRecord = new NestedRecordWithUpdateBehavior();
1268-
updateNestedRecord.setNestedCounter(100L);
1269-
CompositeRecord updateCompositeRecord = new CompositeRecord();
1270-
updateCompositeRecord.setNestedRecord(updateNestedRecord);
1271-
flattenRecord.setCompositeRecord(updateCompositeRecord);
1272-
beanWithFlattenRecordAndFlattenMap.setFlattenRecord(flattenRecord);
1273-
1274-
beanWithFlattenRecordAndFlattenMap.setAttributesMap(new HashMap<String, String>() {{
1275-
put("mapAttribute1", "mapValue1");
1276-
put("mapAttribute2", "mapValue2");
1277-
put("mapAttribute3", "mapValue3");
1278-
}});
1279-
1280-
1281-
BeanTableSchema<BeanWithFlattenRecordAndFlattenMap> beanTableSchema = BeanTableSchema.create(BeanWithFlattenRecordAndFlattenMap.class);
1282-
Map<String, AttributeValue> itemMap = beanTableSchema.itemToMap(beanWithFlattenRecordAndFlattenMap, true);
1283-
1284-
assertThat(itemMap.size(), is(6));
1285-
assertThat(itemMap, hasEntry("rootAttribute1", stringValue("rootValue1")));
1286-
assertThat(itemMap, hasEntry("rootAttribute2", stringValue("rootValue2")));
1287-
assertThat(itemMap, hasEntry("mapAttribute1", stringValue("mapValue1")));
1288-
assertThat(itemMap, hasEntry("mapAttribute2", stringValue("mapValue2")));
1289-
assertThat(itemMap, hasEntry("mapAttribute3", stringValue("mapValue3")));
1290-
1291-
AttributeValue resultedNestedRecord = itemMap.get("nestedRecord");
1292-
Assertions.assertThat(resultedNestedRecord).isNotNull();
1293-
}
1294-
1295-
@Test
1296-
public void itemToMap_withFlattenedMapAndNotIgnoringNulls_createsItemAndAndAddNullAttributes_withFlattenedMapAndIgnoreNulls_correctlyCreatesItemAndOmitNulls() {
1297-
StaticTableSchema<FakeItem> staticTableSchema =
1298-
StaticTableSchema.builder(FakeItem.class)
1299-
.newItemSupplier(FakeItem::new)
1300-
.flatten(FakeItemComposedClass.getTableSchema(),
1301-
FakeItem::getComposedObject,
1302-
FakeItem::setComposedObject)
1303-
.flatten("attributesMap",
1304-
FakeItem::getAttributesMap,
1305-
FakeItem::setAttributesMap)
1306-
.addAttribute(String.class, a -> a.name("id")
1307-
.getter(FakeItem::getId)
1308-
.setter(FakeItem::setId)
1309-
.addTag(primaryPartitionKey()))
1310-
.addAttribute(Integer.class, a -> a.name("version")
1311-
.getter(FakeItem::getVersion)
1312-
.setter(FakeItem::setVersion))
1313-
.build();
1314-
1315-
FakeItemComposedClass nestedBean = new FakeItemComposedClass();
1316-
FakeItem fakeItem = new FakeItem("1", 1, nestedBean, new HashMap<String, String>() {{
1317-
put("mapAttribute1", "mapValue1");
1318-
put("mapAttribute2", null);
1319-
put("mapAttribute3", null);
1320-
}});
1321-
1322-
Map<String, AttributeValue> itemMap = staticTableSchema.itemToMap(fakeItem, true);
1323-
1324-
assertThat(itemMap.size(), is(3));
1325-
assertThat(itemMap, hasEntry("id", stringValue("1")));
1326-
assertThat(itemMap, hasEntry("version", numberValue(1)));
1327-
assertThat(itemMap, hasEntry("mapAttribute1", stringValue("mapValue1")));
1328-
}
1329-
1330-
@Test
1331-
public void itemToMap_withFlattenedMapAndNotIgnoringNulls_createsItemAndAndAddNullAttributes() {
1332-
StaticTableSchema<FakeItem> staticTableSchema =
1333-
StaticTableSchema.builder(FakeItem.class)
1334-
.newItemSupplier(FakeItem::new)
1335-
.flatten(FakeItemComposedClass.getTableSchema(),
1336-
FakeItem::getComposedObject,
1337-
FakeItem::setComposedObject)
1338-
.flatten("attributesMap",
1339-
FakeItem::getAttributesMap,
1340-
FakeItem::setAttributesMap)
1341-
.addAttribute(String.class, a -> a.name("id")
1342-
.getter(FakeItem::getId)
1343-
.setter(FakeItem::setId)
1344-
.addTag(primaryPartitionKey()))
1345-
.addAttribute(Integer.class, a -> a.name("version")
1346-
.getter(FakeItem::getVersion)
1347-
.setter(FakeItem::setVersion))
1348-
.build();
1349-
1350-
FakeItemComposedClass nestedBean = new FakeItemComposedClass();
1351-
FakeItem fakeItem = new FakeItem("1", 1, nestedBean, new HashMap<String, String>() {{
1352-
put("mapAttribute1", "mapValue1");
1353-
put("mapAttribute2", null);
1354-
put("mapAttribute3", null);
1355-
}});
1356-
1357-
Map<String, AttributeValue> itemMap = staticTableSchema.itemToMap(fakeItem, false);
1358-
1359-
assertThat(itemMap.size(), is(6));
1360-
assertThat(itemMap, hasEntry("id", stringValue("1")));
1361-
assertThat(itemMap, hasEntry("version", numberValue(1)));
1362-
assertThat(itemMap, hasEntry("mapAttribute1", stringValue("mapValue1")));
1363-
assertThat(itemMap, hasEntry("mapAttribute2", AttributeValue.builder().build()));
1364-
assertThat(itemMap, hasEntry("mapAttribute3", AttributeValue.builder().build()));
1365-
}
1366-
1367-
@Test
1368-
public void mapToItem_withFlattenedMap_createsItem() {
1369-
BeanTableSchema<FlattenMapValidBean> beanTableSchema = BeanTableSchema.create(FlattenMapValidBean.class);
1370-
Map<String, AttributeValue> itemMap = new HashMap<>();
1371-
itemMap.put("id", stringValue("123"));
1372-
itemMap.put("rootAttribute1", stringValue("rootAttributeValue1"));
1373-
itemMap.put("rootAttribute2", stringValue("rootAttributeValue2"));
1374-
itemMap.put("mapAttribute1", AttributeValue.builder().s("mapValue1").build());
1375-
itemMap.put("mapAttribute2", AttributeValue.builder().s("mapValue2").build());
1376-
itemMap.put("mapAttribute3", AttributeValue.builder().s("mapValue3").build());
1377-
1378-
FlattenMapValidBean result = beanTableSchema.mapToItem(itemMap);
1379-
1380-
assertThat(result.getId(), is("123"));
1381-
assertThat(result.getRootAttribute1(), is("rootAttributeValue1"));
1382-
assertThat(result.getRootAttribute2(), is("rootAttributeValue2"));
1383-
assertThat(result.getAttributesMap().size(), is(3));
1384-
assertThat(itemMap, hasEntry("mapAttribute1", stringValue("mapValue1")));
1385-
assertThat(itemMap, hasEntry("mapAttribute2", stringValue("mapValue2")));
1386-
assertThat(itemMap, hasEntry("mapAttribute3", stringValue("mapValue3")));
1387-
}
13881179
}

0 commit comments

Comments
 (0)