Skip to content

Commit e59216d

Browse files
Steven Aertsjoviegas
Steven Aerts
authored andcommitted
Add support for ByteBufferAttributeConverter
Add support ByteBuffer as an an attribute type. The DynamoDBType already lists it as a standard type.
1 parent be39a9a commit e59216d

File tree

5 files changed

+203
-0
lines changed

5 files changed

+203
-0
lines changed

services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/DefaultAttributeConverterProvider.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import software.amazon.awssdk.enhanced.dynamodb.internal.converter.attribute.BooleanAttributeConverter;
3636
import software.amazon.awssdk.enhanced.dynamodb.internal.converter.attribute.ByteArrayAttributeConverter;
3737
import software.amazon.awssdk.enhanced.dynamodb.internal.converter.attribute.ByteAttributeConverter;
38+
import software.amazon.awssdk.enhanced.dynamodb.internal.converter.attribute.ByteBufferAttributeConverter;
3839
import software.amazon.awssdk.enhanced.dynamodb.internal.converter.attribute.CharSequenceAttributeConverter;
3940
import software.amazon.awssdk.enhanced.dynamodb.internal.converter.attribute.CharacterArrayAttributeConverter;
4041
import software.amazon.awssdk.enhanced.dynamodb.internal.converter.attribute.CharacterAttributeConverter;
@@ -204,6 +205,7 @@ private static Builder getDefaultBuilder() {
204205
.addConverter(BigIntegerAttributeConverter.create())
205206
.addConverter(BooleanAttributeConverter.create())
206207
.addConverter(ByteArrayAttributeConverter.create())
208+
.addConverter(ByteBufferAttributeConverter.create())
207209
.addConverter(ByteAttributeConverter.create())
208210
.addConverter(CharacterArrayAttributeConverter.create())
209211
.addConverter(CharacterAttributeConverter.create())
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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.internal.converter.attribute;
17+
18+
import java.nio.ByteBuffer;
19+
import software.amazon.awssdk.annotations.Immutable;
20+
import software.amazon.awssdk.annotations.SdkInternalApi;
21+
import software.amazon.awssdk.annotations.ThreadSafe;
22+
import software.amazon.awssdk.core.SdkBytes;
23+
import software.amazon.awssdk.enhanced.dynamodb.AttributeConverter;
24+
import software.amazon.awssdk.enhanced.dynamodb.AttributeValueType;
25+
import software.amazon.awssdk.enhanced.dynamodb.EnhancedType;
26+
import software.amazon.awssdk.enhanced.dynamodb.internal.converter.TypeConvertingVisitor;
27+
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
28+
29+
30+
/**
31+
* A converter between {@link ByteBuffer} and {@link AttributeValue}.
32+
*
33+
* <p>
34+
* This stores values in DynamoDB as a binary blob.
35+
*
36+
* <p>
37+
* This supports reading every byte value supported by DynamoDB, making it fully compatible with custom converters as
38+
* well as internal converters (e.g. {@link SdkBytesAttributeConverter}).
39+
*
40+
* <p>
41+
* This can be created via {@link #create()}.
42+
*/
43+
@SdkInternalApi
44+
@ThreadSafe
45+
@Immutable
46+
public final class ByteBufferAttributeConverter implements AttributeConverter<ByteBuffer> {
47+
private static final Visitor VISITOR = new Visitor();
48+
49+
private ByteBufferAttributeConverter() {
50+
}
51+
52+
public static ByteBufferAttributeConverter create() {
53+
return new ByteBufferAttributeConverter();
54+
}
55+
56+
@Override
57+
public EnhancedType<ByteBuffer> type() {
58+
return EnhancedType.of(ByteBuffer.class);
59+
}
60+
61+
@Override
62+
public AttributeValueType attributeValueType() {
63+
return AttributeValueType.B;
64+
}
65+
66+
@Override
67+
public AttributeValue transformFrom(ByteBuffer input) {
68+
return AttributeValue.builder().b(SdkBytes.fromByteBuffer(input)).build();
69+
}
70+
71+
@Override
72+
public ByteBuffer transformTo(AttributeValue input) {
73+
if (input.b() != null) {
74+
return EnhancedAttributeValue.fromBytes(input.b()).convert(VISITOR);
75+
}
76+
77+
return EnhancedAttributeValue.fromAttributeValue(input).convert(VISITOR);
78+
}
79+
80+
private static final class Visitor extends TypeConvertingVisitor<ByteBuffer> {
81+
private Visitor() {
82+
super(ByteBuffer.class, ByteBufferAttributeConverter.class);
83+
}
84+
85+
@Override
86+
public ByteBuffer convertBytes(SdkBytes value) {
87+
return value.asByteBuffer();
88+
}
89+
}
90+
}
91+

services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/converters/attribute/BinaryAttributeConvertersTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static software.amazon.awssdk.enhanced.dynamodb.converters.attribute.ConverterTestUtils.transformFrom;
2020
import static software.amazon.awssdk.enhanced.dynamodb.converters.attribute.ConverterTestUtils.transformTo;
2121

22+
import java.nio.ByteBuffer;
2223
import java.util.Set;
2324
import org.junit.Test;
2425
import software.amazon.awssdk.core.SdkBytes;
@@ -27,6 +28,7 @@
2728
import software.amazon.awssdk.enhanced.dynamodb.internal.converter.attribute.EnhancedAttributeValue;
2829
import software.amazon.awssdk.enhanced.dynamodb.internal.converter.attribute.SdkBytesAttributeConverter;
2930
import software.amazon.awssdk.enhanced.dynamodb.internal.converter.attribute.SetAttributeConverter;
31+
import software.amazon.awssdk.enhanced.dynamodb.internal.converter.attribute.ByteBufferAttributeConverter;
3032

3133
public class BinaryAttributeConvertersTest {
3234
@Test
@@ -56,4 +58,15 @@ public void sdkBytesSetAttributeConverter_ReturnsBSType() {
5658
SetAttributeConverter<Set<SdkBytes>> bytesSet = SetAttributeConverter.setConverter(SdkBytesAttributeConverter.create());
5759
assertThat(bytesSet.attributeValueType()).isEqualTo(AttributeValueType.BS);
5860
}
61+
62+
@Test
63+
public void byteBufferAttributeConverterBehaves() {
64+
ByteBufferAttributeConverter converter = ByteBufferAttributeConverter.create();
65+
assertThat(converter.attributeValueType()).isEqualTo(AttributeValueType.B);
66+
String foo = "foo";
67+
ByteBuffer byteBuffer = ByteBuffer.wrap(foo.getBytes());
68+
SdkBytes sdkBytes = SdkBytes.fromUtf8String(foo);
69+
assertThat(transformFrom(converter, byteBuffer).b()).isEqualTo(sdkBytes);
70+
assertThat(transformTo(converter, EnhancedAttributeValue.fromBytes(sdkBytes).toAttributeValue())).isEqualTo(byteBuffer);
71+
}
5972
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
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.functionaltests.models;
17+
18+
import software.amazon.awssdk.core.SdkBytes;
19+
import software.amazon.awssdk.enhanced.dynamodb.mapper.StaticTableSchema;
20+
21+
import java.nio.ByteBuffer;
22+
import java.util.Objects;
23+
24+
import static software.amazon.awssdk.enhanced.dynamodb.mapper.StaticAttributeTags.primaryPartitionKey;
25+
26+
public class FakeItemWithByteBufferKey {
27+
private static final StaticTableSchema<FakeItemWithByteBufferKey> FAKE_ITEM_WITH_BINARY_KEY_SCHEMA =
28+
StaticTableSchema.builder(FakeItemWithByteBufferKey.class)
29+
.newItemSupplier(FakeItemWithByteBufferKey::new)
30+
.addAttribute(SdkBytes.class, a -> a.name("id")
31+
.getter(FakeItemWithByteBufferKey::getIdAsSdkBytes)
32+
.setter(FakeItemWithByteBufferKey::setIdAsSdkBytes)
33+
.tags(primaryPartitionKey()))
34+
.build();
35+
36+
private ByteBuffer id;
37+
38+
public static StaticTableSchema<FakeItemWithByteBufferKey> getTableSchema() {
39+
return FAKE_ITEM_WITH_BINARY_KEY_SCHEMA;
40+
}
41+
42+
public ByteBuffer getId() {
43+
return id;
44+
}
45+
46+
public void setId(ByteBuffer id) {
47+
this.id = id;
48+
}
49+
50+
51+
public SdkBytes getIdAsSdkBytes() {
52+
return SdkBytes.fromByteBuffer(id);
53+
}
54+
55+
public void setIdAsSdkBytes(SdkBytes id) {
56+
this.id = id.asByteBuffer();
57+
}
58+
59+
@Override
60+
public boolean equals(Object o) {
61+
if (this == o) return true;
62+
if (o == null || getClass() != o.getClass()) return false;
63+
FakeItemWithByteBufferKey that = (FakeItemWithByteBufferKey) o;
64+
return Objects.equals(id, that.id);
65+
}
66+
67+
@Override
68+
public int hashCode() {
69+
return Objects.hash(id);
70+
}
71+
}

services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/internal/operations/CreateTableOperationTest.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import software.amazon.awssdk.enhanced.dynamodb.TableMetadata;
4242
import software.amazon.awssdk.enhanced.dynamodb.functionaltests.models.FakeItem;
4343
import software.amazon.awssdk.enhanced.dynamodb.functionaltests.models.FakeItemWithBinaryKey;
44+
import software.amazon.awssdk.enhanced.dynamodb.functionaltests.models.FakeItemWithByteBufferKey;
4445
import software.amazon.awssdk.enhanced.dynamodb.functionaltests.models.FakeItemWithIndices;
4546
import software.amazon.awssdk.enhanced.dynamodb.functionaltests.models.FakeItemWithNumericSort;
4647
import software.amazon.awssdk.enhanced.dynamodb.model.CreateTableEnhancedRequest;
@@ -387,6 +388,31 @@ public void generateRequest_withBinaryKey() {
387388
.build()));
388389
}
389390

391+
@Test
392+
public void generateRequest_withByteBufferKey() {
393+
CreateTableOperation<FakeItemWithByteBufferKey> operation = CreateTableOperation.create(CreateTableEnhancedRequest.builder()
394+
.build());
395+
396+
CreateTableRequest request = operation.generateRequest(FakeItemWithByteBufferKey.getTableSchema(),
397+
PRIMARY_CONTEXT,
398+
null);
399+
400+
assertThat(request.tableName(), is(TABLE_NAME));
401+
assertThat(request.keySchema(), containsInAnyOrder(KeySchemaElement.builder()
402+
.attributeName("id")
403+
.keyType(HASH)
404+
.build()));
405+
406+
assertThat(request.globalSecondaryIndexes(), is(empty()));
407+
assertThat(request.localSecondaryIndexes(), is(empty()));
408+
409+
assertThat(request.attributeDefinitions(), containsInAnyOrder(
410+
AttributeDefinition.builder()
411+
.attributeName("id")
412+
.attributeType(ScalarAttributeType.B)
413+
.build()));
414+
}
415+
390416
@Test(expected = IllegalArgumentException.class)
391417
public void generateRequest_doesNotWorkForIndex() {
392418
CreateTableOperation<FakeItemWithIndices> operation = CreateTableOperation.create(CreateTableEnhancedRequest.builder()

0 commit comments

Comments
 (0)