Skip to content

Commit 824e670

Browse files
authored
Adds count, scanned count and consumed capacity to DDB Enhanced Page (#4444)
* Adds count, scanned count and consumed capacity to DDB Enhanced Page * Add javadoc
1 parent 5ea3c40 commit 824e670

22 files changed

+1070
-1381
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"type": "feature",
3+
"category": "DynamoDB Enhanced Client",
4+
"contributor": "",
5+
"description": "Adds count, scanned count and returned consumed capacity to Page, used by Scan and Query operations"
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.awssdk.enhanced.dynamodb;
17+
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
import static software.amazon.awssdk.enhanced.dynamodb.mapper.StaticAttributeTags.secondaryPartitionKey;
20+
import static software.amazon.awssdk.enhanced.dynamodb.mapper.StaticAttributeTags.secondarySortKey;
21+
22+
import org.assertj.core.data.Offset;
23+
import org.junit.AfterClass;
24+
import org.junit.BeforeClass;
25+
import org.junit.Test;
26+
import software.amazon.awssdk.enhanced.dynamodb.model.DeleteItemEnhancedResponse;
27+
import software.amazon.awssdk.enhanced.dynamodb.model.EnhancedLocalSecondaryIndex;
28+
import software.amazon.awssdk.enhanced.dynamodb.model.GetItemEnhancedResponse;
29+
import software.amazon.awssdk.enhanced.dynamodb.model.PutItemEnhancedRequest;
30+
import software.amazon.awssdk.enhanced.dynamodb.model.PutItemEnhancedResponse;
31+
import software.amazon.awssdk.enhanced.dynamodb.model.Record;
32+
import software.amazon.awssdk.enhanced.dynamodb.model.UpdateItemEnhancedRequest;
33+
import software.amazon.awssdk.enhanced.dynamodb.model.UpdateItemEnhancedResponse;
34+
import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient;
35+
import software.amazon.awssdk.services.dynamodb.model.ConsumedCapacity;
36+
import software.amazon.awssdk.services.dynamodb.model.Projection;
37+
import software.amazon.awssdk.services.dynamodb.model.ProjectionType;
38+
import software.amazon.awssdk.services.dynamodb.model.ReturnConsumedCapacity;
39+
import software.amazon.awssdk.services.dynamodb.model.ReturnItemCollectionMetrics;
40+
41+
public class AsyncCrudWithResponseIntegrationTest extends DynamoDbEnhancedIntegrationTestBase {
42+
43+
44+
private static final String TABLE_NAME = createTestTableName();
45+
46+
47+
private static final EnhancedLocalSecondaryIndex LOCAL_SECONDARY_INDEX = EnhancedLocalSecondaryIndex.builder()
48+
.indexName("index1")
49+
.projection(Projection.builder()
50+
.projectionType(ProjectionType.ALL)
51+
.build())
52+
.build();
53+
54+
private static DynamoDbAsyncClient dynamoDbClient;
55+
private static DynamoDbEnhancedAsyncClient enhancedClient;
56+
private static DynamoDbAsyncTable<Record> mappedTable;
57+
58+
@BeforeClass
59+
public static void setup() {
60+
dynamoDbClient = createAsyncDynamoDbClient();
61+
enhancedClient = DynamoDbEnhancedAsyncClient.builder().dynamoDbClient(dynamoDbClient).build();
62+
mappedTable = enhancedClient.table(TABLE_NAME, TABLE_SCHEMA);
63+
mappedTable.createTable(r -> r.localSecondaryIndices(LOCAL_SECONDARY_INDEX)).join();
64+
dynamoDbClient.waiter().waitUntilTableExists(r -> r.tableName(TABLE_NAME)).join();
65+
}
66+
67+
@AfterClass
68+
public static void teardown() {
69+
try {
70+
dynamoDbClient.deleteTable(r -> r.tableName(TABLE_NAME)).join();
71+
} finally {
72+
dynamoDbClient.close();
73+
}
74+
}
75+
76+
77+
@Test
78+
public void putItem_returnItemCollectionMetrics_set_itemCollectionMetricsNull() {
79+
Record record = new Record().setId("1").setSort(10);
80+
PutItemEnhancedRequest<Record> request = PutItemEnhancedRequest.builder(Record.class)
81+
.item(record)
82+
.build();
83+
84+
PutItemEnhancedResponse<Record> response = mappedTable.putItemWithResponse(request).join();
85+
86+
assertThat(response.itemCollectionMetrics()).isNull();
87+
}
88+
89+
@Test
90+
public void putItem_returnItemCollectionMetrics_set_itemCollectionMetricsNotNull() {
91+
Record record = new Record().setId("1").setSort(10);
92+
PutItemEnhancedRequest<Record> request = PutItemEnhancedRequest.builder(Record.class)
93+
.item(record)
94+
.returnItemCollectionMetrics(ReturnItemCollectionMetrics.SIZE)
95+
.build();
96+
97+
PutItemEnhancedResponse<Record> response = mappedTable.putItemWithResponse(request).join();
98+
99+
assertThat(response.itemCollectionMetrics()).isNotNull();
100+
}
101+
102+
@Test
103+
public void updateItem_returnItemCollectionMetrics_set_itemCollectionMetricsNull() {
104+
Record record = new Record().setId("1").setSort(10);
105+
UpdateItemEnhancedRequest<Record> request = UpdateItemEnhancedRequest.builder(Record.class)
106+
.item(record)
107+
.build();
108+
109+
UpdateItemEnhancedResponse<Record> response = mappedTable.updateItemWithResponse(request).join();
110+
111+
assertThat(response.itemCollectionMetrics()).isNull();
112+
}
113+
114+
@Test
115+
public void updateItem_returnItemCollectionMetrics_set_itemCollectionMetricsNotNull() {
116+
Record record = new Record().setId("1").setSort(10);
117+
UpdateItemEnhancedRequest<Record> request = UpdateItemEnhancedRequest.builder(Record.class)
118+
.item(record)
119+
.returnItemCollectionMetrics(ReturnItemCollectionMetrics.SIZE)
120+
.build();
121+
122+
UpdateItemEnhancedResponse<Record> response = mappedTable.updateItemWithResponse(request).join();
123+
124+
assertThat(response.itemCollectionMetrics()).isNotNull();
125+
}
126+
127+
@Test
128+
public void deleteItem_returnConsumedCapacity_unset_consumedCapacityNull() {
129+
Key key = Key.builder().partitionValue("1").sortValue(10).build();
130+
131+
DeleteItemEnhancedResponse<Record> response = mappedTable.deleteItemWithResponse(r -> r.key(key)).join();
132+
133+
assertThat(response.consumedCapacity()).isNull();
134+
}
135+
136+
@Test
137+
public void deleteItem_returnConsumedCapacity_set_consumedCapacityNotNull() {
138+
Key key = Key.builder().partitionValue("1").sortValue(10).build();
139+
140+
DeleteItemEnhancedResponse<Record> response =
141+
mappedTable.deleteItemWithResponse(r -> r.key(key).returnConsumedCapacity(ReturnConsumedCapacity.TOTAL)).join();
142+
143+
assertThat(response.consumedCapacity()).isNotNull();
144+
}
145+
146+
@Test
147+
public void delete_returnItemCollectionMetrics_set_itemCollectionMetricsNotNull() {
148+
Key key = Key.builder().partitionValue("1").sortValue(10).build();
149+
150+
DeleteItemEnhancedResponse<Record> response =
151+
mappedTable.deleteItemWithResponse(r -> r.key(key).returnItemCollectionMetrics(ReturnItemCollectionMetrics.SIZE))
152+
.join();
153+
154+
assertThat(response.itemCollectionMetrics()).isNotNull();
155+
}
156+
157+
@Test
158+
public void getItem_withoutReturnConsumedCapacity() {
159+
Record record = new Record().setId("101").setSort(102).setStringAttribute(getStringAttrValue(80_000));
160+
Key key = Key.builder()
161+
.partitionValue(record.getId())
162+
.sortValue(record.getSort())
163+
.build();
164+
165+
GetItemEnhancedResponse<Record> response = mappedTable.getItemWithResponse(req -> req.key(key)).join();
166+
assertThat(response.consumedCapacity()).isNull();
167+
}
168+
169+
@Test
170+
public void getItem_withReturnConsumedCapacity_eventualConsistent() {
171+
Record record = new Record().setId("101").setSort(102).setStringAttribute(getStringAttrValue(80 * 1024));
172+
Key key = Key.builder()
173+
.partitionValue(record.getId())
174+
.sortValue(record.getSort())
175+
.build();
176+
mappedTable.putItem(record).join();
177+
178+
GetItemEnhancedResponse<Record> response = mappedTable.getItemWithResponse(
179+
req -> req.key(key).returnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
180+
).join();
181+
ConsumedCapacity consumedCapacity = response.consumedCapacity();
182+
assertThat(consumedCapacity).isNotNull();
183+
// An eventually consistent read request of an item up to 4 KB requires one-half read request unit.
184+
assertThat(consumedCapacity.capacityUnits()).isCloseTo(10.0, Offset.offset(1.0));
185+
}
186+
187+
@Test
188+
public void getItem_withReturnConsumedCapacity_stronglyConsistent() {
189+
Record record = new Record().setId("201").setSort(202).setStringAttribute(getStringAttrValue(80 * 1024));
190+
Key key = Key.builder()
191+
.partitionValue(record.getId())
192+
.sortValue(record.getSort())
193+
.build();
194+
mappedTable.putItem(record).join();
195+
196+
GetItemEnhancedResponse<Record> response = mappedTable.getItemWithResponse(
197+
req -> req.key(key).returnConsumedCapacity(ReturnConsumedCapacity.TOTAL).consistentRead(true)
198+
).join();
199+
ConsumedCapacity consumedCapacity = response.consumedCapacity();
200+
assertThat(consumedCapacity).isNotNull();
201+
// A strongly consistent read request of an item up to 4 KB requires one read request unit.
202+
assertThat(consumedCapacity.capacityUnits()).isCloseTo(20.0, Offset.offset(1.0));
203+
}
204+
}

services-custom/dynamodb-enhanced/src/it/java/software/amazon/awssdk/enhanced/dynamodb/AsyncDeleteItemWithResponseIntegrationTest.java

Lines changed: 0 additions & 166 deletions
This file was deleted.

0 commit comments

Comments
 (0)