Contained resource handling improved

This commit is contained in:
James Agnew 2014-07-23 17:02:54 -04:00
parent 4cd3bdf441
commit 318dcfcaaf
7 changed files with 135 additions and 13 deletions

View File

@ -28,4 +28,4 @@ public class DateOrListParam extends BaseOrListParam<DateParam> {
return new DateParam();
}
}
}

View File

@ -28,4 +28,4 @@ public class ReferenceOrListParam extends BaseOrListParam<ReferenceParam> {
return new ReferenceParam();
}
}
}

View File

@ -28,4 +28,4 @@ public class StringOrListParam extends BaseOrListParam<StringParam> {
return new StringParam();
}
}
}

View File

@ -48,4 +48,4 @@ public class TokenOrListParam extends BaseOrListParam<TokenParam> {
add(new TokenParam(theCodingDt));
}
}
}

View File

@ -20,7 +20,7 @@ package ca.uhn.fhir.rest.server;
* #L%
*/
import static org.apache.commons.lang3.StringUtils.*;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.IOException;
import java.io.OutputStreamWriter;
@ -29,12 +29,15 @@ import java.io.Writer;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.UUID;
import java.util.zip.GZIPOutputStream;
@ -56,6 +59,7 @@ import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.Tag;
import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dstu.resource.Binary;
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
import ca.uhn.fhir.model.dstu.resource.OperationOutcome.Issue;
@ -804,6 +808,8 @@ public class RestfulServer extends HttpServlet {
bundle.getLinkBase().setValue(theServerBase);
bundle.getLinkSelf().setValue(theCompleteUrl);
List<IResource> addedResources = new ArrayList<IResource>();
Set<IdDt> addedResourceIds = new HashSet<IdDt>();
for (IResource next : theResult) {
if (theContext.getNarrativeGenerator() != null) {
@ -816,9 +822,35 @@ public class RestfulServer extends HttpServlet {
ourLog.trace("No narrative generator specified");
}
List<ResourceReferenceDt> references = theContext.newTerser().getAllPopulatedChildElementsOfType(next, ResourceReferenceDt.class);
for (ResourceReferenceDt nextRef : references) {
IResource nextRes = nextRef.getResource();
if (nextRes != null) {
if (nextRes.getId().hasIdPart()) {
IdDt id = nextRes.getId().toVersionless();
if (id.hasResourceType()==false) {
String resName = theContext.getResourceDefinition(nextRes).getName();
id = id.withResourceType(resName);
}
if (!addedResourceIds.contains(id)) {
addedResourceIds.add(id);
addedResources.add(nextRes);
}
nextRef.setResource(null);
nextRef.setReference(id);
}
}
}
bundle.addResource(next, theContext, theServerBase);
}
for (IResource next : addedResources) {
bundle.addResource(next, theContext, theServerBase);
}
bundle.getTotalResults().setValue(theTotalResults);
return bundle;
}

View File

@ -391,6 +391,27 @@ public class XmlParserTest {
assertThat(bundleString, not(containsString("at:by")));
}
@Test
public void testEncodeContainedAndIncludedResources() {
DiagnosticReport rpt = new DiagnosticReport();
rpt.getName().setText("Report");
Specimen spm = new Specimen();
spm.addIdentifier().setLabel("Report1ContainedSpecimen1");
rpt.addSpecimen().setResource(spm);
IParser p = ourCtx.newXmlParser().setPrettyPrint(true);
String str = p.encodeResourceToString(rpt);
ourLog.info(str);
}
@Test
public void testEncodeContainedResources() {

View File

@ -1,8 +1,9 @@
package ca.uhn.fhir.rest.server;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@ -23,8 +24,10 @@ import org.junit.Test;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.PathSpecification;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.dstu.resource.Organization;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.rest.annotation.IncludeParam;
import ca.uhn.fhir.rest.annotation.RequiredParam;
@ -45,7 +48,8 @@ public class IncludeTest {
public void testNoIncludes() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?name=Hello");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent()); IOUtils.closeQuietly(status.getEntity().getContent());
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
Bundle bundle = new FhirContext().newXmlParser().parseBundle(responseContent);
@ -60,7 +64,8 @@ public class IncludeTest {
public void testOneInclude() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?name=Hello&_include=foo");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent()); IOUtils.closeQuietly(status.getEntity().getContent());
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
Bundle bundle = new FhirContext().newXmlParser().parseBundle(responseContent);
@ -72,11 +77,38 @@ public class IncludeTest {
assertEquals("foo", p.getName().get(0).getFamilyFirstRep().getValue());
}
@Test
public void testIIncludedResourcesNonContained() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_query=normalInclude&_pretty=true");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
Bundle bundle = new FhirContext().newXmlParser().parseBundle(responseContent);
ourLog.info(responseContent);
assertEquals(3, bundle.size());
assertEquals(new IdDt("Patient/p1"), bundle.toListOfResources().get(0).getId().toUnqualifiedVersionless());
assertEquals(new IdDt("Patient/p2"), bundle.toListOfResources().get(1).getId().toUnqualifiedVersionless());
assertEquals(new IdDt("Organization/o1"), bundle.toListOfResources().get(2).getId().toUnqualifiedVersionless());
Patient p1 = (Patient) bundle.toListOfResources().get(0);
assertEquals(0,p1.getContained().getContainedResources().size());
Patient p2 = (Patient) bundle.toListOfResources().get(1);
assertEquals(0,p2.getContained().getContainedResources().size());
}
@Test
public void testTwoInclude() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?name=Hello&_include=foo&_include=bar");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent()); IOUtils.closeQuietly(status.getEntity().getContent());
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
Bundle bundle = new FhirContext().newXmlParser().parseBundle(responseContent);
@ -128,17 +160,54 @@ public class IncludeTest {
*/
public static class DummyPatientResourceProvider implements IResourceProvider {
@Search(queryName = "normalInclude")
public List<Patient> normalInclude() {
Organization o1 = new Organization();
o1.getName().setValue("o1");
o1.setId("o1");
Patient p1 = new Patient();
p1.setId("p1");
p1.addIdentifier().setLabel("p1");
p1.getManagingOrganization().setResource(o1);
Patient p2 = new Patient();
p2.setId("p2");
p2.addIdentifier().setLabel("p2");
p2.getManagingOrganization().setResource(o1);
return Arrays.asList(p1, p2);
}
@Search(queryName = "containedInclude")
public List<Patient> containedInclude() {
Organization o1 = new Organization();
o1.getName().setValue("o1");
Patient p1 = new Patient();
p1.setId("p1");
p1.addIdentifier().setLabel("p1");
p1.getManagingOrganization().setResource(o1);
Patient p2 = new Patient();
p2.setId("p2");
p2.addIdentifier().setLabel("p2");
p2.getManagingOrganization().setResource(o1);
return Arrays.asList(p1, p2);
}
@Search
public List<Patient> findPatient(@RequiredParam(name = Patient.SP_NAME) StringDt theName, @IncludeParam(allow = { "foo", "bar" }) Set<PathSpecification> theIncludes) {
public List<Patient> findPatient(@RequiredParam(name = Patient.SP_NAME) StringDt theName, @IncludeParam(allow = { "foo", "bar" }) Set<Include> theIncludes) {
ArrayList<Patient> retVal = new ArrayList<Patient>();
Patient p = new Patient();
p.addIdentifier("foo", "bar");
p.setId(theName.getValue());
if (theIncludes != null) {
for (PathSpecification next : theIncludes) {
for (Include next : theIncludes) {
p.addName().addFamily().setValue(next.getValue());
}
}