From 0c83c1ce44ef8e4ecd1caea9f122f62a8a136b78 Mon Sep 17 00:00:00 2001 From: Jennifer Chan Date: Thu, 2 Jan 2020 14:15:48 -0500 Subject: [PATCH] Changed BaseresourceReturningMethodBinding to accept IBaseBundle as a bundle resource. --- .../BaseResourceReturningMethodBinding.java | 4 +- ...ithVersionlessBundleResourceParamTest.java | 146 ++++++++++++++++++ 2 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/TransactionWithVersionlessBundleResourceParamTest.java diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/BaseResourceReturningMethodBinding.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/BaseResourceReturningMethodBinding.java index 3976e8fadf8..704b72a60fe 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/BaseResourceReturningMethodBinding.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/BaseResourceReturningMethodBinding.java @@ -24,6 +24,7 @@ import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.util.ReflectionUtil; import ca.uhn.fhir.util.UrlUtil; +import org.hl7.fhir.instance.model.api.IBaseBundle; import org.hl7.fhir.instance.model.api.IBaseOperationOutcome; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IPrimitiveType; @@ -81,7 +82,8 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi } } else if (IBaseResource.class.isAssignableFrom(methodReturnType)) { - if (Modifier.isAbstract(methodReturnType.getModifiers()) == false && theContext.getResourceDefinition((Class) methodReturnType).isBundle()) { + + if ((Modifier.isAbstract(methodReturnType.getModifiers()) == false && theContext.getResourceDefinition((Class) methodReturnType).isBundle()) || IBaseBundle.class.isAssignableFrom(methodReturnType)) { myMethodReturnType = MethodReturnTypeEnum.BUNDLE_RESOURCE; } else { myMethodReturnType = MethodReturnTypeEnum.RESOURCE; diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/TransactionWithVersionlessBundleResourceParamTest.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/TransactionWithVersionlessBundleResourceParamTest.java new file mode 100644 index 00000000000..be23b590ac9 --- /dev/null +++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/TransactionWithVersionlessBundleResourceParamTest.java @@ -0,0 +1,146 @@ +package ca.uhn.fhir.rest.server; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.model.dstu2.resource.Bundle; +import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry; +import ca.uhn.fhir.model.dstu2.resource.OperationOutcome; +import ca.uhn.fhir.model.dstu2.resource.Patient; +import ca.uhn.fhir.model.dstu2.valueset.HTTPVerbEnum; +import ca.uhn.fhir.model.primitive.IdDt; +import ca.uhn.fhir.model.primitive.InstantDt; +import ca.uhn.fhir.rest.annotation.Transaction; +import ca.uhn.fhir.rest.annotation.TransactionParam; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.test.utilities.JettyUtil; +import ca.uhn.fhir.util.TestUtil; +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletHolder; +import org.hl7.fhir.instance.model.api.IBaseBundle; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.assertEquals; + +public class TransactionWithVersionlessBundleResourceParamTest { + + + private static CloseableHttpClient ourClient; + + + private static FhirContext ourCtx = FhirContext.forDstu2(); + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(TransactionWithVersionlessBundleResourceParamTest.class); + private static int ourPort; + private static boolean ourReturnOperationOutcome; + private static Server ourServer; + + @Before + public void before() { + ourReturnOperationOutcome = false; + } + + @Test + public void testTransactionWithJsonRequest() throws Exception { + Bundle b = new Bundle(); + InstantDt nowInstant = InstantDt.withCurrentTime(); + + Patient p1 = new Patient(); + p1.addName().addFamily("Family1"); + Entry entry = b.addEntry(); + p1.getId().setValue("1"); + entry.setResource(p1); + + String bundleString = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(b); + ourLog.info(bundleString); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/"); + httpPost.setEntity(new StringEntity(bundleString, ContentType.create(Constants.CT_FHIR_JSON, "UTF-8"))); + HttpResponse status = ourClient.execute(httpPost); + String responseContent = IOUtils.toString(status.getEntity().getContent()); + IOUtils.closeQuietly(status.getEntity().getContent()); + + assertEquals(200, status.getStatusLine().getStatusCode()); + + ourLog.info(responseContent); + + Bundle bundle = ourCtx.newJsonParser().parseResource(Bundle.class, responseContent); + assertEquals(1, bundle.getEntry().size()); + + Entry entry0 = bundle.getEntry().get(0); + assertEquals("Patient/81/_history/91", entry0.getResponse().getLocation()); + + } + + @AfterClass + public static void afterClassClearContext() throws Exception { + JettyUtil.closeServer(ourServer); + TestUtil.clearAllStaticFieldsForUnitTest(); + } + + @BeforeClass + public static void beforeClass() throws Exception { + ourServer = new Server(0); + + DummyProvider patientProvider = new DummyProvider(); + RestfulServer server = new RestfulServer(ourCtx); + server.setProviders(patientProvider); + + org.eclipse.jetty.servlet.ServletContextHandler proxyHandler = new org.eclipse.jetty.servlet.ServletContextHandler(); + proxyHandler.setContextPath("/"); + + ServletHolder handler = new ServletHolder(); + handler.setServlet(server); + proxyHandler.addServlet(handler, "/*"); + + ourServer.setHandler(proxyHandler); + JettyUtil.startServer(ourServer); + ourPort = JettyUtil.getPortForStartedServer(ourServer); + + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(500000, TimeUnit.MILLISECONDS); + HttpClientBuilder builder = HttpClientBuilder.create(); + builder.setConnectionManager(connectionManager); + ourClient = builder.build(); + + } + + + public static class DummyProvider { + + @Transaction + public IBaseBundle transaction(@TransactionParam Bundle theResources) { + Bundle retVal = new Bundle(); + + if (ourReturnOperationOutcome) { + OperationOutcome oo = new OperationOutcome(); + oo.addIssue().setDetails("AAAAA"); + retVal.addEntry().setResource(oo); + } + + int index = 1; + for (Entry nextEntry : theResources.getEntry()) { + String newId = "8" + Integer.toString(index); + if (nextEntry.getRequest().getMethodElement().getValueAsEnum() == HTTPVerbEnum.DELETE) { + newId = new IdDt(nextEntry.getRequest().getUrlElement()).getIdPart(); + } + IdDt newIdDt = (new IdDt("Patient", newId, "9" + Integer.toString(index))); + retVal.addEntry().getResponse().setLocation(newIdDt.getValue()); + index++; + } + + return retVal; + } + + } + +}