|
25 | 25 | import org.junit.Test; |
26 | 26 | import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient; |
27 | 27 | import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable; |
| 28 | +import software.amazon.awssdk.enhanced.dynamodb.extensions.annotations.DynamoDbAtomicCounter; |
28 | 29 | import software.amazon.awssdk.enhanced.dynamodb.functionaltests.LocalDynamoDbSyncTestBase; |
| 30 | +import software.amazon.awssdk.enhanced.dynamodb.mapper.BeanTableSchema; |
29 | 31 | import software.amazon.awssdk.enhanced.dynamodb.mapper.StaticTableSchema; |
| 32 | +import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean; |
| 33 | +import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey; |
30 | 34 |
|
31 | 35 | public class AtomicCounterExtensionTest extends LocalDynamoDbSyncTestBase { |
32 | 36 |
|
33 | | - private static final StaticTableSchema<CounterRecord> TABLE_SCHEMA = |
34 | | - StaticTableSchema.builder(CounterRecord.class) |
35 | | - .newItemSupplier(CounterRecord::new) |
| 37 | + private static final StaticTableSchema<StaticCounterRecord> TABLE_SCHEMA = |
| 38 | + StaticTableSchema.builder(StaticCounterRecord.class) |
| 39 | + .newItemSupplier(StaticCounterRecord::new) |
36 | 40 | .addAttribute(String.class, |
37 | 41 | a -> a.name("id1") |
38 | | - .getter(CounterRecord::getId) |
39 | | - .setter(CounterRecord::setId) |
| 42 | + .getter(StaticCounterRecord::getId) |
| 43 | + .setter(StaticCounterRecord::setId) |
40 | 44 | .addTag(primaryPartitionKey())) |
41 | 45 | .addAttribute(String.class, |
42 | 46 | a -> a.name("data") |
43 | | - .getter(CounterRecord::getData) |
44 | | - .setter(CounterRecord::setData)) |
| 47 | + .getter(StaticCounterRecord::getData) |
| 48 | + .setter(StaticCounterRecord::setData)) |
45 | 49 | .addAttribute(Long.class, |
46 | 50 | a -> a.name("defaultCounter") |
47 | | - .getter(CounterRecord::getDefaultCounter) |
48 | | - .setter(CounterRecord::setDefaultCounter) |
| 51 | + .getter(StaticCounterRecord::getDefaultCounter) |
| 52 | + .setter(StaticCounterRecord::setDefaultCounter) |
49 | 53 | .addTag(atomicCounter())) |
50 | 54 | .addAttribute(Long.class, |
51 | 55 | a -> a.name("customCounter") |
52 | | - .getter(CounterRecord::getCustomCounter) |
53 | | - .setter(CounterRecord::setCustomCounter) |
| 56 | + .getter(StaticCounterRecord::getCustomCounter) |
| 57 | + .setter(StaticCounterRecord::setCustomCounter) |
54 | 58 | .addTag(atomicCounter(5, 10))) |
55 | 59 | .build(); |
56 | 60 |
|
57 | 61 | private final DynamoDbEnhancedClient enhancedClient = |
58 | 62 | DynamoDbEnhancedClient.builder().dynamoDbClient(getDynamoDbClient()).build(); |
59 | 63 |
|
60 | | - private final DynamoDbTable<CounterRecord> mappedTable = enhancedClient.table( |
61 | | - getConcreteTableName("atomic-counter-table"), TABLE_SCHEMA); |
| 64 | + private final DynamoDbTable<BeanCounterRecord> beanMappedTable = enhancedClient.table( |
| 65 | + getConcreteTableName("atomic-counter-table-bean"), BeanTableSchema.create(BeanCounterRecord.class)); |
| 66 | + |
| 67 | + private final DynamoDbTable<StaticCounterRecord> staticMappedTable = enhancedClient.table( |
| 68 | + getConcreteTableName("atomic-counter-table-static"), TABLE_SCHEMA); |
62 | 69 |
|
63 | 70 | @Before |
64 | 71 | public void createTable() { |
65 | | - mappedTable.createTable(r -> r.provisionedThroughput(getDefaultProvisionedThroughput())); |
| 72 | + staticMappedTable.createTable(r -> r.provisionedThroughput(getDefaultProvisionedThroughput())); |
| 73 | + beanMappedTable.createTable(r -> r.provisionedThroughput(getDefaultProvisionedThroughput())); |
66 | 74 | } |
67 | 75 |
|
68 | 76 | @After |
69 | 77 | public void deleteTable() { |
70 | 78 | getDynamoDbClient().deleteTable(r -> r.tableName( |
71 | | - getConcreteTableName("atomic-counter-table"))); |
| 79 | + getConcreteTableName("atomic-counter-table-bean"))); |
| 80 | + getDynamoDbClient().deleteTable(r -> r.tableName( |
| 81 | + getConcreteTableName("atomic-counter-table-static"))); |
| 82 | + } |
| 83 | + |
| 84 | + @Test |
| 85 | + public void putItem_beanSchema_initializesCountersWithDefaultValues() { |
| 86 | + BeanCounterRecord beanRecord = new BeanCounterRecord(); |
| 87 | + beanRecord.setId("id"); |
| 88 | + |
| 89 | + beanMappedTable.putItem(beanRecord); |
| 90 | + |
| 91 | + BeanCounterRecord retrieved = beanMappedTable.getItem(r -> r.key(k -> k.partitionValue("id"))); |
| 92 | + assertThat(retrieved).isNotNull(); |
| 93 | + assertThat(retrieved.getId()).isEqualTo("id"); |
| 94 | + assertThat(retrieved.getDefaultCounter()).isEqualTo(0L); |
| 95 | + assertThat(retrieved.getCustomCounter()).isEqualTo(10L); |
| 96 | + } |
| 97 | + |
| 98 | + @Test |
| 99 | + public void updateItem_beanSchema_incrementsCounters() { |
| 100 | + BeanCounterRecord beanRecord = new BeanCounterRecord(); |
| 101 | + beanRecord.setId("id1"); |
| 102 | + beanRecord.setData("data1"); |
| 103 | + beanMappedTable.putItem(beanRecord); |
| 104 | + |
| 105 | + BeanCounterRecord update = new BeanCounterRecord(); |
| 106 | + update.setId("id1"); |
| 107 | + update.setData("data2"); |
| 108 | + beanMappedTable.updateItem(update); |
| 109 | + |
| 110 | + BeanCounterRecord retrieved = beanMappedTable.getItem(r -> r.key(k -> k.partitionValue("id1"))); |
| 111 | + assertThat(retrieved).isNotNull(); |
| 112 | + assertThat(retrieved.getData()).isEqualTo("data2"); |
| 113 | + assertThat(retrieved.getDefaultCounter()).isEqualTo(1L); |
| 114 | + assertThat(retrieved.getCustomCounter()).isEqualTo(15L); |
| 115 | + } |
| 116 | + |
| 117 | + @Test |
| 118 | + public void updateItem_beanSchema_multipleUpdates_incrementsCountersCorrectly() { |
| 119 | + BeanCounterRecord record = new BeanCounterRecord(); |
| 120 | + record.setId("id1"); |
| 121 | + record.setData("data1"); |
| 122 | + beanMappedTable.putItem(record); |
| 123 | + |
| 124 | + for (int i = 2; i <= 10; i++) { |
| 125 | + BeanCounterRecord update = new BeanCounterRecord(); |
| 126 | + update.setId("id1"); |
| 127 | + update.setData(String.format("data%d", i)); |
| 128 | + beanMappedTable.updateItem(update); |
| 129 | + } |
| 130 | + |
| 131 | + BeanCounterRecord retrieved = beanMappedTable.getItem(r -> r.key(k -> k.partitionValue("id1"))); |
| 132 | + assertThat(retrieved).isNotNull(); |
| 133 | + assertThat(retrieved.getData()).isEqualTo("data10"); |
| 134 | + assertThat(retrieved.getDefaultCounter()).isEqualTo(9L); |
| 135 | + assertThat(retrieved.getCustomCounter()).isEqualTo(55L); |
| 136 | + } |
| 137 | + |
| 138 | + @Test |
| 139 | + public void putItem_beanSchema_withExistingCounterValues_overwritesWithStartValues() { |
| 140 | + BeanCounterRecord record = new BeanCounterRecord(); |
| 141 | + record.setId("id1"); |
| 142 | + record.setDefaultCounter(100L); |
| 143 | + record.setCustomCounter(200L); |
| 144 | + |
| 145 | + beanMappedTable.putItem(record); |
| 146 | + |
| 147 | + BeanCounterRecord retrieved = beanMappedTable.getItem(r -> r.key(k -> k.partitionValue("id1"))); |
| 148 | + assertThat(retrieved).isNotNull(); |
| 149 | + assertThat(retrieved.getDefaultCounter()).isEqualTo(0L); |
| 150 | + assertThat(retrieved.getCustomCounter()).isEqualTo(10L); |
72 | 151 | } |
73 | 152 |
|
74 | 153 | @Test |
75 | | - public void putItem_initializesCountersWithDefaultValues() { |
76 | | - CounterRecord record = new CounterRecord(); |
| 154 | + public void putItem_staticSchema_initializesCountersWithDefaultValues() { |
| 155 | + StaticCounterRecord record = new StaticCounterRecord(); |
77 | 156 | record.setId("id1"); |
78 | 157 |
|
79 | | - mappedTable.putItem(record); |
| 158 | + staticMappedTable.putItem(record); |
80 | 159 |
|
81 | | - CounterRecord retrieved = mappedTable.getItem(r -> r.key(k -> k.partitionValue("id1"))); |
| 160 | + StaticCounterRecord retrieved = staticMappedTable.getItem(r -> r.key(k -> k.partitionValue("id1"))); |
82 | 161 | assertThat(retrieved).isNotNull(); |
83 | 162 | assertThat(retrieved.getId()).isEqualTo("id1"); |
84 | 163 | assertThat(retrieved.getDefaultCounter()).isEqualTo(0L); |
85 | 164 | assertThat(retrieved.getCustomCounter()).isEqualTo(10L); |
86 | 165 | } |
87 | 166 |
|
88 | 167 | @Test |
89 | | - public void updateItem_incrementsCounters() { |
90 | | - CounterRecord record = new CounterRecord(); |
| 168 | + public void updateItem_staticSchema_incrementsCounters() { |
| 169 | + StaticCounterRecord record = new StaticCounterRecord(); |
91 | 170 | record.setId("id1"); |
92 | 171 | record.setData("data1"); |
93 | | - mappedTable.putItem(record); |
| 172 | + staticMappedTable.putItem(record); |
94 | 173 |
|
95 | | - CounterRecord update = new CounterRecord(); |
| 174 | + StaticCounterRecord update = new StaticCounterRecord(); |
96 | 175 | update.setId("id1"); |
97 | 176 | update.setData("data2"); |
98 | | - mappedTable.updateItem(update); |
| 177 | + staticMappedTable.updateItem(update); |
99 | 178 |
|
100 | | - CounterRecord retrieved = mappedTable.getItem(r -> r.key(k -> k.partitionValue("id1"))); |
| 179 | + StaticCounterRecord retrieved = staticMappedTable.getItem(r -> r.key(k -> k.partitionValue("id1"))); |
101 | 180 | assertThat(retrieved).isNotNull(); |
102 | 181 | assertThat(retrieved.getData()).isEqualTo("data2"); |
103 | 182 | assertThat(retrieved.getDefaultCounter()).isEqualTo(1L); |
104 | 183 | assertThat(retrieved.getCustomCounter()).isEqualTo(15L); |
105 | 184 | } |
106 | 185 |
|
107 | 186 | @Test |
108 | | - public void updateItem_multipleUpdates_incrementsCountersCorrectly() { |
109 | | - CounterRecord record = new CounterRecord(); |
| 187 | + public void updateItem_staticSchema_multipleUpdates_incrementsCountersCorrectly() { |
| 188 | + StaticCounterRecord record = new StaticCounterRecord(); |
110 | 189 | record.setId("id1"); |
111 | 190 | record.setData("data1"); |
112 | | - mappedTable.putItem(record); |
| 191 | + staticMappedTable.putItem(record); |
113 | 192 |
|
114 | 193 | for (int i = 2; i <= 10; i++) { |
115 | | - CounterRecord update = new CounterRecord(); |
| 194 | + StaticCounterRecord update = new StaticCounterRecord(); |
116 | 195 | update.setId("id1"); |
117 | 196 | update.setData(String.format("data%d", i)); |
118 | | - mappedTable.updateItem(update); |
| 197 | + staticMappedTable.updateItem(update); |
119 | 198 | } |
120 | 199 |
|
121 | | - CounterRecord retrieved = mappedTable.getItem(r -> r.key(k -> k.partitionValue("id1"))); |
| 200 | + StaticCounterRecord retrieved = staticMappedTable.getItem(r -> r.key(k -> k.partitionValue("id1"))); |
122 | 201 | assertThat(retrieved).isNotNull(); |
123 | 202 | assertThat(retrieved.getData()).isEqualTo("data10"); |
124 | 203 | assertThat(retrieved.getDefaultCounter()).isEqualTo(9L); |
125 | 204 | assertThat(retrieved.getCustomCounter()).isEqualTo(55L); |
126 | 205 | } |
127 | 206 |
|
128 | 207 | @Test |
129 | | - public void putItem_withExistingCounterValues_overwritesWithStartValues() { |
130 | | - CounterRecord record = new CounterRecord(); |
| 208 | + public void putItem_staticSchema_withExistingCounterValues_overwritesWithStartValues() { |
| 209 | + StaticCounterRecord record = new StaticCounterRecord(); |
131 | 210 | record.setId("id1"); |
132 | 211 | record.setDefaultCounter(100L); |
133 | 212 | record.setCustomCounter(200L); |
134 | 213 |
|
135 | | - mappedTable.putItem(record); |
| 214 | + staticMappedTable.putItem(record); |
136 | 215 |
|
137 | | - CounterRecord retrieved = mappedTable.getItem(r -> r.key(k -> k.partitionValue("id1"))); |
| 216 | + StaticCounterRecord retrieved = staticMappedTable.getItem(r -> r.key(k -> k.partitionValue("id1"))); |
138 | 217 | assertThat(retrieved).isNotNull(); |
139 | 218 | assertThat(retrieved.getDefaultCounter()).isEqualTo(0L); |
140 | 219 | assertThat(retrieved.getCustomCounter()).isEqualTo(10L); |
141 | 220 | } |
142 | 221 |
|
143 | | - public static class CounterRecord { |
| 222 | + @DynamoDbBean |
| 223 | + public static class BeanCounterRecord { |
| 224 | + private String id; |
| 225 | + private String data; |
| 226 | + private Long defaultCounter; |
| 227 | + private Long customCounter; |
| 228 | + |
| 229 | + @DynamoDbPartitionKey |
| 230 | + public String getId() { |
| 231 | + return id; |
| 232 | + } |
| 233 | + |
| 234 | + public void setId(String id) { |
| 235 | + this.id = id; |
| 236 | + } |
| 237 | + |
| 238 | + public String getData() { |
| 239 | + return data; |
| 240 | + } |
| 241 | + |
| 242 | + public void setData(String data) { |
| 243 | + this.data = data; |
| 244 | + } |
| 245 | + |
| 246 | + @DynamoDbAtomicCounter |
| 247 | + public Long getDefaultCounter() { |
| 248 | + return defaultCounter; |
| 249 | + } |
| 250 | + |
| 251 | + public void setDefaultCounter(Long defaultCounter) { |
| 252 | + this.defaultCounter = defaultCounter; |
| 253 | + } |
| 254 | + |
| 255 | + @DynamoDbAtomicCounter(delta = 5, startValue = 10) |
| 256 | + public Long getCustomCounter() { |
| 257 | + return customCounter; |
| 258 | + } |
| 259 | + |
| 260 | + public void setCustomCounter(Long customCounter) { |
| 261 | + this.customCounter = customCounter; |
| 262 | + } |
| 263 | + |
| 264 | + @Override |
| 265 | + public boolean equals(Object o) { |
| 266 | + if (this == o) { |
| 267 | + return true; |
| 268 | + } |
| 269 | + if (o == null || getClass() != o.getClass()) { |
| 270 | + return false; |
| 271 | + } |
| 272 | + StaticCounterRecord that = (StaticCounterRecord) o; |
| 273 | + return Objects.equals(id, that.id) |
| 274 | + && Objects.equals(data, that.data) |
| 275 | + && Objects.equals(defaultCounter, that.defaultCounter) |
| 276 | + && Objects.equals(customCounter, that.customCounter); |
| 277 | + } |
| 278 | + |
| 279 | + @Override |
| 280 | + public int hashCode() { |
| 281 | + return Objects.hash(id, defaultCounter, customCounter); |
| 282 | + } |
| 283 | + } |
| 284 | + |
| 285 | + public static class StaticCounterRecord { |
144 | 286 | private String id; |
145 | 287 | private String data; |
146 | 288 | private Long defaultCounter; |
@@ -186,7 +328,7 @@ public boolean equals(Object o) { |
186 | 328 | if (o == null || getClass() != o.getClass()) { |
187 | 329 | return false; |
188 | 330 | } |
189 | | - CounterRecord that = (CounterRecord) o; |
| 331 | + StaticCounterRecord that = (StaticCounterRecord) o; |
190 | 332 | return Objects.equals(id, that.id) |
191 | 333 | && Objects.equals(data, that.data) |
192 | 334 | && Objects.equals(defaultCounter, that.defaultCounter) |
|
0 commit comments