Skip to content

Commit 8d241ab

Browse files
Release: 5.2.2 (#14)
* Read Consistency Setting * #8 Custom Mapper Spec * #8 Custom Mapper CDI fix * Fix symlink to CONTRIBUTING.md (#13) * #8 Don't use autowired or constructor injection with FactoryBeans (#12) * [maven-release-plugin] prepare release v5.2.2 * [maven-release-plugin] prepare for next development iteration Co-authored-by: Christian Frommeyer <frommeyerc@googlemail.com>
1 parent 4d6371e commit 8d241ab

19 files changed

+127
-39
lines changed

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<modelVersion>4.0.0</modelVersion>
2121
<groupId>io.github.boostchicken</groupId>
2222
<artifactId>spring-data-dynamodb</artifactId>
23-
<version>5.2.2-SNAPSHOT</version>
23+
<version>5.2.3-SNAPSHOT</version>
2424
<name>Spring Data DynamoDB</name>
2525
<inceptionYear>2018</inceptionYear>
2626

src/main/java/org/socialsignin/spring/data/dynamodb/repository/Query.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import java.lang.annotation.Retention;
2121
import java.lang.annotation.RetentionPolicy;
2222
import java.lang.annotation.Target;
23-
23+
import org.socialsignin.spring.data.dynamodb.repository.QueryConstants.ConsistentReadMode;
2424
import static org.socialsignin.spring.data.dynamodb.repository.QueryConstants.QUERY_LIMIT_UNLIMITED;
2525

2626
@Retention(RetentionPolicy.RUNTIME)
@@ -47,4 +47,7 @@
4747
* Expressions</a>
4848
*/
4949
int limit() default QUERY_LIMIT_UNLIMITED;
50+
51+
52+
ConsistentReadMode consistentReads() default ConsistentReadMode.DEFAULT;
5053
}

src/main/java/org/socialsignin/spring/data/dynamodb/repository/QueryConstants.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,16 @@
1515
*/
1616
package org.socialsignin.spring.data.dynamodb.repository;
1717

18-
public final class QueryConstants {
18+
public class QueryConstants {
1919

2020
private QueryConstants() {
2121
}
2222

2323
public static final int QUERY_LIMIT_UNLIMITED = Integer.MIN_VALUE;
2424

25+
public enum ConsistentReadMode {
26+
DEFAULT,
27+
CONSISTENT,
28+
EVENTUAL
29+
}
2530
}

src/main/java/org/socialsignin/spring/data/dynamodb/repository/cdi/DynamoDBRepositoryBean.java

+11-3
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ class DynamoDBRepositoryBean<T> extends CdiRepositoryBean<T> {
4646

4747
private final Bean<DynamoDBOperations> dynamoDBOperationsBean;
4848

49+
private final Bean<DynamoDBMapper> dynamoDBMapperBean;
50+
4951
/**
5052
* Constructs a {@link DynamoDBRepositoryBean}.
5153
*
@@ -62,7 +64,7 @@ class DynamoDBRepositoryBean<T> extends CdiRepositoryBean<T> {
6264
*/
6365
DynamoDBRepositoryBean(BeanManager beanManager, Bean<AmazonDynamoDB> amazonDynamoDBBean,
6466
Bean<DynamoDBMapperConfig> dynamoDBMapperConfigBean, Bean<DynamoDBOperations> dynamoDBOperationsBean,
65-
Set<Annotation> qualifiers, Class<T> repositoryType) {
67+
Bean<DynamoDBMapper> dynamoDBMapperBean, Set<Annotation> qualifiers, Class<T> repositoryType) {
6668

6769
super(qualifiers, repositoryType, beanManager);
6870
if (dynamoDBOperationsBean == null) {
@@ -77,6 +79,7 @@ class DynamoDBRepositoryBean<T> extends CdiRepositoryBean<T> {
7779
this.amazonDynamoDBBean = amazonDynamoDBBean;
7880
this.dynamoDBMapperConfigBean = dynamoDBMapperConfigBean;
7981
this.dynamoDBOperationsBean = dynamoDBOperationsBean;
82+
this.dynamoDBMapperBean = dynamoDBMapperBean;
8083
}
8184

8285
/*
@@ -97,15 +100,20 @@ protected T create(CreationalContext<T> creationalContext, Class<T> repositoryTy
97100
? null
98101
: getDependencyInstance(dynamoDBMapperConfigBean, DynamoDBMapperConfig.class);
99102

103+
DynamoDBMapper dynamoDBMapper = dynamoDBMapperBean == null
104+
? null
105+
: getDependencyInstance(dynamoDBMapperBean, DynamoDBMapper.class);
106+
100107
DynamoDBOperations dynamoDBOperations = dynamoDBOperationsBean == null
101108
? null
102109
: getDependencyInstance(dynamoDBOperationsBean, DynamoDBOperations.class);
103110

104111
if (dynamoDBMapperConfig == null) {
105112
dynamoDBMapperConfig = DynamoDBMapperConfig.DEFAULT;
106113
}
107-
DynamoDBMapper dynamoDBMapper = new DynamoDBMapper(amazonDynamoDB, dynamoDBMapperConfig);
108-
114+
if(dynamoDBMapper == null) {
115+
dynamoDBMapper = new DynamoDBMapper(amazonDynamoDB, dynamoDBMapperConfig);
116+
}
109117
if (dynamoDBOperations == null) {
110118
dynamoDBOperations = new DynamoDBTemplate(amazonDynamoDB, dynamoDBMapper, dynamoDBMapperConfig);
111119
}

src/main/java/org/socialsignin/spring/data/dynamodb/repository/cdi/DynamoDBRepositoryExtension.java

+13-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
1919
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
20+
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
2021
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig;
2122
import org.slf4j.Logger;
2223
import org.slf4j.LoggerFactory;
@@ -54,6 +55,7 @@ public class DynamoDBRepositoryExtension extends CdiRepositoryExtensionSupport {
5455

5556
private final Map<Set<Annotation>, Bean<DynamoDBMapperConfig>> dbMapperConfigs = new HashMap<Set<Annotation>, Bean<DynamoDBMapperConfig>>();
5657

58+
private final Map<Set<Annotation>, Bean<DynamoDBMapper>> dbMapper = new HashMap<>();
5759
public DynamoDBRepositoryExtension() {
5860
LOGGER.info("Activating CDI extension for Spring Data DynamoDB repositories.");
5961
}
@@ -89,6 +91,14 @@ <X> void processBean(@Observes ProcessBean<X> processBean) {
8991
dbMapperConfigs.put(qualifiers, (Bean<DynamoDBMapperConfig>) bean);
9092
}
9193
}
94+
if (type instanceof Class<?> && DynamoDBMapper.class.isAssignableFrom((Class<?>) type)) {
95+
Set<Annotation> qualifiers = new HashSet<Annotation>(bean.getQualifiers());
96+
if (bean.isAlternative() || !dbMapper.containsKey(qualifiers)) {
97+
LOGGER.debug("Discovered '{}' with qualifiers {}.", DynamoDBMapper.class.getName(),
98+
qualifiers);
99+
dbMapper.put(qualifiers, (Bean<DynamoDBMapper>) bean);
100+
}
101+
}
92102
}
93103
}
94104

@@ -138,16 +148,17 @@ private <T> Bean<T> createRepositoryBean(Class<T> repositoryType, Set<Annotation
138148
// qualifiers of the repository.
139149
Bean<DynamoDBMapperConfig> dynamoDBMapperConfigBean = dbMapperConfigs.get(qualifiers);
140150

151+
Bean<DynamoDBOperations> dynamoDBOperationsBean = dynamoDBOperationss.get(qualifiers);
141152
if (amazonDynamoDBBean == null) {
142153
throw new UnsatisfiedResolutionException(
143154
String.format("Unable to resolve a bean for '%s' with qualifiers %s.",
144155
AmazonDynamoDBClient.class.getName(), qualifiers));
145156
}
146157

147-
Bean<DynamoDBOperations> dynamoDBOperationsBean = dynamoDBOperationss.get(qualifiers);
158+
Bean<DynamoDBMapper> dynamoDBMapperBean = dbMapper.get(qualifiers);
148159

149160
// Construct and return the repository bean.
150161
return new DynamoDBRepositoryBean<T>(beanManager, amazonDynamoDBBean, dynamoDBMapperConfigBean,
151-
dynamoDBOperationsBean, qualifiers, repositoryType);
162+
dynamoDBOperationsBean, dynamoDBMapperBean, qualifiers, repositoryType);
152163
}
153164
}

src/main/java/org/socialsignin/spring/data/dynamodb/repository/config/DynamoDBMapperFactory.java

+13-11
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,23 @@
1515
*/
1616
package org.socialsignin.spring.data.dynamodb.repository.config;
1717

18+
import org.springframework.beans.BeansException;
19+
import org.springframework.beans.factory.BeanFactory;
20+
import org.springframework.beans.factory.BeanFactoryAware;
1821
import org.springframework.beans.factory.FactoryBean;
19-
import org.springframework.beans.factory.annotation.Autowired;
2022

2123
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
2224
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
2325
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig;
2426

25-
public class DynamoDBMapperFactory implements FactoryBean<DynamoDBMapper> {
26-
27-
private final AmazonDynamoDB amazonDynamoDB;
28-
private final DynamoDBMapperConfig dynamoDBMapperConfig;
29-
30-
@Autowired
31-
public DynamoDBMapperFactory(AmazonDynamoDB amazonDynamoDB, DynamoDBMapperConfig dynamoDBMapperConfig) {
32-
this.amazonDynamoDB = amazonDynamoDB;
33-
this.dynamoDBMapperConfig = dynamoDBMapperConfig;
34-
}
27+
public class DynamoDBMapperFactory implements FactoryBean<DynamoDBMapper>, BeanFactoryAware {
3528

29+
private BeanFactory beanFactory;
30+
3631
@Override
3732
public DynamoDBMapper getObject() throws Exception {
33+
AmazonDynamoDB amazonDynamoDB = beanFactory.getBean(AmazonDynamoDB.class);
34+
DynamoDBMapperConfig dynamoDBMapperConfig = beanFactory.getBean(DynamoDBMapperConfig.class);
3835
return new DynamoDBMapper(amazonDynamoDB, dynamoDBMapperConfig);
3936
}
4037

@@ -43,4 +40,9 @@ public Class<?> getObjectType() {
4340
return DynamoDBMapper.class;
4441
}
4542

43+
@Override
44+
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
45+
this.beanFactory = beanFactory;
46+
}
47+
4648
}

src/main/java/org/socialsignin/spring/data/dynamodb/repository/config/DynamoDBRepositoryConfigExtension.java

+8-5
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ public void registerBeansForRoot(BeanDefinitionRegistry registry,
260260
this.registry = registry;
261261

262262
this.dynamoDBMapperConfigName = getBeanNameWithModulePrefix("DynamoDBMapperConfig");
263-
Optional dynamoDBMapperConfigRef = configurationSource.getAttribute("dynamoDBMapperConfigRef");
263+
Optional<String> dynamoDBMapperConfigRef = configurationSource.getAttribute("dynamoDBMapperConfigRef");
264264

265265
if (!dynamoDBMapperConfigRef.isPresent()) {
266266
BeanDefinitionBuilder dynamoDBMapperConfigBuiilder = BeanDefinitionBuilder
@@ -269,10 +269,13 @@ public void registerBeansForRoot(BeanDefinitionRegistry registry,
269269
dynamoDBMapperConfigBuiilder.getBeanDefinition());
270270
}
271271

272-
this.dynamoDBMapperName = getBeanNameWithModulePrefix("DynamoDBMapper");
273-
BeanDefinitionBuilder dynamoDBMapperBuilder = BeanDefinitionBuilder
274-
.genericBeanDefinition(DynamoDBMapperFactory.class);
275-
registry.registerBeanDefinition(this.dynamoDBMapperName, dynamoDBMapperBuilder.getBeanDefinition());
272+
Optional<String> dynamoDBMapperRef = configurationSource.getAttribute("dynamoDBMapperRef");
273+
if(!dynamoDBMapperRef.isPresent()) {
274+
this.dynamoDBMapperName = getBeanNameWithModulePrefix("DynamoDBMapper");
275+
BeanDefinitionBuilder dynamoDBMapperBuilder = BeanDefinitionBuilder
276+
.genericBeanDefinition(DynamoDBMapperFactory.class);
277+
registry.registerBeanDefinition(this.dynamoDBMapperName, dynamoDBMapperBuilder.getBeanDefinition());
278+
}
276279
}
277280

278281
protected String getBeanNameWithModulePrefix(String baseBeanName) {

src/main/java/org/socialsignin/spring/data/dynamodb/repository/config/EnableDynamoDBRepositories.java

+11
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,17 @@
147147
*/
148148
String dynamoDBMapperConfigRef() default "";
149149

150+
/**
151+
* Returns the
152+
* {@link com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper }
153+
* reference to be used
154+
*
155+
* @return The
156+
* {@link com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper}
157+
* bean name
158+
*/
159+
String dynamoDBMapperRef() default "";
160+
150161
/**
151162
* Returns the {@link javax.validation.Validator } reference to be used for to
152163
* validate DynamoDB entities

src/main/java/org/socialsignin/spring/data/dynamodb/repository/query/AbstractDynamoDBQueryCreator.java

+7-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.amazonaws.services.dynamodbv2.model.ComparisonOperator;
2020
import org.socialsignin.spring.data.dynamodb.core.DynamoDBOperations;
2121
import org.socialsignin.spring.data.dynamodb.query.Query;
22+
import org.socialsignin.spring.data.dynamodb.repository.QueryConstants;
2223
import org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBEntityInformation;
2324
import org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBIdIsHashAndRangeKeyEntityInformation;
2425
import org.springframework.data.mapping.PropertyPath;
@@ -47,23 +48,26 @@ public abstract class AbstractDynamoDBQueryCreator<T, ID, R>
4748
protected final DynamoDBOperations dynamoDBOperations;
4849
protected final Optional<String> projection;
4950
protected final Optional<Integer> limit;
51+
protected final QueryConstants.ConsistentReadMode consistentReads;
5052

5153
public AbstractDynamoDBQueryCreator(PartTree tree, DynamoDBEntityInformation<T, ID> entityMetadata,
52-
Optional<String> projection, Optional<Integer> limitResults, DynamoDBOperations dynamoDBOperations) {
54+
Optional<String> projection, Optional<Integer> limitResults, QueryConstants.ConsistentReadMode consistentReads, DynamoDBOperations dynamoDBOperations) {
5355
super(tree);
5456
this.entityMetadata = entityMetadata;
5557
this.projection = projection;
5658
this.limit = limitResults;
59+
this.consistentReads = consistentReads;
5760
this.dynamoDBOperations = dynamoDBOperations;
5861
}
5962

6063
public AbstractDynamoDBQueryCreator(PartTree tree, ParameterAccessor parameterAccessor,
61-
DynamoDBEntityInformation<T, ID> entityMetadata, Optional<String> projection,
62-
Optional<Integer> limitResults, DynamoDBOperations dynamoDBOperations) {
64+
DynamoDBEntityInformation<T, ID> entityMetadata, Optional<String> projection,
65+
Optional<Integer> limitResults, QueryConstants.ConsistentReadMode consistentReads, DynamoDBOperations dynamoDBOperations) {
6366
super(tree, parameterAccessor);
6467
this.entityMetadata = entityMetadata;
6568
this.projection = projection;
6669
this.limit = limitResults;
70+
this.consistentReads = consistentReads;
6771
this.dynamoDBOperations = dynamoDBOperations;
6872
}
6973

src/main/java/org/socialsignin/spring/data/dynamodb/repository/query/AbstractDynamoDBQueryCriteria.java

+19
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.socialsignin.spring.data.dynamodb.marshaller.Date2IsoDynamoDBMarshaller;
3030
import org.socialsignin.spring.data.dynamodb.marshaller.Instant2IsoDynamoDBMarshaller;
3131
import org.socialsignin.spring.data.dynamodb.query.Query;
32+
import org.socialsignin.spring.data.dynamodb.repository.QueryConstants;
3233
import org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBEntityInformation;
3334
import org.socialsignin.spring.data.dynamodb.utils.SortHandler;
3435
import org.springframework.data.domain.Sort;
@@ -73,6 +74,7 @@ public abstract class AbstractDynamoDBQueryCriteria<T, ID> implements DynamoDBQu
7374
protected Sort sort = Sort.unsorted();
7475
protected Optional<String> projection = Optional.empty();
7576
protected Optional<Integer> limit = Optional.empty();
77+
protected QueryConstants.ConsistentReadMode consistentReads = QueryConstants.ConsistentReadMode.DEFAULT;
7678

7779
public abstract boolean isApplicableForLoad();
7880

@@ -134,6 +136,17 @@ protected QueryRequest buildQueryRequest(String tableName, String theIndexName,
134136
}
135137

136138
limit.ifPresent(queryRequest::setLimit);
139+
140+
switch (consistentReads) {
141+
case CONSISTENT:
142+
queryRequest.setConsistentRead(true);
143+
break;
144+
case EVENTUAL:
145+
queryRequest.setConsistentRead(false);
146+
break;
147+
default:
148+
break;
149+
}
137150
applySortIfSpecified(queryRequest, new ArrayList<>(new HashSet<>(allowedSortProperties)));
138151
}
139152
return queryRequest;
@@ -703,4 +716,10 @@ public DynamoDBQueryCriteria<T, ID> withLimit(Optional<Integer> limit) {
703716
this.limit = limit;
704717
return this;
705718
}
719+
720+
@Override
721+
public DynamoDBQueryCriteria<T, ID> withConsistentReads(QueryConstants.ConsistentReadMode consistentReads) {
722+
this.consistentReads = consistentReads;
723+
return this;
724+
}
706725
}

src/main/java/org/socialsignin/spring/data/dynamodb/repository/query/DynamoDBCountQueryCreator.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.socialsignin.spring.data.dynamodb.core.DynamoDBOperations;
1919
import org.socialsignin.spring.data.dynamodb.query.Query;
2020
import org.socialsignin.spring.data.dynamodb.query.StaticQuery;
21+
import org.socialsignin.spring.data.dynamodb.repository.QueryConstants;
2122
import org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBEntityInformation;
2223
import org.springframework.data.domain.Sort;
2324
import org.springframework.data.repository.query.ParameterAccessor;
@@ -32,13 +33,13 @@ public class DynamoDBCountQueryCreator<T, ID> extends AbstractDynamoDBQueryCreat
3233

3334
public DynamoDBCountQueryCreator(PartTree tree, DynamoDBEntityInformation<T, ID> entityMetadata,
3435
DynamoDBOperations dynamoDBOperations, boolean pageQuery) {
35-
super(tree, entityMetadata, Optional.empty(), Optional.empty(), dynamoDBOperations);
36+
super(tree, entityMetadata, Optional.empty(), Optional.empty(), QueryConstants.ConsistentReadMode.DEFAULT, dynamoDBOperations);
3637
this.pageQuery = pageQuery;
3738
}
3839

3940
public DynamoDBCountQueryCreator(PartTree tree, ParameterAccessor parameterAccessor,
4041
DynamoDBEntityInformation<T, ID> entityMetadata, DynamoDBOperations dynamoDBOperations, boolean pageQuery) {
41-
super(tree, parameterAccessor, entityMetadata, Optional.empty(), Optional.empty(), dynamoDBOperations);
42+
super(tree, parameterAccessor, entityMetadata, Optional.empty(), Optional.empty(), QueryConstants.ConsistentReadMode.DEFAULT, dynamoDBOperations);
4243
this.pageQuery = pageQuery;
4344

4445
}

src/main/java/org/socialsignin/spring/data/dynamodb/repository/query/DynamoDBQueryCreator.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.socialsignin.spring.data.dynamodb.core.DynamoDBOperations;
1919
import org.socialsignin.spring.data.dynamodb.query.Query;
2020
import org.socialsignin.spring.data.dynamodb.query.StaticQuery;
21+
import org.socialsignin.spring.data.dynamodb.repository.QueryConstants;
2122
import org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBEntityInformation;
2223
import org.springframework.data.domain.Sort;
2324
import org.springframework.data.repository.query.ParameterAccessor;
@@ -29,9 +30,9 @@
2930
public class DynamoDBQueryCreator<T, ID> extends AbstractDynamoDBQueryCreator<T, ID, T> {
3031

3132
public DynamoDBQueryCreator(PartTree tree, ParameterAccessor parameterAccessor,
32-
DynamoDBEntityInformation<T, ID> entityMetadata, Optional<String> projection, Optional<Integer> limit,
33+
DynamoDBEntityInformation<T, ID> entityMetadata, Optional<String> projection, Optional<Integer> limit, QueryConstants.ConsistentReadMode consistentReads,
3334
DynamoDBOperations dynamoDBOperations) {
34-
super(tree, parameterAccessor, entityMetadata, projection, limit, dynamoDBOperations);
35+
super(tree, parameterAccessor, entityMetadata, projection, limit, consistentReads, dynamoDBOperations);
3536
}
3637

3738
@Override
@@ -42,6 +43,7 @@ protected Query<T> complete(@Nullable DynamoDBQueryCriteria<T, ID> criteria, Sor
4243
criteria.withSort(sort);
4344
criteria.withProjection(projection);
4445
criteria.withLimit(limit);
46+
criteria.withConsistentReads(consistentReads);
4547
return criteria.buildQuery(dynamoDBOperations);
4648
}
4749
}

src/main/java/org/socialsignin/spring/data/dynamodb/repository/query/DynamoDBQueryCriteria.java

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.amazonaws.services.dynamodbv2.model.ComparisonOperator;
1919
import org.socialsignin.spring.data.dynamodb.core.DynamoDBOperations;
2020
import org.socialsignin.spring.data.dynamodb.query.Query;
21+
import org.socialsignin.spring.data.dynamodb.repository.QueryConstants;
2122
import org.springframework.data.domain.Sort;
2223

2324
import java.util.Optional;
@@ -45,6 +46,8 @@ DynamoDBQueryCriteria<T, ID> withSingleValueCriteria(String propertyName, Compar
4546

4647
DynamoDBQueryCriteria<T, ID> withLimit(Optional<Integer> limit);
4748

49+
DynamoDBQueryCriteria<T, ID> withConsistentReads(QueryConstants.ConsistentReadMode reads);
50+
4851
Query<T> buildQuery(DynamoDBOperations dynamoDBOperations);
4952

5053
Query<Long> buildCountQuery(DynamoDBOperations dynamoDBOperations, boolean pageQuery);

0 commit comments

Comments
 (0)