13
13
* permissions and limitations under the License.
14
14
*/
15
15
16
+
16
17
package software .amazon .awssdk .enhanced .dynamodb ;
17
18
18
- import static org .assertj .core .api .Assertions .as ;
19
19
import static org .assertj .core .api .Assertions .assertThat ;
20
20
import static org .assertj .core .api .Assertions .assertThatThrownBy ;
21
21
31
31
import software .amazon .awssdk .enhanced .dynamodb .model .PutItemEnhancedRequest ;
32
32
import software .amazon .awssdk .enhanced .dynamodb .model .PutItemEnhancedResponse ;
33
33
import software .amazon .awssdk .enhanced .dynamodb .model .Record ;
34
+ import software .amazon .awssdk .enhanced .dynamodb .model .RecordWithVersion ;
35
+ import software .amazon .awssdk .enhanced .dynamodb .model .TransactWriteItemsEnhancedRequest ;
34
36
import software .amazon .awssdk .enhanced .dynamodb .model .UpdateItemEnhancedRequest ;
35
37
import software .amazon .awssdk .enhanced .dynamodb .model .UpdateItemEnhancedResponse ;
36
38
import software .amazon .awssdk .services .dynamodb .DynamoDbAsyncClient ;
41
43
import software .amazon .awssdk .services .dynamodb .model .ReturnItemCollectionMetrics ;
42
44
import software .amazon .awssdk .services .dynamodb .model .ReturnValue ;
43
45
import software .amazon .awssdk .services .dynamodb .model .ReturnValuesOnConditionCheckFailure ;
46
+ import software .amazon .awssdk .services .dynamodb .model .TransactionCanceledException ;
44
47
45
48
public class AsyncCrudWithResponseIntegrationTest extends DynamoDbEnhancedIntegrationTestBase {
46
49
@@ -56,13 +59,15 @@ public class AsyncCrudWithResponseIntegrationTest extends DynamoDbEnhancedIntegr
56
59
private static DynamoDbAsyncClient dynamoDbClient ;
57
60
private static DynamoDbEnhancedAsyncClient enhancedClient ;
58
61
private static DynamoDbAsyncTable <Record > mappedTable ;
62
+ private static DynamoDbAsyncTable <RecordWithVersion > recordWithVersionMappedTable ;
59
63
60
64
@ BeforeClass
61
65
public static void beforeClass () {
62
66
dynamoDbClient = createAsyncDynamoDbClient ();
63
67
enhancedClient = DynamoDbEnhancedAsyncClient .builder ().dynamoDbClient (dynamoDbClient ).build ();
64
68
mappedTable = enhancedClient .table (TABLE_NAME , TABLE_SCHEMA );
65
69
mappedTable .createTable (r -> r .localSecondaryIndices (LOCAL_SECONDARY_INDEX )).join ();
70
+ recordWithVersionMappedTable = enhancedClient .table (TABLE_NAME , RECORD_WITH_VERSION_TABLE_SCHEMA );
66
71
dynamoDbClient .waiter ().waitUntilTableExists (r -> r .tableName (TABLE_NAME )).join ();
67
72
}
68
73
@@ -113,8 +118,8 @@ public void putItem_returnItemCollectionMetrics_set_itemCollectionMetricsNotNull
113
118
public void updateItem_returnItemCollectionMetrics_set_itemCollectionMetricsNull () {
114
119
Record record = new Record ().setId ("1" ).setSort (10 );
115
120
UpdateItemEnhancedRequest <Record > request = UpdateItemEnhancedRequest .builder (Record .class )
116
- .item (record )
117
- .build ();
121
+ .item (record )
122
+ .build ();
118
123
119
124
UpdateItemEnhancedResponse <Record > response = mappedTable .updateItemWithResponse (request ).join ();
120
125
@@ -196,8 +201,8 @@ public void updateItem_returnValues_all_old() {
196
201
197
202
198
203
UpdateItemEnhancedResponse <Record > response = mappedTable .updateItemWithResponse (r -> r .item (updatedRecord )
199
- .returnValues (ReturnValue .ALL_OLD ))
200
- .join ();
204
+ .returnValues (ReturnValue .ALL_OLD ))
205
+ .join ();
201
206
202
207
assertThat (response .attributes ().getId ()).isEqualTo (record .getId ());
203
208
assertThat (response .attributes ().getSort ()).isEqualTo (record .getSort ());
@@ -341,4 +346,167 @@ public void getItem_withoutReturnConsumedCapacity() {
341
346
GetItemEnhancedResponse <Record > response = mappedTable .getItemWithResponse (req -> req .key (key )).join ();
342
347
assertThat (response .consumedCapacity ()).isNull ();
343
348
}
349
+
350
+ @ Test
351
+ public void deleteItemWithoutVersion_andOptimisticLockingEnabled_shouldSucceed () {
352
+ Record originalItem = new Record ().setId ("123" ).setSort (10 ).setStringAttribute ("Original Item" );
353
+ Key recordKey = Key .builder ()
354
+ .partitionValue (originalItem .getId ())
355
+ .sortValue (originalItem .getSort ())
356
+ .build ();
357
+ mappedTable .putItem (originalItem ).join ();
358
+
359
+ // Retrieve the item
360
+ Record retrievedItem = mappedTable .getItem (r -> r .key (recordKey )).join ();
361
+
362
+ // Delete the item using a transaction
363
+ TransactWriteItemsEnhancedRequest request =
364
+ TransactWriteItemsEnhancedRequest .builder ()
365
+ .addDeleteItem (mappedTable , retrievedItem )
366
+ .build ();
367
+
368
+ enhancedClient .transactWriteItems (request ).join ();
369
+
370
+ Record deletedItem = mappedTable .getItem (r -> r .key (recordKey )).join ();
371
+ assertThat (deletedItem ).isNull ();
372
+ }
373
+
374
+ @ Test
375
+ public void deleteItemWithoutVersion_andOptimisticLockingDisabled_shouldSucceed () {
376
+ Record originalItem = new Record ().setId ("123" ).setSort (10 ).setStringAttribute ("Original Item" );
377
+ Key recordKey = Key .builder ()
378
+ .partitionValue (originalItem .getId ())
379
+ .sortValue (originalItem .getSort ())
380
+ .build ();
381
+ mappedTable .putItem (originalItem ).join ();
382
+
383
+ // Retrieve the item
384
+ Record retrievedItem = mappedTable .getItem (r -> r .key (recordKey )).join ();
385
+
386
+ // Delete the item using a transaction
387
+ TransactWriteItemsEnhancedRequest request =
388
+ TransactWriteItemsEnhancedRequest .builder ()
389
+ .addDeleteItem (mappedTable , retrievedItem )
390
+ .build ();
391
+
392
+ enhancedClient .transactWriteItems (request ).join ();
393
+
394
+ Record deletedItem = mappedTable .getItem (r -> r .key (recordKey )).join ();
395
+ assertThat (deletedItem ).isNull ();
396
+ }
397
+
398
+ @ Test
399
+ public void deleteItemWithVersion_andOptimisticLockingEnabled_ifVersionMatch_shouldSucceed () {
400
+ RecordWithVersion originalItem = new RecordWithVersion ().setId ("123" ).setSort (10 ).setStringAttribute ("Original Item" );
401
+ Key recordKey = Key .builder ()
402
+ .partitionValue (originalItem .getId ())
403
+ .sortValue (originalItem .getSort ())
404
+ .build ();
405
+ recordWithVersionMappedTable .putItem (originalItem ).join ();
406
+
407
+ // Retrieve the item
408
+ RecordWithVersion retrievedItem = recordWithVersionMappedTable .getItem (r -> r .key (recordKey )).join ();
409
+
410
+ // Delete the item using a transaction
411
+ TransactWriteItemsEnhancedRequest request =
412
+ TransactWriteItemsEnhancedRequest .builder ()
413
+ .addDeleteItem (recordWithVersionMappedTable , retrievedItem )
414
+ .build ();
415
+
416
+ enhancedClient .transactWriteItems (request ).join ();
417
+
418
+ RecordWithVersion deletedItem = recordWithVersionMappedTable .getItem (r -> r .key (recordKey )).join ();
419
+ assertThat (deletedItem ).isNull ();
420
+ }
421
+
422
+ @ Test
423
+ public void deleteItemWithVersion_andOptimisticLockingEnabled_ifVersionMismatch_shouldFail () {
424
+ RecordWithVersion originalItem = new RecordWithVersion ().setId ("123" ).setSort (10 ).setStringAttribute ("Original Item" );
425
+ Key recordKey = Key .builder ()
426
+ .partitionValue (originalItem .getId ())
427
+ .sortValue (originalItem .getSort ())
428
+ .build ();
429
+
430
+ recordWithVersionMappedTable .putItem (originalItem ).join ();
431
+
432
+ // Retrieve the item and modify it separately
433
+ RecordWithVersion modifiedItem = recordWithVersionMappedTable .getItem (r -> r .key (recordKey )).join ();
434
+ modifiedItem .setStringAttribute ("Updated Item" );
435
+
436
+ // Update the item, which will increment the version
437
+ recordWithVersionMappedTable .updateItem (modifiedItem );
438
+
439
+
440
+ // Now attempt to delete the original item using a transaction
441
+ TransactWriteItemsEnhancedRequest request =
442
+ TransactWriteItemsEnhancedRequest .builder ()
443
+ .addDeleteItem (recordWithVersionMappedTable , modifiedItem )
444
+ .build ();
445
+
446
+ // enhancedClient.transactWriteItems(request).join();
447
+
448
+ assertThatThrownBy (() -> enhancedClient .transactWriteItems (request ).join ())
449
+ .isInstanceOf (CompletionException .class )
450
+ .satisfies (e ->
451
+ assertThat (((TransactionCanceledException ) e .getCause ())
452
+ .cancellationReasons ()
453
+ .stream ()
454
+ .anyMatch (reason ->
455
+ "ConditionalCheckFailed" .equals (reason .code ())
456
+ && "The conditional request failed" .equals (reason .message ())))
457
+ .isTrue ());
458
+ }
459
+
460
+ @ Test
461
+ public void deleteItemWithVersion_andOptimisticLockingDisabled_ifVersionMatch_shouldSucceed () {
462
+ RecordWithVersion originalItem = new RecordWithVersion ().setId ("123" ).setSort (10 ).setStringAttribute ("Original Item" );
463
+ Key recordKey = Key .builder ()
464
+ .partitionValue (originalItem .getId ())
465
+ .sortValue (originalItem .getSort ())
466
+ .build ();
467
+ recordWithVersionMappedTable .putItem (originalItem ).join ();
468
+
469
+ // Retrieve the item
470
+ RecordWithVersion retrievedItem = recordWithVersionMappedTable .getItem (r -> r .key (recordKey )).join ();
471
+
472
+ // Delete the item using a transaction
473
+ TransactWriteItemsEnhancedRequest request =
474
+ TransactWriteItemsEnhancedRequest .builder ()
475
+ .addDeleteItem (recordWithVersionMappedTable , retrievedItem )
476
+ .build ();
477
+
478
+ enhancedClient .transactWriteItems (request ).join ();
479
+
480
+ RecordWithVersion deletedItem = recordWithVersionMappedTable .getItem (r -> r .key (recordKey )).join ();
481
+ assertThat (deletedItem ).isNull ();
482
+ }
483
+
484
+ @ Test
485
+ public void deleteItemWithVersion_andOptimisticLockingDisabled_ifVersionMismatch_shouldSucceed () {
486
+ RecordWithVersion originalItem = new RecordWithVersion ().setId ("123" ).setSort (10 ).setStringAttribute ("Original Item" );
487
+ Key recordKey = Key .builder ()
488
+ .partitionValue (originalItem .getId ())
489
+ .sortValue (originalItem .getSort ())
490
+ .build ();
491
+
492
+ recordWithVersionMappedTable .putItem (originalItem ).join ();
493
+
494
+ // Retrieve the item and modify it separately
495
+ RecordWithVersion modifiedItem = recordWithVersionMappedTable .getItem (r -> r .key (recordKey )).join ();
496
+ modifiedItem .setStringAttribute ("Updated Item" );
497
+
498
+ // Update the item, which will increment the version
499
+ recordWithVersionMappedTable .updateItem (modifiedItem );
500
+
501
+ // Now attempt to delete the original item using a transaction
502
+ TransactWriteItemsEnhancedRequest request =
503
+ TransactWriteItemsEnhancedRequest .builder ()
504
+ .addDeleteItem (recordWithVersionMappedTable , modifiedItem )
505
+ .build ();
506
+
507
+ enhancedClient .transactWriteItems (request ).join ();
508
+
509
+ RecordWithVersion deletedItem = recordWithVersionMappedTable .getItem (r -> r .key (recordKey )).join ();
510
+ assertThat (deletedItem ).isNull ();
511
+ }
344
512
}
0 commit comments