From 8d515feb6d59105450ecc120fc568ad3617d1ded Mon Sep 17 00:00:00 2001 From: James Agnew Date: Wed, 21 Oct 2015 11:58:19 -0400 Subject: [PATCH] Fix #242 - Allow compartment and read method to coexist for server --- .../fhir/rest/method/ReadMethodBinding.java | 8 + .../search/IndexNonDeletedInterceptor.java | 2 +- .../util/BigDecimalNumericFieldBridge.java | 2 +- .../rest/server/CompartmentDstu2Test.java | 187 ++++++++++++++++++ src/changes/changes.xml | 5 + vagrant/Vagrantfile | 2 +- 6 files changed, 203 insertions(+), 3 deletions(-) create mode 100644 hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/CompartmentDstu2Test.java diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/ReadMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/ReadMethodBinding.java index 300fcd3f4ceb..bb0ae9a495b1 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/ReadMethodBinding.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/ReadMethodBinding.java @@ -1,5 +1,7 @@ package ca.uhn.fhir.rest.method; +import static org.apache.commons.lang3.StringUtils.isNotBlank; + /* * #%L * HAPI FHIR - Core Library @@ -138,6 +140,9 @@ public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) { return false; } } + if (isNotBlank(theRequest.getCompartmentName())) { + return false; + } if (theRequest.getRequestType() != RequestTypeEnum.GET) { ourLog.trace("Method {} doesn't match because request type is not GET: {}", theRequest.getId(), theRequest.getRequestType()); return false; @@ -198,6 +203,9 @@ public Object invokeClient(String theResponseMimeType, InputStream theResponseRe return resource; case BUNDLE_PROVIDER: return new SimpleBundleProvider(resource); + case BUNDLE_RESOURCE: + case METHOD_OUTCOME: + break; } throw new IllegalStateException("" + getMethodReturnType()); // should not happen diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/IndexNonDeletedInterceptor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/IndexNonDeletedInterceptor.java index e440cf659171..3209b63c377e 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/IndexNonDeletedInterceptor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/IndexNonDeletedInterceptor.java @@ -55,4 +55,4 @@ public IndexingOverride onDelete(ResourceTable entity) { public IndexingOverride onCollectionUpdate(ResourceTable entity) { return IndexingOverride.APPLY_DEFAULT; } -} \ No newline at end of file +} diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/BigDecimalNumericFieldBridge.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/BigDecimalNumericFieldBridge.java index 97bafcc760ec..a5f192c81e20 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/BigDecimalNumericFieldBridge.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/BigDecimalNumericFieldBridge.java @@ -59,4 +59,4 @@ public Object get(final String name, final Document document) { protected void applyToLuceneOptions(LuceneOptions luceneOptions, String name, Number value, Document document) { luceneOptions.addNumericFieldToDocument(name, value, document); } -} \ No newline at end of file +} diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/CompartmentDstu2Test.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/CompartmentDstu2Test.java new file mode 100644 index 000000000000..bcd1312565d3 --- /dev/null +++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/CompartmentDstu2Test.java @@ -0,0 +1,187 @@ +package ca.uhn.fhir.rest.server; + +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.startsWith; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +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.ServletHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.model.api.IResource; +import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt; +import ca.uhn.fhir.model.dstu2.resource.Encounter; +import ca.uhn.fhir.model.dstu2.resource.Observation; +import ca.uhn.fhir.model.dstu2.resource.Patient; +import ca.uhn.fhir.model.primitive.IdDt; +import ca.uhn.fhir.model.primitive.StringDt; +import ca.uhn.fhir.rest.annotation.ConditionalUrlParam; +import ca.uhn.fhir.rest.annotation.Create; +import ca.uhn.fhir.rest.annotation.IdParam; +import ca.uhn.fhir.rest.annotation.OptionalParam; +import ca.uhn.fhir.rest.annotation.Read; +import ca.uhn.fhir.rest.annotation.ResourceParam; +import ca.uhn.fhir.rest.annotation.Search; +import ca.uhn.fhir.rest.api.MethodOutcome; +import ca.uhn.fhir.util.PortUtil; + +/** + * Created by dsotnikov on 2/25/2014. + */ +public class CompartmentDstu2Test { + private static CloseableHttpClient ourClient; + + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(CompartmentDstu2Test.class); + private static int ourPort; + private static Server ourServer; + private static String ourLastMethod; + private static FhirContext ourCtx = FhirContext.forDstu2(); + private static IdDt ourLastId; + + @Before + public void before() { + ourLastMethod = null; + ourLastId = null; + } + + + @Test + public void testReadFirst() throws Exception { + init(new TempPatientResourceProvider()); + + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/123"); + HttpResponse status = ourClient.execute(httpGet); + String responseContent = IOUtils.toString(status.getEntity().getContent()); + IOUtils.closeQuietly(status.getEntity().getContent()); + ourLog.info("Response was:\n{}", responseContent); + assertEquals("read", ourLastMethod); + assertEquals("Patient", ourLastId.getResourceType()); + assertEquals("123", ourLastId.getIdPart()); + assertThat(responseContent, startsWith(" getResourceType() { + return Patient.class; + } + + @Read() + public Patient method1Read(final @IdParam IdDt theId) { + ourLastMethod = "read"; + ourLastId = theId; + Patient patient = new Patient(); + patient.setId(theId); + return patient; + } + + @Search(compartmentName = "Encounter") + public List method2SearchCompartment(final @IdParam IdDt theId) { + ourLastId = theId; + ourLastMethod = "searchEncounterCompartment"; + System.out.println("Encounter compartment search"); + List encounters = new ArrayList(); + Encounter encounter = new Encounter(); + encounter.setId("1"); + encounter.setPatient(new ResourceReferenceDt(theId)); + encounters.add(encounter); + return encounters; + } + + @Search(compartmentName = "Observation") + public List method2SearchCompartment2(final @IdParam IdDt theId) { + ourLastId = theId; + ourLastMethod = "searchObservationCompartment"; + System.out.println("Encounter compartment search"); + List encounters = new ArrayList(); + Observation obs = new Observation(); + obs.setId("1"); + obs.setSubject(new ResourceReferenceDt(theId)); + encounters.add(obs); + return encounters; + } + + } + +} diff --git a/src/changes/changes.xml b/src/changes/changes.xml index e1c585f60d6b..42052504dfc7 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -192,6 +192,11 @@ JPA server maximumn length for a URI search parameter has been reduced from 256 to 255 in order to accomodate MySQL's indexing requirements + + Server failed to respond correctly to compartment search operations + if the same provider also contained a read operation. Thanks to GitHub user + @am202 for reporting! + diff --git a/vagrant/Vagrantfile b/vagrant/Vagrantfile index 7624d3e76401..f635f95e279d 100644 --- a/vagrant/Vagrantfile +++ b/vagrant/Vagrantfile @@ -86,7 +86,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| proxy_port: 80, # ssl_port: 443, authbind: 'yes', - java_options: '-Dfhir.logdir=/var/log/fhir -Dfhir.db.location=/var/fhirdb' + java_options: '-Dfhir.logdir=/var/log/fhir -Dfhir.db.location=/var/fhirdb -Dfhir.db.location.dstu2=/var/fhirdb2 -Dfhir.lucene.location.dstu2=/var/fhirlucene2' }, mysql: { version: '5.6',