From b88e557fcb143fb218a800ad43a9ec152c1c2167 Mon Sep 17 00:00:00 2001 From: weiping Date: Mon, 29 Oct 2018 14:11:28 +0800 Subject: [PATCH] support pageable query with sort (#272) * support pageable query with sort --- .../cosmosdb/core/DocumentDbTemplate.java | 4 ++ .../core/query/DocumentDbPageRequest.java | 10 +++++ .../cosmosdb/core/DocumentDbTemplateIT.java | 44 +++++++++++-------- .../cosmosdb/domain/NoDBAnnotationPerson.java | 22 ++++++++++ .../spring/data/cosmosdb/domain/Person.java | 3 ++ .../DocumentDBAnnotationUnitTest.java | 25 ++++++----- .../integration/ProjectRepositorySortIT.java | 36 +++++++++++++++ .../repository/ProjectRepository.java | 4 ++ 8 files changed, 117 insertions(+), 31 deletions(-) create mode 100644 src/test/java/com/microsoft/azure/spring/data/cosmosdb/domain/NoDBAnnotationPerson.java diff --git a/src/main/java/com/microsoft/azure/spring/data/cosmosdb/core/DocumentDbTemplate.java b/src/main/java/com/microsoft/azure/spring/data/cosmosdb/core/DocumentDbTemplate.java index 7e68eb8..8a53bbc 100644 --- a/src/main/java/com/microsoft/azure/spring/data/cosmosdb/core/DocumentDbTemplate.java +++ b/src/main/java/com/microsoft/azure/spring/data/cosmosdb/core/DocumentDbTemplate.java @@ -468,6 +468,10 @@ public class DocumentDbTemplate implements DocumentDbOperations, ApplicationCont @Override public Page findAll(Pageable pageable, Class domainClass, String collectionName) { final DocumentQuery query = new DocumentQuery(Criteria.getInstance(CriteriaType.ALL)).with(pageable); + if (pageable.getSort().isSorted()) { + query.with(pageable.getSort()); + } + return paginationQuery(query, domainClass, collectionName); } diff --git a/src/main/java/com/microsoft/azure/spring/data/cosmosdb/core/query/DocumentDbPageRequest.java b/src/main/java/com/microsoft/azure/spring/data/cosmosdb/core/query/DocumentDbPageRequest.java index 1a99805..d73981a 100644 --- a/src/main/java/com/microsoft/azure/spring/data/cosmosdb/core/query/DocumentDbPageRequest.java +++ b/src/main/java/com/microsoft/azure/spring/data/cosmosdb/core/query/DocumentDbPageRequest.java @@ -6,6 +6,7 @@ package com.microsoft.azure.spring.data.cosmosdb.core.query; import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; /** * DocumentDbPageRequest representing page request during pagination query, field @@ -29,6 +30,15 @@ public class DocumentDbPageRequest extends PageRequest { return new DocumentDbPageRequest(page, size, requestContinuation); } + public DocumentDbPageRequest(int page, int size, String requestContinuation, Sort sort) { + super(page, size, sort); + this.requestContinuation = requestContinuation; + } + + public static DocumentDbPageRequest of(int page, int size, String requestContinuation, Sort sort) { + return new DocumentDbPageRequest(page, size, requestContinuation, sort); + } + public String getRequestContinuation() { return this.requestContinuation; } diff --git a/src/test/java/com/microsoft/azure/spring/data/cosmosdb/core/DocumentDbTemplateIT.java b/src/test/java/com/microsoft/azure/spring/data/cosmosdb/core/DocumentDbTemplateIT.java index dd454a6..ec92955 100644 --- a/src/test/java/com/microsoft/azure/spring/data/cosmosdb/core/DocumentDbTemplateIT.java +++ b/src/test/java/com/microsoft/azure/spring/data/cosmosdb/core/DocumentDbTemplateIT.java @@ -7,10 +7,9 @@ package com.microsoft.azure.spring.data.cosmosdb.core; import com.fasterxml.jackson.databind.ObjectMapper; -import com.microsoft.azure.documentdb.*; +import com.microsoft.azure.documentdb.DocumentCollection; import com.microsoft.azure.spring.data.cosmosdb.DocumentDbFactory; import com.microsoft.azure.spring.data.cosmosdb.common.TestConstants; -import com.microsoft.azure.spring.data.cosmosdb.common.TestUtils; import com.microsoft.azure.spring.data.cosmosdb.config.DocumentDBConfig; import com.microsoft.azure.spring.data.cosmosdb.core.convert.MappingDocumentDbConverter; import com.microsoft.azure.spring.data.cosmosdb.core.mapping.DocumentDbMappingContext; @@ -33,8 +32,8 @@ import org.springframework.context.annotation.PropertySource; import org.springframework.data.annotation.Persistent; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.util.Assert; import java.util.Arrays; import java.util.List; @@ -42,9 +41,7 @@ import java.util.UUID; import static com.microsoft.azure.spring.data.cosmosdb.common.PageTestUtils.validateLastPage; import static com.microsoft.azure.spring.data.cosmosdb.common.PageTestUtils.validateNonLastPage; -import static com.microsoft.azure.spring.data.cosmosdb.common.TestConstants.DB_NAME; -import static com.microsoft.azure.spring.data.cosmosdb.common.TestConstants.PAGE_SIZE_1; -import static com.microsoft.azure.spring.data.cosmosdb.common.TestConstants.PAGE_SIZE_2; +import static com.microsoft.azure.spring.data.cosmosdb.common.TestConstants.*; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertTrue; @@ -57,6 +54,9 @@ public class DocumentDbTemplateIT { private static final Person TEST_PERSON_2 = new Person(TestConstants.ID_2, TestConstants.NEW_FIRST_NAME, TestConstants.NEW_LAST_NAME, TestConstants.HOBBIES, TestConstants.ADDRESSES); + private static final Person TEST_PERSON_3 = new Person(TestConstants.ID_3, TestConstants.NEW_FIRST_NAME, + TestConstants.NEW_LAST_NAME, TestConstants.HOBBIES, TestConstants.ADDRESSES); + @Value("${cosmosdb.uri}") private String documentDbUri; @Value("${cosmosdb.key}") @@ -160,19 +160,6 @@ public class DocumentDbTemplateIT { assertTrue(result.get(0).equals(TEST_PERSON_2)); } - @Test - public void testDocumentDBAnnotation() { - final IndexingPolicy policy = collectionPerson.getIndexingPolicy(); - - Assert.isTrue(policy.getAutomatic() == TestConstants.DEFAULT_INDEXINGPOLICY_AUTOMATIC, - "class Person collection policy should be default automatic"); - Assert.isTrue(policy.getIndexingMode() == TestConstants.DEFAULT_INDEXINGPOLICY_MODE, - "class Person collection policy should be default indexing mode"); - - TestUtils.testIndexingPolicyPathsEquals(policy.getIncludedPaths(), TestConstants.DEFAULT_INCLUDEDPATHS); - TestUtils.testIndexingPolicyPathsEquals(policy.getExcludedPaths(), TestConstants.DEFAULT_EXCLUDEDPATHS); - } - @Test public void testCountByCollection() { final long prevCount = dbTemplate.count(collectionName); @@ -224,4 +211,23 @@ public class DocumentDbTemplateIT { assertThat(page.getContent().size()).isEqualTo(1); validateLastPage(page, PAGE_SIZE_2); } + + @Test + public void testFindAllWithPageableAndSort() { + dbTemplate.insert(TEST_PERSON_2, null); + dbTemplate.insert(TEST_PERSON_3, null); + + final Sort sort = new Sort(Sort.Direction.DESC, "firstName"); + final PageRequest pageRequest = DocumentDbPageRequest.of(0, PAGE_SIZE_3, null, sort); + + final Page page = dbTemplate.findAll(pageRequest, Person.class, collectionName); + assertThat(page.getContent().size()).isEqualTo(3); + validateLastPage(page, PAGE_SIZE_3); + + final List result = page.getContent(); + assertThat(result.get(0).getFirstName()).isEqualTo(NEW_FIRST_NAME); + assertThat(result.get(1).getFirstName()).isEqualTo(NEW_FIRST_NAME); + assertThat(result.get(2).getFirstName()).isEqualTo(FIRST_NAME); + + } } diff --git a/src/test/java/com/microsoft/azure/spring/data/cosmosdb/domain/NoDBAnnotationPerson.java b/src/test/java/com/microsoft/azure/spring/data/cosmosdb/domain/NoDBAnnotationPerson.java new file mode 100644 index 0000000..d4aa2db --- /dev/null +++ b/src/test/java/com/microsoft/azure/spring/data/cosmosdb/domain/NoDBAnnotationPerson.java @@ -0,0 +1,22 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See LICENSE in the project root for + * license information. + */ + +package com.microsoft.azure.spring.data.cosmosdb.domain; + +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.util.List; + +@Data +@AllArgsConstructor +public class NoDBAnnotationPerson { + private String id; + private String firstName; + private String lastName; + private List hobbies; + private List
shippingAddresses; +} diff --git a/src/test/java/com/microsoft/azure/spring/data/cosmosdb/domain/Person.java b/src/test/java/com/microsoft/azure/spring/data/cosmosdb/domain/Person.java index 48b919d..f0961f4 100644 --- a/src/test/java/com/microsoft/azure/spring/data/cosmosdb/domain/Person.java +++ b/src/test/java/com/microsoft/azure/spring/data/cosmosdb/domain/Person.java @@ -6,6 +6,8 @@ package com.microsoft.azure.spring.data.cosmosdb.domain; +import com.microsoft.azure.spring.data.cosmosdb.common.TestConstants; +import com.microsoft.azure.spring.data.cosmosdb.core.mapping.DocumentIndexingPolicy; import lombok.AllArgsConstructor; import lombok.Data; @@ -13,6 +15,7 @@ import java.util.List; @Data @AllArgsConstructor +@DocumentIndexingPolicy(includePaths = TestConstants.ORDER_BY_STRING_PATH) public class Person { private String id; private String firstName; diff --git a/src/test/java/com/microsoft/azure/spring/data/cosmosdb/repository/DocumentDBAnnotationUnitTest.java b/src/test/java/com/microsoft/azure/spring/data/cosmosdb/repository/DocumentDBAnnotationUnitTest.java index a11d0c8..356eb57 100644 --- a/src/test/java/com/microsoft/azure/spring/data/cosmosdb/repository/DocumentDBAnnotationUnitTest.java +++ b/src/test/java/com/microsoft/azure/spring/data/cosmosdb/repository/DocumentDBAnnotationUnitTest.java @@ -10,7 +10,7 @@ import com.microsoft.azure.spring.data.cosmosdb.common.TestConstants; import com.microsoft.azure.spring.data.cosmosdb.common.TestUtils; import com.microsoft.azure.spring.data.cosmosdb.core.mapping.Document; import com.microsoft.azure.spring.data.cosmosdb.core.mapping.DocumentIndexingPolicy; -import com.microsoft.azure.spring.data.cosmosdb.domain.Person; +import com.microsoft.azure.spring.data.cosmosdb.domain.NoDBAnnotationPerson; import com.microsoft.azure.spring.data.cosmosdb.domain.Role; import com.microsoft.azure.spring.data.cosmosdb.domain.TimeToLiveSample; import com.microsoft.azure.spring.data.cosmosdb.repository.support.DocumentDbEntityInformation; @@ -20,27 +20,28 @@ import org.springframework.util.Assert; public class DocumentDBAnnotationUnitTest { - private DocumentDbEntityInformation personInfo; + private DocumentDbEntityInformation personInfo; private DocumentDbEntityInformation roleInfo; @Before public void setUp() { - personInfo = new DocumentDbEntityInformation<>(Person.class); + personInfo = new DocumentDbEntityInformation<>(NoDBAnnotationPerson.class); roleInfo = new DocumentDbEntityInformation<>(Role.class); } @Test public void testDefaultIndexingPolicyAnnotation() { final IndexingPolicy policy = personInfo.getIndexingPolicy(); - final Document documentAnnotation = Person.class.getAnnotation(Document.class); - final DocumentIndexingPolicy policyAnnotation = Person.class.getAnnotation(DocumentIndexingPolicy.class); + final Document documentAnnotation = NoDBAnnotationPerson.class.getAnnotation(Document.class); + final DocumentIndexingPolicy policyAnnotation = + NoDBAnnotationPerson.class.getAnnotation(DocumentIndexingPolicy.class); - Assert.isNull(documentAnnotation, "Person class should not have Document annotation"); - Assert.isNull(policyAnnotation, "Person class should not have DocumentIndexingPolicy annotation"); - Assert.notNull(policy, "Person class collection policy should not be null"); + Assert.isNull(documentAnnotation, "NoDBAnnotationPerson class should not have Document annotation"); + Assert.isNull(policyAnnotation, "NoDBAnnotationPerson class should not have DocumentIndexingPolicy annotation"); + Assert.notNull(policy, "NoDBAnnotationPerson class collection policy should not be null"); // CollectionName, RequestUnit, Automatic and IndexingMode - Assert.isTrue(personInfo.getCollectionName().equals(TestConstants.DEFAULT_COLLECTION_NAME), + Assert.isTrue(personInfo.getCollectionName().equals(NoDBAnnotationPerson.class.getSimpleName()), "should be default collection name"); Assert.isTrue(personInfo.getRequestUnit() == TestConstants.DEFAULT_REQUEST_UNIT, "should be default request unit"); @@ -65,9 +66,9 @@ public class DocumentDBAnnotationUnitTest { final DocumentIndexingPolicy policyAnnotation = Role.class.getAnnotation(DocumentIndexingPolicy.class); // CollectionName, RequestUnit, Automatic and IndexingMode - Assert.notNull(documentAnnotation, "Person class should have Document annotation"); - Assert.notNull(policyAnnotation, "Person class should have DocumentIndexingPolicy annotation"); - Assert.notNull(policy, "Person class collection policy should not be null"); + Assert.notNull(documentAnnotation, "NoDBAnnotationPerson class should have Document annotation"); + Assert.notNull(policyAnnotation, "NoDBAnnotationPerson class should have DocumentIndexingPolicy annotation"); + Assert.notNull(policy, "NoDBAnnotationPerson class collection policy should not be null"); Assert.isTrue(roleInfo.getCollectionName().equals(TestConstants.ROLE_COLLECTION_NAME), "should be Role(class) collection name"); diff --git a/src/test/java/com/microsoft/azure/spring/data/cosmosdb/repository/integration/ProjectRepositorySortIT.java b/src/test/java/com/microsoft/azure/spring/data/cosmosdb/repository/integration/ProjectRepositorySortIT.java index bf4bc61..394db4a 100644 --- a/src/test/java/com/microsoft/azure/spring/data/cosmosdb/repository/integration/ProjectRepositorySortIT.java +++ b/src/test/java/com/microsoft/azure/spring/data/cosmosdb/repository/integration/ProjectRepositorySortIT.java @@ -6,6 +6,7 @@ package com.microsoft.azure.spring.data.cosmosdb.repository.integration; import com.google.common.collect.Lists; +import com.microsoft.azure.spring.data.cosmosdb.core.query.DocumentDbPageRequest; import com.microsoft.azure.spring.data.cosmosdb.domain.Project; import com.microsoft.azure.spring.data.cosmosdb.exception.IllegalQueryException; import com.microsoft.azure.spring.data.cosmosdb.repository.TestRepositoryConfig; @@ -16,6 +17,8 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -24,6 +27,8 @@ import java.util.Arrays; import java.util.Comparator; import java.util.List; +import static com.microsoft.azure.spring.data.cosmosdb.common.PageTestUtils.validateLastPage; + @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = TestRepositoryConfig.class) public class ProjectRepositorySortIT { @@ -177,5 +182,36 @@ public class ProjectRepositorySortIT { Assert.assertEquals(references.size(), projects.size()); Assert.assertEquals(references, projects); } + + @Test + public void testFindAllWithPageableAndSort() { + final Sort sort = new Sort(Sort.Direction.DESC, "name"); + final Pageable pageable = new DocumentDbPageRequest(0, 5, null, sort); + + final Page result = this.repository.findAll(pageable); + + final List references = Arrays.asList(PROJECT_0, PROJECT_1, PROJECT_2, PROJECT_3, PROJECT_4); + references.sort(Comparator.comparing(Project::getName).reversed()); + + Assert.assertEquals(references.size(), result.getContent().size()); + Assert.assertEquals(references, result.getContent()); + validateLastPage(result, 5); + } + + @Test + public void testFindWithPageableAndSort() { + final Sort sort = new Sort(Sort.Direction.DESC, "name"); + final Pageable pageable = new DocumentDbPageRequest(0, 5, null, sort); + + final Page result = this.repository.findByForkCount(FORK_COUNT_3, pageable); + + final List references = Arrays.asList(PROJECT_3, PROJECT_4); + + references.sort(Comparator.comparing(Project::getName).reversed()); + + Assert.assertEquals(references.size(), result.getContent().size()); + Assert.assertEquals(references, result.getContent()); + validateLastPage(result, 5); + } } diff --git a/src/test/java/com/microsoft/azure/spring/data/cosmosdb/repository/repository/ProjectRepository.java b/src/test/java/com/microsoft/azure/spring/data/cosmosdb/repository/repository/ProjectRepository.java index 6fb93bd..021205c 100644 --- a/src/test/java/com/microsoft/azure/spring/data/cosmosdb/repository/repository/ProjectRepository.java +++ b/src/test/java/com/microsoft/azure/spring/data/cosmosdb/repository/repository/ProjectRepository.java @@ -7,6 +7,8 @@ package com.microsoft.azure.spring.data.cosmosdb.repository.repository; import com.microsoft.azure.spring.data.cosmosdb.domain.Project; import com.microsoft.azure.spring.data.cosmosdb.repository.DocumentDbRepository; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import java.util.Collection; @@ -82,4 +84,6 @@ public interface ProjectRepository extends DocumentDbRepository List findByNameIsNotNull(); List findByNameIsNotNullAndHasReleased(boolean hasReleased); + + Page findByForkCount(Long forkCount, Pageable pageable); }