Skip to content

DDB Enhanced: Expose attribute extractors and converters #1757

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# __2.11.7__ __2020-04-01__

## __Amazon DynamoDB Enhanced Client [Preview]__
- ### Features
- Added support for exposing attribute accessor and converters.

## __AWS IoT__
- ### Features
- This release introduces Dimensions for AWS IoT Device Defender. Dimensions can be used in Security Profiles to collect and monitor fine-grained metrics.
Expand All @@ -11,6 +16,7 @@
- ### Features
- Updated service endpoint metadata.


# __2.11.6__ __2020-03-31__
## __AWS Elemental MediaStore__
- ### Features
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package software.amazon.awssdk.enhanced.dynamodb;

import java.util.function.BiConsumer;
import java.util.function.Function;
import software.amazon.awssdk.annotations.SdkPublicApi;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;

/**
* Represents an attribute of a table model.
*
* @param <T> type of the model.
* @param <R> type type of the attribute.
*/
@SdkPublicApi
public interface Attribute<T, R> {

/**
* Returns the name of the attribute.
*
* @return the name of the attribute.
*/
String attributeName();

/**
* Returns the {@link AttributeType} of the attribute which helps with converting the values.
*
* @return the {@link AttributeType} of the attribute which helps with converting the values.
*/
AttributeType<R> attributeType();

/**
* Returns the function which can be used to obtain the attribute value as {@link AttributeValue} from given object.
*
* @return the function which can be used to obtain the attribute value as {@link AttributeValue} from given object.
*/
Function<T, AttributeValue> attributeGetterMethod();

/**
* Returns the consumer which can be used to set the attribute value as {@link AttributeValue} from given object.
*
* @return the consumer which can be used to set the attribute value as {@link AttributeValue} from given object.
*/
BiConsumer<T, AttributeValue> updateItemMethod();

/**
* Returns the {@link TableMetadata} of the parent model.
*
* @return the {@link TableMetadata} of the parent model.
*/
TableMetadata tableMetadata();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package software.amazon.awssdk.enhanced.dynamodb;

import software.amazon.awssdk.annotations.SdkPublicApi;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;

/**
* Attribute type helps to convert attribute values from and to their {@link AttributeValue} representation.
* @param <T> the type of the attribute.
*/
@SdkPublicApi
public interface AttributeType<T> {

/**
* Converts an object representing value of a attribute into {@link AttributeValue}.
*
* @param object an object to be converted.
* @return {@link AttributeValue} representation of the object.
*/
AttributeValue objectToAttributeValue(T object);

/**
* Converts an {@link AttributeValue} to the value expected by the attribute.
* @param attributeValue {@link AttributeValue} to be converted.
* @return the object representation of the {@link AttributeValue}.
*/
T attributeValueToObject(AttributeValue attributeValue);

/**
* Returns the {@link AttributeValueType} representation of the Java class of the attribute.
* @return the {@link AttributeValueType} representation of the Java class of the attribute.
*/
AttributeValueType attributeValueType();
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,12 @@ static <T> BeanTableSchema<T> fromBean(Class<T> beanClass) {
* @return The {@link EnhancedType} of the modelled item this TableSchema maps to.
*/
EnhancedType<T> itemType();

/**
* Returns an attribute accessor from the modelled object.
*
* @param key The attribute name describing which attribute to obtain.
* @return A single {@link Attribute} for accessing the requested modelled attribute in the model object.
*/
Attribute<T, ?> attribute(String key);
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -22,32 +22,32 @@
import java.util.function.Consumer;
import java.util.function.Function;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.enhanced.dynamodb.AttributeValueType;
import software.amazon.awssdk.enhanced.dynamodb.AttributeType;
import software.amazon.awssdk.enhanced.dynamodb.mapper.StaticAttribute;
import software.amazon.awssdk.enhanced.dynamodb.mapper.StaticTableMetadata;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;

@SdkInternalApi
public final class ResolvedStaticAttribute<T> {
public final class ResolvedStaticAttribute<T, R> implements software.amazon.awssdk.enhanced.dynamodb.Attribute<T, R> {
private final String attributeName;
private final Function<T, AttributeValue> getAttributeMethod;
private final BiConsumer<T, AttributeValue> updateItemMethod;
private final StaticTableMetadata tableMetadata;
private final AttributeValueType attributeValueType;
private final AttributeType<R> attributeType;

private ResolvedStaticAttribute(String attributeName,
Function<T, AttributeValue> getAttributeMethod,
BiConsumer<T, AttributeValue> updateItemMethod,
StaticTableMetadata tableMetadata,
AttributeValueType attributeValueType) {
AttributeType<R> attributeType) {
this.attributeName = attributeName;
this.getAttributeMethod = getAttributeMethod;
this.updateItemMethod = updateItemMethod;
this.tableMetadata = tableMetadata;
this.attributeValueType = attributeValueType;
this.attributeType = attributeType;
}

public static <T, R> ResolvedStaticAttribute<T> create(StaticAttribute<T, R> staticAttribute,
public static <T, R> ResolvedStaticAttribute<T, R> create(StaticAttribute<T, R> staticAttribute,
AttributeType<R> attributeType) {
Function<T, AttributeValue> getAttributeValueWithTransform = item -> {
R value = staticAttribute.getter().apply(item);
Expand Down Expand Up @@ -78,21 +78,21 @@ public static <T, R> ResolvedStaticAttribute<T> create(StaticAttribute<T, R> sta
getAttributeValueWithTransform,
updateItemWithTransform,
tableMetadataBuilder.build(),
attributeType.attributeValueType());
attributeType);
}

/**
* Return a transformed copy of this attribute that knows how to get/set from a different type of object given a
* function that can convert the containing object itself. It does this by modifying the get/set functions of
* type T to type R given a transformation function F(T) = R.
* type T to type S given a transformation function F(T) = S.
* @param transform A function that converts the object storing the attribute from the source type to the
* destination type.
* @param createComponent A consumer to create a new instance of the component object when required. A null value
* will bypass this logic.
* @param <R> The type being transformed to.
* @return A new Attribute that be contained by an object of type R.
* @param <S> The type being transformed to.
* @return A new Attribute that be contained by an object of type S.
*/
public <R> ResolvedStaticAttribute<R> transform(Function<R, T> transform, Consumer<R> createComponent) {
public <S> ResolvedStaticAttribute<S, R> transform(Function<S, T> transform, Consumer<S> createComponent) {
return new ResolvedStaticAttribute<>(
attributeName,
item -> {
Expand All @@ -110,21 +110,30 @@ public <R> ResolvedStaticAttribute<R> transform(Function<R, T> transform, Consum
updateItemMethod.accept(transform.apply(item), value);
},
tableMetadata,
attributeValueType);
attributeType);
}

@Override
public String attributeName() {
return attributeName;
}

@Override
public AttributeType<R> attributeType() {
return attributeType;
}

@Override
public Function<T, AttributeValue> attributeGetterMethod() {
return getAttributeMethod;
}

@Override
public BiConsumer<T, AttributeValue> updateItemMethod() {
return updateItemMethod;
}

@Override
public StaticTableMetadata tableMetadata() {
return tableMetadata;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.enhanced.dynamodb.AttributeConverter;
import software.amazon.awssdk.enhanced.dynamodb.AttributeType;
import software.amazon.awssdk.enhanced.dynamodb.AttributeValueType;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
import software.amazon.awssdk.annotations.SdkPublicApi;
import software.amazon.awssdk.enhanced.dynamodb.Attribute;
import software.amazon.awssdk.enhanced.dynamodb.AttributeConverter;
import software.amazon.awssdk.enhanced.dynamodb.AttributeConverterProvider;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
Expand Down Expand Up @@ -172,6 +173,11 @@ public EnhancedType<T> itemType() {
return wrappedTableSchema.itemType();
}

@Override
public Attribute<T, ?> attribute(String key) {
return wrappedTableSchema.attribute(key);
}

private static <T> StaticTableSchema<T> createStaticTableSchema(Class<T> beanClass) {
DynamoDbBean dynamoDbBean = beanClass.getAnnotation(DynamoDbBean.class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public Builder<T, R> toBuilder() {
}


ResolvedStaticAttribute<T> resolve(AttributeConverterProvider attributeConverterProvider) {
ResolvedStaticAttribute<T, R> resolve(AttributeConverterProvider attributeConverterProvider) {
return ResolvedStaticAttribute.create(this,
StaticAttributeType.create(converterFrom(attributeConverterProvider)));
}
Expand Down
Loading