From 3a8830a9f4b905e3fa69a811b27cef24b343fd14 Mon Sep 17 00:00:00 2001 From: chine zoheir Date: Wed, 7 Mar 2018 08:43:52 +0100 Subject: [PATCH] ATT-4: Files uploads handled via REST through AttachmentResource --- .../attachments/AttachmentsConstants.java | 6 +- .../rest/AttachmentResource1_10.java | 64 ++++++++++++- .../rest/AttachmentController1_10Test.java | 91 +++++++++++++++++-- omod-2.0/pom.xml | 4 +- .../rest/AttachmentController2_0Test.java | 8 +- pom.xml | 4 +- 6 files changed, 157 insertions(+), 20 deletions(-) diff --git a/api/src/main/java/org/openmrs/module/attachments/AttachmentsConstants.java b/api/src/main/java/org/openmrs/module/attachments/AttachmentsConstants.java index fa7d6a5f..e666a60b 100644 --- a/api/src/main/java/org/openmrs/module/attachments/AttachmentsConstants.java +++ b/api/src/main/java/org/openmrs/module/attachments/AttachmentsConstants.java @@ -28,11 +28,11 @@ public static enum ContentFamily { public static final String MODULE_BASE_URL = "/" + MODULE_ARTIFACT_ID; - public static final String UPLOAD_ATTACHMENT_URL = MODULE_BASE_URL + "/upload"; + public static final String ATTACHMENT_URI = "attachment"; - public static final String DOWNLOAD_ATTACHMENT_URL = MODULE_BASE_URL + "/download"; + public static final String UPLOAD_ATTACHMENT_URL = "/rest/v1/" + ATTACHMENT_URI; - public static final String ATTACHMENT_URI = "attachment"; + public static final String DOWNLOAD_ATTACHMENT_URL = MODULE_BASE_URL + "/download"; /* * Spring components qualifiers diff --git a/omod-1.10/src/main/java/org/openmrs/module/attachments/rest/AttachmentResource1_10.java b/omod-1.10/src/main/java/org/openmrs/module/attachments/rest/AttachmentResource1_10.java index 58cbc986..e84c6918 100644 --- a/omod-1.10/src/main/java/org/openmrs/module/attachments/rest/AttachmentResource1_10.java +++ b/omod-1.10/src/main/java/org/openmrs/module/attachments/rest/AttachmentResource1_10.java @@ -1,26 +1,48 @@ package org.openmrs.module.attachments.rest; +import org.apache.commons.lang.StringUtils; +import org.openmrs.Patient; import org.openmrs.Encounter; import org.openmrs.Obs; +import org.openmrs.Provider; +import org.openmrs.Visit; import org.openmrs.api.EncounterService; import org.openmrs.api.context.Context; import org.openmrs.module.attachments.AttachmentsConstants; +import org.openmrs.module.attachments.AttachmentsContext; +import org.openmrs.module.attachments.ComplexObsSaver; import org.openmrs.module.attachments.obs.Attachment; +import org.openmrs.module.attachments.obs.ValueComplex; +import org.openmrs.module.webservices.rest.web.ConversionUtil; import org.openmrs.module.webservices.rest.web.RequestContext; import org.openmrs.module.webservices.rest.web.RestConstants; import org.openmrs.module.webservices.rest.web.annotation.Resource; +import org.openmrs.module.webservices.rest.web.representation.CustomRepresentation; import org.openmrs.module.webservices.rest.web.representation.Representation; +import org.openmrs.module.webservices.rest.web.resource.api.Uploadable; import org.openmrs.module.webservices.rest.web.resource.impl.DataDelegatingCrudResource; import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; import org.openmrs.module.webservices.rest.web.response.GenericRestException; +import org.openmrs.module.webservices.rest.web.response.IllegalRequestException; import org.openmrs.module.webservices.rest.web.response.ResponseException; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; + +import static org.openmrs.module.attachments.AttachmentsContext.getContentFamily; @Resource(name = RestConstants.VERSION_1 + "/attachment", supportedClass = Attachment.class, supportedOpenmrsVersions = { "1.10.*", "1.11.*", "1.12.*" }) -public class AttachmentResource1_10 extends DataDelegatingCrudResource { +public class AttachmentResource1_10 extends DataDelegatingCrudResource implements Uploadable { protected static final String REASON = "REST web service"; + ComplexObsSaver obsSaver = Context.getRegisteredComponent(AttachmentsConstants.COMPONENT_COMPLEXOBS_SAVER, + ComplexObsSaver.class); + + AttachmentsContext attachmentsContext = Context.getRegisteredComponent(AttachmentsConstants.COMPONENT_ATT_CONTEXT, + AttachmentsContext.class); + @Override public Attachment newDelegate() { return new Attachment(); @@ -57,6 +79,46 @@ public void purge(Attachment delegate, RequestContext context) throws ResponseEx voidEncounterIfEmpty(Context.getEncounterService(), encounterUuid); } + @Override + public Object upload(MultipartFile file, RequestContext context) throws ResponseException, IOException { + + // Prepare Parameters + Patient patient = Context.getPatientService().getPatientByUuid(context.getParameter("patient")); + Visit visit = Context.getVisitService().getVisitByUuid(context.getParameter("visit")); + Provider provider = Context.getProviderService().getProviderByUuid(context.getParameter("provider")); + String fileCaption = context.getParameter("fileCaption"); + String instructions = context.getParameter("instructions"); + + // Verify Parameters + if (patient == null) { + throw new IllegalRequestException("A patient parameter must be provided when uploading an attachment."); + } + + if (StringUtils.isEmpty(instructions)) + instructions = ValueComplex.INSTRUCTIONS_DEFAULT; + + Encounter encounter = null; + if (visit != null) { + encounter = attachmentsContext.getAttachmentEncounter(patient, visit, provider); + } + + // Save Obs + Obs obs; + switch (getContentFamily(file.getContentType())) { + case IMAGE: + obs = obsSaver.saveImageAttachment(visit, patient, encounter, fileCaption, file, instructions); + break; + + case OTHER: + default: + obs = obsSaver.saveOtherAttachment(visit, patient, encounter, fileCaption, file, instructions); + break; + } + + return ConversionUtil.convertToRepresentation(obs, + new CustomRepresentation(AttachmentsConstants.REPRESENTATION_OBS)); + } + @Override public DelegatingResourceDescription getCreatableProperties() { DelegatingResourceDescription description = new DelegatingResourceDescription(); diff --git a/omod-1.10/src/test/java/org/openmrs/module/attachments/rest/AttachmentController1_10Test.java b/omod-1.10/src/test/java/org/openmrs/module/attachments/rest/AttachmentController1_10Test.java index f1c8c39e..82e52d10 100644 --- a/omod-1.10/src/test/java/org/openmrs/module/attachments/rest/AttachmentController1_10Test.java +++ b/omod-1.10/src/test/java/org/openmrs/module/attachments/rest/AttachmentController1_10Test.java @@ -1,22 +1,29 @@ package org.openmrs.module.attachments.rest; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; - import org.apache.commons.beanutils.PropertyUtils; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.openmrs.Obs; +import org.openmrs.Patient; +import org.openmrs.Visit; import org.openmrs.api.ObsService; +import org.openmrs.api.context.Context; import org.openmrs.module.attachments.AttachmentsConstants; +import org.openmrs.module.attachments.AttachmentsContext; import org.openmrs.module.attachments.obs.TestHelper; +import org.openmrs.module.webservices.rest.SimpleObject; import org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceControllerTest; +import org.openmrs.obs.ComplexData; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.mock.web.MockMultipartHttpServletRequest; + +import java.io.File; +import java.io.IOException; +import java.util.Random; + +import static org.junit.Assert.*; public class AttachmentController1_10Test extends MainResourceControllerTest { @@ -26,11 +33,17 @@ public class AttachmentController1_10Test extends MainResourceControllerTest { @Autowired protected TestHelper testHelper; + @Autowired + private AttachmentsContext attachmentsContext; + + private byte[] randomData = new byte[20]; + private Obs obs; @Before public void setup() throws IOException { obs = testHelper.getTestComplexObs(); + new Random().nextBytes(randomData); } @Override @@ -159,4 +172,66 @@ public void purgeAttachment_shouldPurgeObsWithoutAssociatedEncounter() throws Ex // Verify assertNull(obsService.getObsByUuid(obs.getUuid())); } + + @Test + public void postAttachment_shouldUploadFile() throws Exception { + + String fileCaption = "Test file caption"; + + { + // Setup + String fileName = "testFile1.dat"; + Patient patient = Context.getPatientService().getPatient(2); + Visit visit = Context.getVisitService().getVisit(1); + + MockMultipartHttpServletRequest request = newUploadRequest(getURI()); + MockMultipartFile file = new MockMultipartFile("file", fileName, "application/octet-stream", randomData); + + request.addFile(file); + request.addParameter("patient", patient.getUuid()); + request.addParameter("visit", visit.getUuid()); + request.addParameter("fileCaption", fileCaption); + + // Reply + SimpleObject response = deserialize(handle(request)); + + Obs obs = Context.getObsService().getObsByUuid((String) response.get("uuid")); + Obs complexObs = Context.getObsService().getComplexObs(obs.getObsId(), null); + ComplexData complexData = complexObs.getComplexData(); + + // Verify + Assert.assertEquals(obs.getComment(), fileCaption); + Assert.assertEquals(complexData.getTitle(), fileName); + Assert.assertArrayEquals(randomData, (byte[]) complexData.getData()); + Assert.assertNotNull(obs.getEncounter()); + Assert.assertEquals(obs.getEncounter().getEncounterType(), attachmentsContext.getEncounterType()); + } + + // File upload should not require visit + { + // Setup + String fileName = "testFile2.dat"; + Patient patient = Context.getPatientService().getPatient(2); + + MockMultipartHttpServletRequest request = newUploadRequest(getURI()); + MockMultipartFile file = new MockMultipartFile("file", fileName, "application/octet-stream", randomData); + + request.addFile(file); + request.addParameter("patient", patient.getUuid()); + request.addParameter("fileCaption", fileCaption); + + // Reply + SimpleObject response = deserialize(handle(request)); + + Obs obs = Context.getObsService().getObsByUuid((String) response.get("uuid")); + Obs complexObs = Context.getObsService().getComplexObs(obs.getObsId(), null); + ComplexData complexData = complexObs.getComplexData(); + + // Verify + Assert.assertEquals(obs.getComment(), fileCaption); + Assert.assertEquals(complexData.getTitle(), fileName); + Assert.assertArrayEquals(randomData, (byte[]) complexData.getData()); + Assert.assertNull(obs.getEncounter()); + } + } } diff --git a/omod-2.0/pom.xml b/omod-2.0/pom.xml index ce1c637f..3cb242a6 100644 --- a/omod-2.0/pom.xml +++ b/omod-2.0/pom.xml @@ -17,7 +17,7 @@ 2.0.0 1.19 - 2.16 + 2.17 0.10.4 0.2.12 @@ -225,4 +225,4 @@ - \ No newline at end of file + diff --git a/omod-2.0/src/test/java/org/openmrs/module/attachments/rest/AttachmentController2_0Test.java b/omod-2.0/src/test/java/org/openmrs/module/attachments/rest/AttachmentController2_0Test.java index 8c3a475d..920bf886 100644 --- a/omod-2.0/src/test/java/org/openmrs/module/attachments/rest/AttachmentController2_0Test.java +++ b/omod-2.0/src/test/java/org/openmrs/module/attachments/rest/AttachmentController2_0Test.java @@ -1,9 +1,5 @@ package org.openmrs.module.attachments.rest; -import static org.junit.Assert.assertEquals; - -import java.io.IOException; - import org.apache.commons.beanutils.PropertyUtils; import org.junit.Before; import org.junit.Test; @@ -14,6 +10,10 @@ import org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceControllerTest; import org.springframework.beans.factory.annotation.Autowired; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; + public class AttachmentController2_0Test extends MainResourceControllerTest { @Autowired diff --git a/pom.xml b/pom.xml index c4e8b301..41f8ed6a 100644 --- a/pom.xml +++ b/pom.xml @@ -44,7 +44,7 @@ 2.2.1 3.3.1 1.4 - 2.12 + 2.17 1.12 0.9.2.1 1.1 @@ -204,4 +204,4 @@ - \ No newline at end of file +