diff --git a/data/data-samples/sample-data-cassandra-reactive/src/main/java/io/americanexpress/data/book/repository/BookRepository.java b/data/data-samples/sample-data-cassandra-reactive/src/main/java/io/americanexpress/data/book/repository/BookRepository.java index 3e945ad39..5cba19b8a 100644 --- a/data/data-samples/sample-data-cassandra-reactive/src/main/java/io/americanexpress/data/book/repository/BookRepository.java +++ b/data/data-samples/sample-data-cassandra-reactive/src/main/java/io/americanexpress/data/book/repository/BookRepository.java @@ -14,8 +14,11 @@ package io.americanexpress.data.book.repository; import io.americanexpress.data.book.entity.BookEntity; +import org.springframework.data.cassandra.core.query.CassandraPageRequest; import org.springframework.data.cassandra.repository.AllowFiltering; import org.springframework.data.cassandra.repository.ReactiveCassandraRepository; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; import org.springframework.stereotype.Repository; import reactor.core.publisher.Mono; @@ -31,4 +34,7 @@ public interface BookRepository extends ReactiveCassandraRepository findByTitle(String title); + + Mono> findAllBy(Pageable pageable); + } diff --git a/service/service-samples/sample-service-reactive-cassandra-book/src/main/java/io/americanexpress/service/book/rest/controller/ReadPolyBookReactiveController.java b/service/service-samples/sample-service-reactive-cassandra-book/src/main/java/io/americanexpress/service/book/rest/controller/ReadPolyBookReactiveController.java new file mode 100644 index 000000000..36f0919f4 --- /dev/null +++ b/service/service-samples/sample-service-reactive-cassandra-book/src/main/java/io/americanexpress/service/book/rest/controller/ReadPolyBookReactiveController.java @@ -0,0 +1,30 @@ +/* + * Copyright 2020 American Express Travel Related Services Company, Inc. + * + * 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 io.americanexpress.service.book.rest.controller; + +import io.americanexpress.service.book.rest.config.BookEndpoints; +import io.americanexpress.service.book.rest.model.ReadBookResponse; +import io.americanexpress.service.book.rest.model.ReadBookPaginatedRequest; +import io.americanexpress.service.book.rest.service.ReadPolyBookReactiveService; +import io.americanexpress.synapse.service.rest.controller.reactive.BaseReadPolyReactiveController; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * {@code ReadPolyBookReactiveController} is the controller class for retrieving books from the Cassandra Book database. + */ +@RestController +@RequestMapping(BookEndpoints.BOOK_ENDPOINT) +public class ReadPolyBookReactiveController extends BaseReadPolyReactiveController { +} diff --git a/service/service-samples/sample-service-reactive-cassandra-book/src/main/java/io/americanexpress/service/book/rest/model/ReadBookPaginatedRequest.java b/service/service-samples/sample-service-reactive-cassandra-book/src/main/java/io/americanexpress/service/book/rest/model/ReadBookPaginatedRequest.java new file mode 100644 index 000000000..cbc3538c8 --- /dev/null +++ b/service/service-samples/sample-service-reactive-cassandra-book/src/main/java/io/americanexpress/service/book/rest/model/ReadBookPaginatedRequest.java @@ -0,0 +1,24 @@ +/* + * Copyright 2020 American Express Travel Related Services Company, Inc. + * + * 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 io.americanexpress.service.book.rest.model; + +import io.americanexpress.synapse.service.rest.model.BasePaginatedServiceRequest; + + +/** + * {@code ReadBookPaginatedRequest} is the request object for reading book paginated. + */ +public class ReadBookPaginatedRequest extends BasePaginatedServiceRequest { + +} diff --git a/service/service-samples/sample-service-reactive-cassandra-book/src/main/java/io/americanexpress/service/book/rest/service/ReadPolyBookReactiveService.java b/service/service-samples/sample-service-reactive-cassandra-book/src/main/java/io/americanexpress/service/book/rest/service/ReadPolyBookReactiveService.java new file mode 100644 index 000000000..711be4467 --- /dev/null +++ b/service/service-samples/sample-service-reactive-cassandra-book/src/main/java/io/americanexpress/service/book/rest/service/ReadPolyBookReactiveService.java @@ -0,0 +1,84 @@ +/* + * Copyright 2020 American Express Travel Related Services Company, Inc. + * + * 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 io.americanexpress.service.book.rest.service; + +import io.americanexpress.data.book.entity.BookEntity; +import io.americanexpress.data.book.repository.BookRepository; +import io.americanexpress.service.book.rest.model.ReadBookResponse; +import io.americanexpress.service.book.rest.model.ReadBookPaginatedRequest; +import io.americanexpress.service.book.rest.service.helper.ReadBookResponseCreator; +import io.americanexpress.synapse.service.rest.model.PageInformation; +import io.americanexpress.synapse.service.rest.service.reactive.BaseReadPolyReactiveService; +import org.springframework.data.cassandra.core.query.CassandraPageRequest; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.http.HttpHeaders; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; + +/** + * {@code ReadPolyBookReactiveService} is the service class for retrieving books from the Cassandra Book database. + */ +@Service +public class ReadPolyBookReactiveService extends BaseReadPolyReactiveService { + + private final BookRepository bookRepository; + + private Map pageInformationPagingStateMap = new HashMap<>(); + + + /** + * Instantiates a new Read poly book reactive service. + * + * @param bookRepository the book repository + */ + public ReadPolyBookReactiveService(BookRepository bookRepository) { + this.bookRepository = bookRepository; + } + + @Override + protected Flux executeRead(HttpHeaders headers, ReadBookPaginatedRequest request) { + Flux readBookResponseFlux; + if(request.getPageInformation() != null) { + Pageable pageable = PageRequest.of(0, request.getPageInformation().getSize()); + Pageable cassandraPageable = CassandraPageRequest.of(pageable, getPageState(request.getPageInformation())); + Mono> bookEntityList = bookRepository.findAllBy(cassandraPageable); + bookEntityList.map(Slice::nextOrLastPageable).subscribe(nextPageable -> addPageState(request.getPageInformation(), (CassandraPageRequest) nextPageable)); + return bookEntityList.flatMapMany(Flux::fromIterable).map(ReadBookResponseCreator::create); + }else { + readBookResponseFlux = bookRepository.findAll() + .map(ReadBookResponseCreator::create) + .switchIfEmpty(Flux.empty()); + } + return readBookResponseFlux; + } + private ByteBuffer getPageState(PageInformation pageInformation) { + return pageInformationPagingStateMap.get(pageInformation); + } + + private void addPageState(PageInformation pageInformation, CassandraPageRequest nextOrLastPageable) { + System.out.println("AddPageState"); + if(nextOrLastPageable.getPagingState() != null ) { + pageInformation.setPage(pageInformation.getPage() + 1); + pageInformationPagingStateMap.put(pageInformation, nextOrLastPageable.getPagingState()); + } + } +} + diff --git a/service/service-samples/sample-service-rest-cassandra-book/src/main/java/io/americanexpress/service/book/rest/controller/ReadPolyBookController.java b/service/service-samples/sample-service-rest-cassandra-book/src/main/java/io/americanexpress/service/book/rest/controller/ReadPolyBookController.java new file mode 100644 index 000000000..fba7198d5 --- /dev/null +++ b/service/service-samples/sample-service-rest-cassandra-book/src/main/java/io/americanexpress/service/book/rest/controller/ReadPolyBookController.java @@ -0,0 +1,30 @@ +/* + * Copyright 2020 American Express Travel Related Services Company, Inc. + * + * 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 io.americanexpress.service.book.rest.controller; + +import io.americanexpress.service.book.rest.config.BookEndpoints; +import io.americanexpress.service.book.rest.model.ReadBookPaginatedRequest; +import io.americanexpress.service.book.rest.model.ReadBookResponse; +import io.americanexpress.service.book.rest.service.ReadPolyBookService; +import io.americanexpress.synapse.service.rest.controller.BaseReadPolyController; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * {@code ReadPolyBookController} is the controller class for reading books in the Cassandra Book database. + */ +@RestController +@RequestMapping(BookEndpoints.BOOK_ENDPOINT) +public class ReadPolyBookController extends BaseReadPolyController { +} diff --git a/service/service-samples/sample-service-rest-cassandra-book/src/main/java/io/americanexpress/service/book/rest/model/ReadBookPaginatedRequest.java b/service/service-samples/sample-service-rest-cassandra-book/src/main/java/io/americanexpress/service/book/rest/model/ReadBookPaginatedRequest.java new file mode 100644 index 000000000..cbc3538c8 --- /dev/null +++ b/service/service-samples/sample-service-rest-cassandra-book/src/main/java/io/americanexpress/service/book/rest/model/ReadBookPaginatedRequest.java @@ -0,0 +1,24 @@ +/* + * Copyright 2020 American Express Travel Related Services Company, Inc. + * + * 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 io.americanexpress.service.book.rest.model; + +import io.americanexpress.synapse.service.rest.model.BasePaginatedServiceRequest; + + +/** + * {@code ReadBookPaginatedRequest} is the request object for reading book paginated. + */ +public class ReadBookPaginatedRequest extends BasePaginatedServiceRequest { + +} diff --git a/service/service-samples/sample-service-rest-cassandra-book/src/main/java/io/americanexpress/service/book/rest/service/ReadBookService.java b/service/service-samples/sample-service-rest-cassandra-book/src/main/java/io/americanexpress/service/book/rest/service/ReadBookService.java index 73979a13b..6cbc68b1b 100644 --- a/service/service-samples/sample-service-rest-cassandra-book/src/main/java/io/americanexpress/service/book/rest/service/ReadBookService.java +++ b/service/service-samples/sample-service-rest-cassandra-book/src/main/java/io/americanexpress/service/book/rest/service/ReadBookService.java @@ -25,7 +25,7 @@ import java.util.Optional; /** - * {@code ReadBookService} is the service class for creating a book in the Cassandra Book database. + * {@code ReadBookService} is the service class for reading a book in the Cassandra Book database. */ @Service public class ReadBookService extends BaseReadMonoService { diff --git a/service/service-samples/sample-service-rest-cassandra-book/src/main/java/io/americanexpress/service/book/rest/service/ReadPolyBookService.java b/service/service-samples/sample-service-rest-cassandra-book/src/main/java/io/americanexpress/service/book/rest/service/ReadPolyBookService.java new file mode 100644 index 000000000..3367cf5d0 --- /dev/null +++ b/service/service-samples/sample-service-rest-cassandra-book/src/main/java/io/americanexpress/service/book/rest/service/ReadPolyBookService.java @@ -0,0 +1,83 @@ +/* + * Copyright 2020 American Express Travel Related Services Company, Inc. + * + * 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 io.americanexpress.service.book.rest.service; + +import io.americanexpress.data.book.entity.BookEntity; +import io.americanexpress.data.book.repository.BookRepository; +import io.americanexpress.service.book.rest.model.ReadBookPaginatedRequest; +import io.americanexpress.service.book.rest.model.ReadBookResponse; +import io.americanexpress.service.book.rest.service.helper.ReadBookResponseCreator; +import io.americanexpress.synapse.service.rest.model.PageInformation; +import io.americanexpress.synapse.service.rest.service.BaseReadPolyService; +import org.springframework.data.cassandra.core.query.CassandraPageRequest; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.http.HttpHeaders; +import org.springframework.stereotype.Service; + +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * {@code ReadPolyBookService} is the service class for retrieving books from the Cassandra Book database. + */ +@Service +public class ReadPolyBookService extends BaseReadPolyService { + + private final BookRepository bookRepository; + + private Map pageInformationPagingStateMap = new HashMap<>(); + + /** + * Instantiates a new Read poly book service. + * + * @param bookRepository the book repository + */ + public ReadPolyBookService(BookRepository bookRepository) { + this.bookRepository = bookRepository; + } + + @Override + protected Page executeRead(HttpHeaders headers, ReadBookPaginatedRequest request) { + List readBookResponses; + if(request.getPageInformation() != null) { + Pageable pageable = PageRequest.of(0, request.getPageInformation().getSize()); + Pageable cassandraPageable = CassandraPageRequest.of(pageable, getPageState(request.getPageInformation())); + + Slice bookEntitySlice = bookRepository.findAll(cassandraPageable); + addPageState(request.getPageInformation(), (CassandraPageRequest) bookEntitySlice.nextOrLastPageable()); + + readBookResponses = bookEntitySlice.getContent().stream().map(ReadBookResponseCreator::create).toList(); + }else { + readBookResponses = bookRepository.findAll().stream().map(ReadBookResponseCreator::create).toList(); + } + return new PageImpl<>(readBookResponses); + } + + private ByteBuffer getPageState(PageInformation pageInformation) { + return pageInformationPagingStateMap.get(pageInformation); + } + + private void addPageState(PageInformation pageInformation, CassandraPageRequest nextOrLastPageable) { + if(nextOrLastPageable.getPagingState() != null ) { + pageInformation.setPage(pageInformation.getPage() + 1); + pageInformationPagingStateMap.put(pageInformation, nextOrLastPageable.getPagingState()); + } + } +} diff --git a/service/synapse-service-rest/src/main/java/io/americanexpress/synapse/service/rest/model/PageInformation.java b/service/synapse-service-rest/src/main/java/io/americanexpress/synapse/service/rest/model/PageInformation.java index 1c8d1b7e5..e0355bcaa 100644 --- a/service/synapse-service-rest/src/main/java/io/americanexpress/synapse/service/rest/model/PageInformation.java +++ b/service/synapse-service-rest/src/main/java/io/americanexpress/synapse/service/rest/model/PageInformation.java @@ -13,6 +13,8 @@ */ package io.americanexpress.synapse.service.rest.model; +import java.util.Objects; + /** * {@code PageInformation} class specifies the parameters for a service request, * limiting the results to a subset of how many (size) and on which page (page). @@ -65,4 +67,17 @@ public int getSize() { public void setSize(int size) { this.size = size; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + PageInformation that = (PageInformation) o; + return page == that.page && size == that.size; + } + + @Override + public int hashCode() { + return Objects.hash(page, size); + } }