From 300179447393f3f76189d02270ec4028a0dae7b7 Mon Sep 17 00:00:00 2001 From: ruhanga <ruhanganathan@gmail.com> Date: Wed, 21 Nov 2018 15:59:18 +0300 Subject: [PATCH] RESTWS-641: Add support for MIME types when posting complexObs value in json request --- .../resource/openmrs1_8/ObsResource1_8.java | 18 ++- .../openmrs2_0/ObsController2_0Test.java | 120 ++++++++++++++++++ .../test/resources/ComplexObsTestImage.png | Bin 0 -> 82 bytes 3 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 omod-2.0/src/test/java/org/openmrs/module/webservices/rest/web/v1_0/controller/openmrs2_0/ObsController2_0Test.java create mode 100644 omod-2.0/src/test/resources/ComplexObsTestImage.png diff --git a/omod-1.8/src/main/java/org/openmrs/module/webservices/rest/web/v1_0/resource/openmrs1_8/ObsResource1_8.java b/omod-1.8/src/main/java/org/openmrs/module/webservices/rest/web/v1_0/resource/openmrs1_8/ObsResource1_8.java index 098f808c7..5619b4576 100644 --- a/omod-1.8/src/main/java/org/openmrs/module/webservices/rest/web/v1_0/resource/openmrs1_8/ObsResource1_8.java +++ b/omod-1.8/src/main/java/org/openmrs/module/webservices/rest/web/v1_0/resource/openmrs1_8/ObsResource1_8.java @@ -388,10 +388,24 @@ public static void setConcept(Obs obs, Object value) { public static void setValue(Obs obs, Object value) throws ParseException, ConversionException, IOException { if (value != null) { if (obs.isComplex()) { - byte[] bytes = DatatypeConverter.parseBase64Binary(value.toString()); + byte[] bytes = null; - ComplexData complexData = new ComplexData(obs.getUuid() + ".raw", new ByteArrayInputStream(bytes)); + String extension = "raw"; + //Try to extract extension from the MIME type if it is provided in value + if (value.toString().startsWith("data:")) { + String dataUri = value.toString(); + String mimeType = (dataUri.split(":", 2)[1]).split(";", 2)[0]; + bytes = DatatypeConverter.parseBase64Binary(dataUri.split(",", 2)[1]); + extension = mimeType.toLowerCase().split("/")[1]; + //extensions with hyphen within them are not supported, instead "raw" is used + extension = extension.contains("-") ? "raw" : extension; + } else { + //no MIME type provided + bytes = DatatypeConverter.parseBase64Binary(value.toString()); + } + ComplexData complexData = new ComplexData(obs.getUuid() + "." + extension, new ByteArrayInputStream(bytes)); obs.setComplexData(complexData); + } else if (obs.getConcept().getDatatype().isCoded()) { // setValueAsString is not implemented for coded obs (in core) diff --git a/omod-2.0/src/test/java/org/openmrs/module/webservices/rest/web/v1_0/controller/openmrs2_0/ObsController2_0Test.java b/omod-2.0/src/test/java/org/openmrs/module/webservices/rest/web/v1_0/controller/openmrs2_0/ObsController2_0Test.java new file mode 100644 index 000000000..1d6156788 --- /dev/null +++ b/omod-2.0/src/test/java/org/openmrs/module/webservices/rest/web/v1_0/controller/openmrs2_0/ObsController2_0Test.java @@ -0,0 +1,120 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public License, + * v. 2.0. If a copy of the MPL was not distributed with this file, You can + * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under + * the terms of the Healthcare Disclaimer located at http://openmrs.org/license. + * + * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS + * graphic logo is a trademark of OpenMRS Inc. + */ +package org.openmrs.module.webservices.rest.web.v1_0.controller.openmrs2_0; + +import org.apache.commons.beanutils.PropertyUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.output.ByteArrayOutputStream; +import org.junit.Assert; +import org.junit.Test; +import org.openmrs.ConceptComplex; +import org.openmrs.ConceptName; +import org.openmrs.GlobalProperty; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.module.webservices.rest.test.Util; +import org.openmrs.module.webservices.rest.web.RestTestConstants1_8; +import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; +import org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceControllerTest; +import org.openmrs.util.OpenmrsConstants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.mock.web.MockMultipartHttpServletRequest; +import javax.imageio.ImageIO; +import javax.xml.bind.DatatypeConverter; +import java.io.InputStream; +import java.util.List; +import java.util.Locale; +import static org.junit.Assert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.equalTo; + +public class ObsController2_0Test extends MainResourceControllerTest { + + @Autowired + ConceptService conceptService; + + @Autowired + AdministrationService adminService; + + /** + * @see org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceControllerTest#getURI() + */ + @Override + public String getURI() { + return "obs"; + } + + @Override + public long getAllCount() { + return Context.getObsService().getObservationCount(null, true); + } + + /** + * @see org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceControllerTest#getUuid() + */ + @Override + public String getUuid() { + return RestTestConstants1_8.OBS_UUID; + } + + /** + * @see org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceControllerTest#shouldGetAll() + */ + @Override + @Test(expected = ResourceDoesNotSupportOperationException.class) + public void shouldGetAll() throws Exception { + super.shouldGetAll(); + } + + @Test + public void shouldSupportMimeTypesWhenPostingBase64Binary() throws Exception { + ConceptComplex conceptComplex = newConceptComplex(); + + InputStream in = getClass().getClassLoader().getResourceAsStream("ComplexObsTestImage.png"); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ImageIO.write(ImageIO.read(in), "png", out); + + String value = DatatypeConverter.printBase64Binary(out.toByteArray()); + String contentType = "image/png"; + + String json = "{\"concept\":\"" + conceptComplex.getUuid() + "\"," + "\"value\":\"" + "data:" + + contentType + ";base64," + value + "\",\"person\":\"5946f880-b197-400b-9caa-a3c661d23041\"," + + "\"obsDatetime\":\"2015-09-07T00:00:00.000+0530\"}"; + + SimpleObject response = deserialize(handle(newPostRequest(getURI(), json))); + + MockHttpServletResponse rawResponse = handle(newGetRequest(getURI() + "/" + response.get("uuid") + "/value")); + + assertThat(contentType, is(equalTo(rawResponse.getContentType()))); + assertThat(out.toByteArray(), is(equalTo(rawResponse.getContentAsByteArray()))); + } + + private ConceptComplex newConceptComplex() { + setupBinaryDataHandler(); + + ConceptComplex conceptComplex = new ConceptComplex(); + conceptComplex.setHandler("ImageHandler"); + conceptComplex.addName(new ConceptName("Xml Test Data", Locale.ENGLISH)); + conceptComplex.setDatatype(conceptService.getConceptDatatypeByName("Complex")); + conceptComplex.setConceptClass(conceptService.getConceptClassByName("Misc")); + conceptService.saveConcept(conceptComplex); + return conceptComplex; + } + + private void setupBinaryDataHandler() { + adminService.saveGlobalProperty(new GlobalProperty("obs.complex_obs_dir", "complexObsDir")); + } +} diff --git a/omod-2.0/src/test/resources/ComplexObsTestImage.png b/omod-2.0/src/test/resources/ComplexObsTestImage.png new file mode 100644 index 0000000000000000000000000000000000000000..6c9a1d9f373b1327bb696de17783997e3a3a5eb4 GIT binary patch literal 82 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga%mF?juK#@*VoWXSfm|+67srr_ bImt;tHX8%8nR(3$AdA7%)z4*}Q$iB}P&yD{ literal 0 HcmV?d00001