Skip to content

Commit e59216d

Browse files
Steven Aertsjoviegas
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)