From 014fa2666a24bffceda20dca20050f3cbee70975 Mon Sep 17 00:00:00 2001 From: Sebastian J Date: Fri, 2 Feb 2018 10:41:42 -0500 Subject: [PATCH] Followup: Handle new `Sort.unsorted()` sorting strategy Spring-Data no longer passes in `null` if no sorting order is given by the caller but uses `Sort.unsorted()` which incorrectly causes an Exception. This should also solve #99 Followup to 8c3e139246c4a9617b0d7c22b5a170fb2d42f261 Also getting rid of some JDK9 deprecated warnings on the JDK classes - as those methods exist in JDK8 already. --- .../event/AbstractDynamoDBEventListener.java | 1 + .../query/ScanExpressionCountQuery.java | 2 +- .../query/AbstractDynamoDBQueryCriteria.java | 81 ++++++++---------- ...moDBEntityWithHashAndRangeKeyCriteria.java | 2 +- ...DynamoDBEntityWithHashKeyOnlyCriteria.java | 2 +- .../DynamoDBEntityMetadataSupport.java | 8 +- ...dRangeKeyExtractingEntityMetadataImpl.java | 7 +- .../support/SimpleDynamoDBCrudRepository.java | 4 +- ...pleDynamoDBPagingAndSortingRepository.java | 6 +- .../data/dynamodb/utils/SortHandler.java | 45 ++++++++++ .../DynamoDBAuditingRegistrarUnitTests.java | 2 +- .../spring/data/dynamodb/core/FeedUserIT.java | 2 +- .../AbstractMultipleEntityQueryTest.java | 85 +++++++++++++++++++ .../query/ScanExpressionCountQueryTest.java | 83 ++++++++++++++++++ .../dynamodb/utils/DynamoDBLocalResource.java | 9 +- 15 files changed, 268 insertions(+), 71 deletions(-) create mode 100644 src/main/java/org/socialsignin/spring/data/dynamodb/utils/SortHandler.java create mode 100644 src/test/java/org/socialsignin/spring/data/dynamodb/query/AbstractMultipleEntityQueryTest.java create mode 100644 src/test/java/org/socialsignin/spring/data/dynamodb/query/ScanExpressionCountQueryTest.java diff --git a/src/main/java/org/socialsignin/spring/data/dynamodb/mapping/event/AbstractDynamoDBEventListener.java b/src/main/java/org/socialsignin/spring/data/dynamodb/mapping/event/AbstractDynamoDBEventListener.java index 1b8f0cdf..e7b954e1 100644 --- a/src/main/java/org/socialsignin/spring/data/dynamodb/mapping/event/AbstractDynamoDBEventListener.java +++ b/src/main/java/org/socialsignin/spring/data/dynamodb/mapping/event/AbstractDynamoDBEventListener.java @@ -108,6 +108,7 @@ else if (domainClass.isAssignableFrom(source.getClass())) { } } + @SuppressWarnings("unchecked") private void publishEachElement(List list, Consumer publishMethod) { list.stream() .filter(o -> domainClass.isAssignableFrom(o.getClass())) diff --git a/src/main/java/org/socialsignin/spring/data/dynamodb/query/ScanExpressionCountQuery.java b/src/main/java/org/socialsignin/spring/data/dynamodb/query/ScanExpressionCountQuery.java index 69bf09c0..c4564eea 100644 --- a/src/main/java/org/socialsignin/spring/data/dynamodb/query/ScanExpressionCountQuery.java +++ b/src/main/java/org/socialsignin/spring/data/dynamodb/query/ScanExpressionCountQuery.java @@ -37,7 +37,7 @@ public ScanExpressionCountQuery(DynamoDBOperations dynamoDBOperations, Class @Override public Long getSingleResult() { assertScanCountEnabled(isScanCountEnabled()); - return new Long(dynamoDBOperations.count(domainClass,scanExpression)); + return Long.valueOf(dynamoDBOperations.count(domainClass,scanExpression)); } public void assertScanCountEnabled(boolean scanCountEnabled) diff --git a/src/main/java/org/socialsignin/spring/data/dynamodb/repository/query/AbstractDynamoDBQueryCriteria.java b/src/main/java/org/socialsignin/spring/data/dynamodb/repository/query/AbstractDynamoDBQueryCriteria.java index 50ba3628..655a03d5 100644 --- a/src/main/java/org/socialsignin/spring/data/dynamodb/repository/query/AbstractDynamoDBQueryCriteria.java +++ b/src/main/java/org/socialsignin/spring/data/dynamodb/repository/query/AbstractDynamoDBQueryCriteria.java @@ -29,6 +29,7 @@ import org.socialsignin.spring.data.dynamodb.marshaller.Instant2IsoDynamoDBMarshaller; import org.socialsignin.spring.data.dynamodb.query.Query; import org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBEntityInformation; +import org.socialsignin.spring.data.dynamodb.utils.SortHandler; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.domain.Sort.Order; @@ -51,7 +52,7 @@ /** * @author Michael Lavelle */ -public abstract class AbstractDynamoDBQueryCriteria implements DynamoDBQueryCriteria { +public abstract class AbstractDynamoDBQueryCriteria implements DynamoDBQueryCriteria, SortHandler { protected Class clazz; private DynamoDBEntityInformation entityInformation; @@ -65,19 +66,10 @@ public abstract class AbstractDynamoDBQueryCriteria implements DynamoDBQu protected Object hashKeyAttributeValue; protected Object hashKeyPropertyValue; protected String globalSecondaryIndexName; - protected Sort sort; + protected Sort sort = Sort.unsorted(); public abstract boolean isApplicableForLoad(); - /** - * @throws UnsupportedOperationException if a {@link #sort} is initalized (non-null && not {@link Sort#unsorted()} - */ - protected void ensureNoSort() throws UnsupportedOperationException { - if (sort != null && sort != Sort.unsorted()) { - throw new UnsupportedOperationException("Sort not supported for scan expressions"); - } - } - protected QueryRequest buildQueryRequest(String tableName, String theIndexName, String hashKeyAttributeName, String rangeKeyAttributeName, String rangeKeyPropertyName, List hashKeyConditions, List rangeKeyConditions) { @@ -119,14 +111,12 @@ protected QueryRequest buildQueryRequest(String tableName, String theIndexName, } } - if (sort != null) { - for (Order order : sort) { - final String sortProperty = order.getProperty(); - if (entityInformation.isGlobalIndexRangeKeyProperty(sortProperty)) { - allowedSortProperties.add(sortProperty); - } - } - } + for (Order order : sort) { + final String sortProperty = order.getProperty(); + if (entityInformation.isGlobalIndexRangeKeyProperty(sortProperty)) { + allowedSortProperties.add(sortProperty); + } + } queryRequest.setKeyConditions(keyConditions); queryRequest.setSelect(Select.ALL_PROJECTED_ATTRIBUTES); @@ -140,20 +130,19 @@ protected void applySortIfSpecified(DynamoDBQueryExpression queryExpression, throw new UnsupportedOperationException("Can only sort by at most a single range or index range key"); } - if (sort != null) { - boolean sortAlreadySet = false; - for (Order order : sort) { - if (permittedPropertyNames.contains(order.getProperty())) { - if (sortAlreadySet) { - throw new UnsupportedOperationException("Sorting by multiple attributes not possible"); - } - queryExpression.setScanIndexForward(order.getDirection().equals(Direction.ASC)); - sortAlreadySet = true; - } else { - throw new UnsupportedOperationException("Sorting only possible by " + permittedPropertyNames - + " for the criteria specified"); + boolean sortAlreadySet = false; + for (Order order : sort) { + if (permittedPropertyNames.contains(order.getProperty())) { + if (sortAlreadySet) { + throw new UnsupportedOperationException("Sorting by multiple attributes not possible"); + } + queryExpression.setScanIndexForward(order.getDirection().equals(Direction.ASC)); + sortAlreadySet = true; + } else { + throw new UnsupportedOperationException("Sorting only possible by " + permittedPropertyNames + + " for the criteria specified"); } } } @@ -163,25 +152,23 @@ protected void applySortIfSpecified(QueryRequest queryRequest, List perm throw new UnsupportedOperationException("Can only sort by at most a single global hash and range key"); } - if (sort != null) { - boolean sortAlreadySet = false; - for (Order order : sort) { - if (permittedPropertyNames.contains(order.getProperty())) { - if (sortAlreadySet) { - throw new UnsupportedOperationException("Sorting by multiple attributes not possible"); + boolean sortAlreadySet = false; + for (Order order : sort) { + if (permittedPropertyNames.contains(order.getProperty())) { + if (sortAlreadySet) { + throw new UnsupportedOperationException("Sorting by multiple attributes not possible"); - } - if (queryRequest.getKeyConditions().size() > 1 && !hasIndexHashKeyEqualCondition()) { - throw new UnsupportedOperationException( - "Sorting for global index queries with criteria on both hash and range not possible"); + } + if (queryRequest.getKeyConditions().size() > 1 && !hasIndexHashKeyEqualCondition()) { + throw new UnsupportedOperationException( + "Sorting for global index queries with criteria on both hash and range not possible"); - } - queryRequest.setScanIndexForward(order.getDirection().equals(Direction.ASC)); - sortAlreadySet = true; - } else { - throw new UnsupportedOperationException("Sorting only possible by " + permittedPropertyNames - + " for the criteria specified"); } + queryRequest.setScanIndexForward(order.getDirection().equals(Direction.ASC)); + sortAlreadySet = true; + } else { + throw new UnsupportedOperationException("Sorting only possible by " + permittedPropertyNames + + " for the criteria specified"); } } } diff --git a/src/main/java/org/socialsignin/spring/data/dynamodb/repository/query/DynamoDBEntityWithHashAndRangeKeyCriteria.java b/src/main/java/org/socialsignin/spring/data/dynamodb/repository/query/DynamoDBEntityWithHashAndRangeKeyCriteria.java index ea0fbed9..4259516b 100644 --- a/src/main/java/org/socialsignin/spring/data/dynamodb/repository/query/DynamoDBEntityWithHashAndRangeKeyCriteria.java +++ b/src/main/java/org/socialsignin/spring/data/dynamodb/repository/query/DynamoDBEntityWithHashAndRangeKeyCriteria.java @@ -330,7 +330,7 @@ public boolean isApplicableForQuery() { public DynamoDBScanExpression buildScanExpression() { - ensureNoSort(); + ensureNoSort(sort); DynamoDBScanExpression scanExpression = new DynamoDBScanExpression(); if (isHashKeySpecified()) { diff --git a/src/main/java/org/socialsignin/spring/data/dynamodb/repository/query/DynamoDBEntityWithHashKeyOnlyCriteria.java b/src/main/java/org/socialsignin/spring/data/dynamodb/repository/query/DynamoDBEntityWithHashKeyOnlyCriteria.java index 9dd654a0..71259e54 100644 --- a/src/main/java/org/socialsignin/spring/data/dynamodb/repository/query/DynamoDBEntityWithHashKeyOnlyCriteria.java +++ b/src/main/java/org/socialsignin/spring/data/dynamodb/repository/query/DynamoDBEntityWithHashKeyOnlyCriteria.java @@ -90,7 +90,7 @@ public boolean isApplicableForLoad() { public DynamoDBScanExpression buildScanExpression() { - ensureNoSort(); + ensureNoSort(sort); DynamoDBScanExpression scanExpression = new DynamoDBScanExpression(); if (isHashKeySpecified()) { diff --git a/src/main/java/org/socialsignin/spring/data/dynamodb/repository/support/DynamoDBEntityMetadataSupport.java b/src/main/java/org/socialsignin/spring/data/dynamodb/repository/support/DynamoDBEntityMetadataSupport.java index 4db004a2..8f08e882 100644 --- a/src/main/java/org/socialsignin/spring/data/dynamodb/repository/support/DynamoDBEntityMetadataSupport.java +++ b/src/main/java/org/socialsignin/spring/data/dynamodb/repository/support/DynamoDBEntityMetadataSupport.java @@ -32,6 +32,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; @@ -301,12 +302,9 @@ public DynamoDBMarshaller getMarshallerForProperty(final String propertyName) if(annotation != null) { try { - return annotation.marshallerClass().newInstance(); - } catch (InstantiationException e) { + return annotation.marshallerClass().getDeclaredConstructor().newInstance(); + } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } } diff --git a/src/main/java/org/socialsignin/spring/data/dynamodb/repository/support/DynamoDBHashAndRangeKeyExtractingEntityMetadataImpl.java b/src/main/java/org/socialsignin/spring/data/dynamodb/repository/support/DynamoDBHashAndRangeKeyExtractingEntityMetadataImpl.java index ab5e7f2f..063b73a3 100644 --- a/src/main/java/org/socialsignin/spring/data/dynamodb/repository/support/DynamoDBHashAndRangeKeyExtractingEntityMetadataImpl.java +++ b/src/main/java/org/socialsignin/spring/data/dynamodb/repository/support/DynamoDBHashAndRangeKeyExtractingEntityMetadataImpl.java @@ -24,6 +24,7 @@ import org.springframework.util.ReflectionUtils.MethodCallback; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashSet; import java.util.Set; @@ -109,7 +110,7 @@ public void doWith(Field field) { public T getHashKeyPropotypeEntityForHashKey(Object hashKey) { try { - T entity = getJavaType().newInstance(); + T entity = getJavaType().getDeclaredConstructor().newInstance(); if (hashKeySetterMethod != null) { ReflectionUtils.invokeMethod(hashKeySetterMethod, entity, hashKey); @@ -120,9 +121,7 @@ public T getHashKeyPropotypeEntityForHashKey(Object hashKey) { } return entity; - } catch (InstantiationException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { + } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { throw new RuntimeException(e); } } diff --git a/src/main/java/org/socialsignin/spring/data/dynamodb/repository/support/SimpleDynamoDBCrudRepository.java b/src/main/java/org/socialsignin/spring/data/dynamodb/repository/support/SimpleDynamoDBCrudRepository.java index f5bef00c..2a3f7a7a 100644 --- a/src/main/java/org/socialsignin/spring/data/dynamodb/repository/support/SimpleDynamoDBCrudRepository.java +++ b/src/main/java/org/socialsignin/spring/data/dynamodb/repository/support/SimpleDynamoDBCrudRepository.java @@ -22,6 +22,7 @@ import org.socialsignin.spring.data.dynamodb.exception.BatchWriteException; import org.socialsignin.spring.data.dynamodb.core.DynamoDBOperations; import org.socialsignin.spring.data.dynamodb.repository.DynamoDBCrudRepository; +import org.socialsignin.spring.data.dynamodb.utils.SortHandler; import org.springframework.dao.DataAccessException; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.util.Assert; @@ -46,7 +47,8 @@ * the type of the entity's identifier */ public class SimpleDynamoDBCrudRepository - implements DynamoDBCrudRepository { + implements DynamoDBCrudRepository, + SortHandler { protected DynamoDBEntityInformation entityInformation; diff --git a/src/main/java/org/socialsignin/spring/data/dynamodb/repository/support/SimpleDynamoDBPagingAndSortingRepository.java b/src/main/java/org/socialsignin/spring/data/dynamodb/repository/support/SimpleDynamoDBPagingAndSortingRepository.java index 0052f081..8d7dce63 100644 --- a/src/main/java/org/socialsignin/spring/data/dynamodb/repository/support/SimpleDynamoDBPagingAndSortingRepository.java +++ b/src/main/java/org/socialsignin/spring/data/dynamodb/repository/support/SimpleDynamoDBPagingAndSortingRepository.java @@ -64,15 +64,13 @@ public SimpleDynamoDBPagingAndSortingRepository(DynamoDBEntityInformation @Override public Iterable findAll(Sort sort) { - throw new UnsupportedOperationException("Sorting not supported for find all scan operations"); + return throwUnsupportedSortOperationException(); } @Override public Page findAll(Pageable pageable) { - if (pageable.getSort() != null) { - throw new UnsupportedOperationException("Sorting not supported for find all scan operations"); - } + ensureNoSort(pageable); DynamoDBScanExpression scanExpression = new DynamoDBScanExpression(); // Scan to the end of the page after the requested page diff --git a/src/main/java/org/socialsignin/spring/data/dynamodb/utils/SortHandler.java b/src/main/java/org/socialsignin/spring/data/dynamodb/utils/SortHandler.java new file mode 100644 index 00000000..2f71b2f5 --- /dev/null +++ b/src/main/java/org/socialsignin/spring/data/dynamodb/utils/SortHandler.java @@ -0,0 +1,45 @@ +/** + * Copyright © 2013 spring-data-dynamodb (https://github.com/derjust/spring-data-dynamodb) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 org.socialsignin.spring.data.dynamodb.utils; + +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; + +/** + * Some helper methods to deal with {@link Sort}. + * + * @author derjust + */ +public interface SortHandler { + + default void ensureNoSort(Pageable pageable) { + Sort sort = pageable.getSort(); + ensureNoSort(sort); + } + + /** + * @throws UnsupportedOperationException if a {@code sort} is initialized (non-null && not {@link Sort#unsorted()} + */ + default void ensureNoSort(Sort sort) throws UnsupportedOperationException { + if (!Sort.unsorted().equals(sort)) { + throwUnsupportedSortOperationException(); + } + } + + default T throwUnsupportedSortOperationException() { + throw new UnsupportedOperationException("Sorting not supported for scan expressions"); + } +} diff --git a/src/test/java/org/socialsignin/spring/data/dynamodb/config/DynamoDBAuditingRegistrarUnitTests.java b/src/test/java/org/socialsignin/spring/data/dynamodb/config/DynamoDBAuditingRegistrarUnitTests.java index cd5fa998..e9d0431a 100644 --- a/src/test/java/org/socialsignin/spring/data/dynamodb/config/DynamoDBAuditingRegistrarUnitTests.java +++ b/src/test/java/org/socialsignin/spring/data/dynamodb/config/DynamoDBAuditingRegistrarUnitTests.java @@ -18,7 +18,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; - import org.mockito.runners.MockitoJUnitRunner; + import org.mockito.junit.MockitoJUnitRunner; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.core.type.AnnotationMetadata; diff --git a/src/test/java/org/socialsignin/spring/data/dynamodb/core/FeedUserIT.java b/src/test/java/org/socialsignin/spring/data/dynamodb/core/FeedUserIT.java index 80682415..d65cf3bf 100644 --- a/src/test/java/org/socialsignin/spring/data/dynamodb/core/FeedUserIT.java +++ b/src/test/java/org/socialsignin/spring/data/dynamodb/core/FeedUserIT.java @@ -42,7 +42,7 @@ public static class TestAppConfig { @Test public void feed_test(){ - PageRequest pageRequest = new PageRequest(1, 10, new Sort(Direction.DESC, "usrNo")); + PageRequest pageRequest = PageRequest.of(1, 10, new Sort(Direction.DESC, "usrNo")); feedUserRepository.findByUsrNo(2, pageRequest); //runnable feedUserRepository.findByUsrNoAndFeedOpenYn(2, true, pageRequest); //not runnable } diff --git a/src/test/java/org/socialsignin/spring/data/dynamodb/query/AbstractMultipleEntityQueryTest.java b/src/test/java/org/socialsignin/spring/data/dynamodb/query/AbstractMultipleEntityQueryTest.java new file mode 100644 index 00000000..46a3537f --- /dev/null +++ b/src/test/java/org/socialsignin/spring/data/dynamodb/query/AbstractMultipleEntityQueryTest.java @@ -0,0 +1,85 @@ +/** + * Copyright © 2013 spring-data-dynamodb (https://github.com/derjust/spring-data-dynamodb) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 org.socialsignin.spring.data.dynamodb.query; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.socialsignin.spring.data.dynamodb.core.DynamoDBOperations; +import org.socialsignin.spring.data.dynamodb.domain.sample.User; +import org.springframework.dao.IncorrectResultSizeDataAccessException; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; + +@RunWith(MockitoJUnitRunner.class) +public class AbstractMultipleEntityQueryTest { + + private static class TestAbstractMultipleEntityQuery extends AbstractMultipleEntityQuery { + private final List resultList; + + public TestAbstractMultipleEntityQuery(DynamoDBOperations dynamoDBOperations, User... resultEntities) { + super(dynamoDBOperations, User.class); + resultList = Arrays.asList(resultEntities); + } + + @Override + public List getResultList() { + return resultList; + } + } + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Mock + private DynamoDBOperations dynamoDBOperations; + @Mock + private User entity; + + private AbstractMultipleEntityQuery underTest; + + @Test + public void testNullResult() { + underTest = new TestAbstractMultipleEntityQuery(dynamoDBOperations, new User[]{null}); + + assertNull(underTest.getSingleResult()); + } + + @Test + public void testSingleResult() { + underTest = new TestAbstractMultipleEntityQuery(dynamoDBOperations, entity); + + assertSame(entity, underTest.getSingleResult()); + } + + @Test + public void testMultiResult() { + expectedException.expect(IncorrectResultSizeDataAccessException.class); + underTest = new TestAbstractMultipleEntityQuery(dynamoDBOperations, entity, entity); + + underTest.getSingleResult(); + } +} diff --git a/src/test/java/org/socialsignin/spring/data/dynamodb/query/ScanExpressionCountQueryTest.java b/src/test/java/org/socialsignin/spring/data/dynamodb/query/ScanExpressionCountQueryTest.java new file mode 100644 index 00000000..a85a0457 --- /dev/null +++ b/src/test/java/org/socialsignin/spring/data/dynamodb/query/ScanExpressionCountQueryTest.java @@ -0,0 +1,83 @@ +/** + * Copyright © 2013 spring-data-dynamodb (https://github.com/derjust/spring-data-dynamodb) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 org.socialsignin.spring.data.dynamodb.query; + +import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBScanExpression; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.socialsignin.spring.data.dynamodb.core.DynamoDBOperations; +import org.socialsignin.spring.data.dynamodb.domain.sample.User; + +import java.util.concurrent.ExecutionException; + +import static org.junit.Assert.assertTrue; + +@RunWith(MockitoJUnitRunner.class) +public class ScanExpressionCountQueryTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Mock + private DynamoDBOperations dynamoDBOperations; + @Mock + private DynamoDBScanExpression scanExpression; + + private ScanExpressionCountQuery underTest; + + @Test + public void testScanCountEnabledTrueTrue() { + underTest = new ScanExpressionCountQuery<>(dynamoDBOperations, User.class, scanExpression, true); + + underTest.assertScanCountEnabled(true); + + assertTrue(true); + } + + @Test + public void testScanCountEnabledTrueFalse() { + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Scanning for the total counts for this query is not enabled. " + + " To enable annotate your repository method with @EnableScanCount, or enable scanning for all repository methods by annotating your repository interface with @EnableScanCount. " + + " This total count is required to serve this Page query - if total counts are not desired an alternative approach could be to replace the Page query with a Slice query "); + underTest = new ScanExpressionCountQuery<>(dynamoDBOperations, User.class, scanExpression, true); + + underTest.assertScanCountEnabled(false); + } + + @Test + public void testScanCountEnabledFalseTrue() { + underTest = new ScanExpressionCountQuery<>(dynamoDBOperations, User.class, scanExpression, false); + + underTest.assertScanCountEnabled(true); + + assertTrue(true); + } + + @Test + public void testScanCountEnabledFalseFalse() { + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Scanning for counts for this query is not enabled. " + + " To enable annotate your repository method with @EnableScanCount, or enable scanning for all repository methods by annotating your repository interface with @EnableScanCount"); + underTest = new ScanExpressionCountQuery<>(dynamoDBOperations, User.class, scanExpression, false); + + underTest.assertScanCountEnabled(false); + } +} diff --git a/src/test/java/org/socialsignin/spring/data/dynamodb/utils/DynamoDBLocalResource.java b/src/test/java/org/socialsignin/spring/data/dynamodb/utils/DynamoDBLocalResource.java index 670ccbfd..f8146f7e 100644 --- a/src/test/java/org/socialsignin/spring/data/dynamodb/utils/DynamoDBLocalResource.java +++ b/src/test/java/org/socialsignin/spring/data/dynamodb/utils/DynamoDBLocalResource.java @@ -47,14 +47,13 @@ public AmazonDynamoDB amazonDynamoDB() { return ddb; } - public static CreateTableResult createTable(AmazonDynamoDB ddb, Class domainType) { - DynamoDBEntityMetadataSupport support = new DynamoDBEntityMetadataSupport(domainType); - DynamoDBEntityInformation entityInfo = support.getEntityInformation(); + public static CreateTableResult createTable(AmazonDynamoDB ddb, Class domainType) { + DynamoDBEntityMetadataSupport support = new DynamoDBEntityMetadataSupport(domainType); + DynamoDBEntityInformation entityInfo = support.getEntityInformation(); String tableName = entityInfo.getDynamoDBTableName(); String hashKey = entityInfo.getHashKeyPropertyName(); - Optional columnName = entityInfo.getOverriddenAttributeName(hashKey); - hashKey = columnName.orElse(hashKey); + hashKey = entityInfo.getOverriddenAttributeName(hashKey).orElse(hashKey); Optional rangeKey = Optional.empty(); if (entityInfo instanceof DynamoDBIdIsHashAndRangeKeyEntityInformation) {