This is an automated email from the ASF dual-hosted git repository. myrle pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/fineract-cn-customer.git
commit 41749c5927fd9066710ad2757184b46d54b34cdc Author: Myrle Krantz <my...@apache.org> AuthorDate: Fri Oct 20 12:01:07 2017 +0200 Added delete document endpoint. --- .../customer/api/v1/CustomerEventConstants.java | 2 + .../api/v1/client/CustomerDocumentsManager.java | 14 +++++++ .../main/java/io/mifos/customer/TestDocuments.java | 38 +++++++++++++++++- .../customer/listener/DocumentEventListener.java | 10 +++++ .../internal/command/DeleteDocumentCommand.java | 45 ++++++++++++++++++++++ .../command/handler/DocumentCommandHandler.java | 16 ++++++++ .../rest/controller/DocumentsRestController.java | 22 +++++++++++ 7 files changed, 146 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/io/mifos/customer/api/v1/CustomerEventConstants.java b/api/src/main/java/io/mifos/customer/api/v1/CustomerEventConstants.java index 7a47b73..9608f83 100644 --- a/api/src/main/java/io/mifos/customer/api/v1/CustomerEventConstants.java +++ b/api/src/main/java/io/mifos/customer/api/v1/CustomerEventConstants.java @@ -49,6 +49,7 @@ public interface CustomerEventConstants { String POST_DOCUMENT = "post-document"; String PUT_DOCUMENT = "put-document"; + String DELETE_DOCUMENT = "delete-document"; String POST_DOCUMENT_PAGE = "post-document-page"; String DELETE_DOCUMENT_PAGE = "delete-document-page"; String POST_DOCUMENT_COMPLETE = "post-document-complete"; @@ -81,6 +82,7 @@ public interface CustomerEventConstants { String SELECTOR_POST_DOCUMENT = SELECTOR_NAME + " = '" + POST_DOCUMENT + "'"; String SELECTOR_PUT_DOCUMENT = SELECTOR_NAME + " = '" + PUT_DOCUMENT + "'"; + String SELECTOR_DELETE_DOCUMENT = SELECTOR_NAME + " = '" + DELETE_DOCUMENT + "'"; String SELECTOR_POST_DOCUMENT_PAGE = SELECTOR_NAME + " = '" + POST_DOCUMENT_PAGE + "'"; String SELECTOR_DELETE_DOCUMENT_PAGE = SELECTOR_NAME + " = '" + DELETE_DOCUMENT_PAGE + "'"; String SELECTOR_POST_DOCUMENT_COMPLETE = SELECTOR_NAME + " = '" + POST_DOCUMENT_COMPLETE + "'"; diff --git a/api/src/main/java/io/mifos/customer/api/v1/client/CustomerDocumentsManager.java b/api/src/main/java/io/mifos/customer/api/v1/client/CustomerDocumentsManager.java index 56ba88a..16575d8 100644 --- a/api/src/main/java/io/mifos/customer/api/v1/client/CustomerDocumentsManager.java +++ b/api/src/main/java/io/mifos/customer/api/v1/client/CustomerDocumentsManager.java @@ -87,6 +87,20 @@ public interface CustomerDocumentsManager { @RequestBody final CustomerDocument customerDocument); + @RequestMapping( + value = "/customers/{customeridentifier}/documents/{documentidentifier}", + method = RequestMethod.DELETE, + produces = MediaType.ALL_VALUE, + consumes = MediaType.APPLICATION_JSON_VALUE + ) + @ThrowsExceptions({ + @ThrowsException(status = HttpStatus.CONFLICT, exception = CompletedDocumentCannotBeChangedException.class) + }) + void deleteDocument( + @PathVariable("customeridentifier") final String customerIdentifier, + @PathVariable("documentidentifier") final String documentIdentifier); + + /** * Once a document is "completed" its name and images cannot be changed again. Only completed * documents should be referenced by other services. diff --git a/component-test/src/main/java/io/mifos/customer/TestDocuments.java b/component-test/src/main/java/io/mifos/customer/TestDocuments.java index 8b8e6d1..3b14735 100644 --- a/component-test/src/main/java/io/mifos/customer/TestDocuments.java +++ b/component-test/src/main/java/io/mifos/customer/TestDocuments.java @@ -44,6 +44,37 @@ import java.util.stream.IntStream; public class TestDocuments extends AbstractCustomerTest { @Test + public void shouldUploadThenDeleteInCompleteDocument() throws InterruptedException, IOException { + logger.info("Prepare test"); + final Customer customer = CustomerGenerator.createRandomCustomer(); + customerManager.createCustomer(customer); + Assert.assertTrue(eventRecorder.wait(CustomerEventConstants.POST_CUSTOMER, customer.getIdentifier())); + + final CustomerDocument customerDocument = CustomerDocumentGenerator.createRandomCustomerDocument(); + customerDocumentsManager.createDocument(customer.getIdentifier(), customerDocument.getIdentifier(), customerDocument); + Assert.assertTrue(eventRecorder.wait(CustomerEventConstants.POST_DOCUMENT, + new DocumentEvent(customer.getIdentifier(), customerDocument.getIdentifier()))); + + for (int i = 0; i < 5; i++) { + createDocumentPage(customer.getIdentifier(), customerDocument.getIdentifier(), i); + } + + logger.info("Delete document"); + customerDocumentsManager.deleteDocument(customer.getIdentifier(), customerDocument.getIdentifier()); + Assert.assertTrue(eventRecorder.wait(CustomerEventConstants.DELETE_DOCUMENT, + new DocumentEvent(customer.getIdentifier(), customerDocument.getIdentifier()))); + + try { + customerDocumentsManager.getDocument(customer.getIdentifier(), customerDocument.getIdentifier()); + Assert.fail("Deleted document should not be findable"); + } + catch (final NotFoundException ignored) {} + + final List<CustomerDocument> customersDocuments = customerDocumentsManager.getDocuments(customer.getIdentifier()); + Assert.assertFalse(customersDocuments.contains(customerDocument)); + } + + @Test public void shouldUploadEditThenCompleteDocument() throws InterruptedException, IOException { logger.info("Prepare test"); final Customer customer = CustomerGenerator.createRandomCustomer(); @@ -128,7 +159,7 @@ public class TestDocuments extends AbstractCustomerTest { timeStampChecker.assertCorrect(completedDocument.getCreatedOn()); - logger.info("Check that document can't be changed after completion"); + logger.info("Check that document can't be changed or removed after completion"); try { createDocumentPage(customer.getIdentifier(), customerDocument.getIdentifier(), 9); Assert.fail("Adding another page after the document is completed shouldn't be possible."); @@ -144,6 +175,11 @@ public class TestDocuments extends AbstractCustomerTest { Assert.fail("Changing a document after it is completed shouldn't be possible."); } catch (final CompletedDocumentCannotBeChangedException ignored) {} + try { + customerDocumentsManager.deleteDocument(customer.getIdentifier(), customerDocument.getIdentifier()); + Assert.fail("Changing a document after it is completed shouldn't be possible."); + } + catch (final CompletedDocumentCannotBeChangedException ignored) {} logger.info("Check that document can't be uncompleted"); diff --git a/component-test/src/main/java/io/mifos/customer/listener/DocumentEventListener.java b/component-test/src/main/java/io/mifos/customer/listener/DocumentEventListener.java index 346df99..2293397 100644 --- a/component-test/src/main/java/io/mifos/customer/listener/DocumentEventListener.java +++ b/component-test/src/main/java/io/mifos/customer/listener/DocumentEventListener.java @@ -61,6 +61,16 @@ public class DocumentEventListener { @JmsListener( destination = CustomerEventConstants.DESTINATION, + selector = CustomerEventConstants.SELECTOR_DELETE_DOCUMENT + ) + public void deleteDocumentEvent( + @Header(TenantHeaderFilter.TENANT_HEADER) final String tenant, + final String payload) { + this.eventRecorder.event(tenant, CustomerEventConstants.DELETE_DOCUMENT, payload, DocumentEvent.class); + } + + @JmsListener( + destination = CustomerEventConstants.DESTINATION, selector = CustomerEventConstants.SELECTOR_POST_DOCUMENT_PAGE ) public void postDocumentPageEvent( diff --git a/service/src/main/java/io/mifos/customer/service/internal/command/DeleteDocumentCommand.java b/service/src/main/java/io/mifos/customer/service/internal/command/DeleteDocumentCommand.java new file mode 100644 index 0000000..f1b17e6 --- /dev/null +++ b/service/src/main/java/io/mifos/customer/service/internal/command/DeleteDocumentCommand.java @@ -0,0 +1,45 @@ +/* + * Copyright 2017 The Mifos Initiative. + * + * 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.mifos.customer.service.internal.command; + +/** + * @author Myrle Krantz + */ +public class DeleteDocumentCommand { + private final String customerIdentifier; + private final String documentIdentifier; + + public DeleteDocumentCommand(String customerIdentifier, String documentIdentifier) { + this.customerIdentifier = customerIdentifier; + this.documentIdentifier = documentIdentifier; + } + + public String getCustomerIdentifier() { + return customerIdentifier; + } + + public String getDocumentIdentifier() { + return documentIdentifier; + } + + @Override + public String toString() { + return "DeleteDocumentCommand{" + + "customerIdentifier='" + customerIdentifier + '\'' + + ", documentIdentifier='" + documentIdentifier + '\'' + + '}'; + } +} diff --git a/service/src/main/java/io/mifos/customer/service/internal/command/handler/DocumentCommandHandler.java b/service/src/main/java/io/mifos/customer/service/internal/command/handler/DocumentCommandHandler.java index 5be492e..9c27aab 100644 --- a/service/src/main/java/io/mifos/customer/service/internal/command/handler/DocumentCommandHandler.java +++ b/service/src/main/java/io/mifos/customer/service/internal/command/handler/DocumentCommandHandler.java @@ -100,6 +100,22 @@ public class DocumentCommandHandler { @Transactional @CommandHandler + @EventEmitter(selectorName = CustomerEventConstants.SELECTOR_NAME, selectorValue = CustomerEventConstants.DELETE_DOCUMENT) + public DocumentEvent process(final DeleteDocumentCommand command) throws IOException { + final DocumentEntity existingDocument = documentRepository.findByCustomerIdAndDocumentIdentifier( + command.getCustomerIdentifier(), command.getDocumentIdentifier()) + .orElseThrow(() -> + ServiceException.notFound("Document ''{0}'' for customer ''{1}'' not found", + command.getDocumentIdentifier(), command.getCustomerIdentifier())); + documentPageRepository.findByCustomerIdAndDocumentIdentifier(command.getCustomerIdentifier(), command.getDocumentIdentifier()) + .forEach(documentPageRepository::delete); + documentRepository.delete(existingDocument); + + return new DocumentEvent(command.getCustomerIdentifier(), command.getDocumentIdentifier()); + } + + @Transactional + @CommandHandler @EventEmitter(selectorName = CustomerEventConstants.SELECTOR_NAME, selectorValue = CustomerEventConstants.POST_DOCUMENT_COMPLETE) public DocumentEvent process(final CompleteDocumentCommand command) throws IOException { final DocumentEntity documentEntity = documentRepository.findByCustomerIdAndDocumentIdentifier( diff --git a/service/src/main/java/io/mifos/customer/service/rest/controller/DocumentsRestController.java b/service/src/main/java/io/mifos/customer/service/rest/controller/DocumentsRestController.java index c0db7c8..fcf07be 100644 --- a/service/src/main/java/io/mifos/customer/service/rest/controller/DocumentsRestController.java +++ b/service/src/main/java/io/mifos/customer/service/rest/controller/DocumentsRestController.java @@ -138,6 +138,28 @@ public class DocumentsRestController { @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.DOCUMENTS) @RequestMapping( + value = "/{documentidentifier}", + method = RequestMethod.DELETE, + produces = MediaType.APPLICATION_JSON_VALUE, + consumes = MediaType.ALL_VALUE + ) + public @ResponseBody + ResponseEntity<Void> deleteDocument( + @PathVariable("customeridentifier") final String customerIdentifier, + @PathVariable("documentidentifier") final String documentIdentifier) { + throwIfCustomerNotExists(customerIdentifier); + throwIfCustomerDocumentNotExists(customerIdentifier, documentIdentifier); + + throwIfDocumentCompleted(customerIdentifier, documentIdentifier); + + commandGateway.process(new DeleteDocumentCommand(customerIdentifier, documentIdentifier)); + + return ResponseEntity.accepted().build(); + } + + + @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.DOCUMENTS) + @RequestMapping( value = "/{documentidentifier}/completed", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, -- To stop receiving notification emails like this one, please contact my...@apache.org.