Fix #33 - Server was incorrectly returning contained resources as
top-level resources
This commit is contained in:
parent
b22bcaec32
commit
287162af91
|
@ -104,6 +104,11 @@
|
||||||
Documentation on contained resources contained a typo and did not actually produce contained resources. Thanks
|
Documentation on contained resources contained a typo and did not actually produce contained resources. Thanks
|
||||||
to David Hay of Orion Health for reporting!
|
to David Hay of Orion Health for reporting!
|
||||||
</action>
|
</action>
|
||||||
|
<action type="fix" issue="33">
|
||||||
|
Server was incorrectly including contained resources being returned as both contained resources, and as
|
||||||
|
top-level resources in the returned bundle for search operations.
|
||||||
|
Thanks to Bill de Beaubien for reporting!
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="0.6" date="2014-Sep-08" description="This release brings a number of new features and bug fixes!">
|
<release version="0.6" date="2014-Sep-08" description="This release brings a number of new features and bug fixes!">
|
||||||
<!--
|
<!--
|
||||||
|
|
|
@ -411,6 +411,8 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
theEventWriter.writeStartArray(childName);
|
theEventWriter.writeStartArray(childName);
|
||||||
inArray = true;
|
inArray = true;
|
||||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null, theIsSubElementWithinResource);
|
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null, theIsSubElementWithinResource);
|
||||||
|
} else if (nextChild instanceof RuntimeChildNarrativeDefinition && theIsSubElementWithinResource) {
|
||||||
|
// suppress narratives from contained resources
|
||||||
} else {
|
} else {
|
||||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, childName, theIsSubElementWithinResource);
|
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, childName, theIsSubElementWithinResource);
|
||||||
}
|
}
|
||||||
|
|
|
@ -549,6 +549,8 @@ public class XmlParser extends BaseParser implements IParser {
|
||||||
theEventWriter.writeAttribute("url", extensionUrl);
|
theEventWriter.writeAttribute("url", extensionUrl);
|
||||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childName, childDef, null, theIncludedResource);
|
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childName, childDef, null, theIncludedResource);
|
||||||
theEventWriter.writeEndElement();
|
theEventWriter.writeEndElement();
|
||||||
|
} else if (nextChild instanceof RuntimeChildNarrativeDefinition && theIncludedResource) {
|
||||||
|
// suppress narratives from contained resources
|
||||||
} else {
|
} else {
|
||||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childName, childDef, extensionUrl, theIncludedResource);
|
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childName, childDef, extensionUrl, theIncludedResource);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1035,6 +1035,13 @@ public class RestfulServer extends HttpServlet {
|
||||||
Set<IdDt> addedResourceIds = new HashSet<IdDt>();
|
Set<IdDt> addedResourceIds = new HashSet<IdDt>();
|
||||||
for (IResource next : theResult) {
|
for (IResource next : theResult) {
|
||||||
|
|
||||||
|
Set<String> containedIds = new HashSet<String>();
|
||||||
|
for (IResource nextContained : next.getContained().getContainedResources()) {
|
||||||
|
if (nextContained.getId().isEmpty()==false) {
|
||||||
|
containedIds.add(nextContained.getId().getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (theContext.getNarrativeGenerator() != null) {
|
if (theContext.getNarrativeGenerator() != null) {
|
||||||
String title = theContext.getNarrativeGenerator().generateTitle(next);
|
String title = theContext.getNarrativeGenerator().generateTitle(next);
|
||||||
ourLog.trace("Narrative generator created title: {}", title);
|
ourLog.trace("Narrative generator created title: {}", title);
|
||||||
|
@ -1053,6 +1060,11 @@ public class RestfulServer extends HttpServlet {
|
||||||
IResource nextRes = nextRef.getResource();
|
IResource nextRes = nextRef.getResource();
|
||||||
if (nextRes != null) {
|
if (nextRes != null) {
|
||||||
if (nextRes.getId().hasIdPart()) {
|
if (nextRes.getId().hasIdPart()) {
|
||||||
|
if (containedIds.contains(nextRes.getId().getValue())) {
|
||||||
|
// Don't add contained IDs as top level resources
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
IdDt id = nextRes.getId().toVersionless();
|
IdDt id = nextRes.getId().toVersionless();
|
||||||
if (id.hasResourceType() == false) {
|
if (id.hasResourceType() == false) {
|
||||||
String resName = theContext.getResourceDefinition(nextRes).getName();
|
String resName = theContext.getResourceDefinition(nextRes).getName();
|
||||||
|
|
|
@ -491,6 +491,29 @@ public class JsonParserTest {
|
||||||
assertThat(encoded, containsString("reference\":\"#1\""));
|
assertThat(encoded, containsString("reference\":\"#1\""));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEncodeContainedWithNarrativeIsSuppresed() {
|
||||||
|
IParser parser = ourCtx.newJsonParser().setPrettyPrint(true);
|
||||||
|
|
||||||
|
// Create an organization, note that the organization does not have an ID
|
||||||
|
Organization org = new Organization();
|
||||||
|
org.getName().setValue("Contained Test Organization");
|
||||||
|
org.getText().setDiv("<div>FOOBAR</div>");
|
||||||
|
|
||||||
|
// Create a patient
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.setId("Patient/1333");
|
||||||
|
patient.addIdentifier("urn:mrns", "253345");
|
||||||
|
patient.getText().setDiv("<div>BARFOO</div>");
|
||||||
|
patient.getManagingOrganization().setResource(org);
|
||||||
|
|
||||||
|
String encoded = parser.encodeResourceToString(patient);
|
||||||
|
ourLog.info(encoded);
|
||||||
|
assertThat(encoded, not(containsString("FOOBAR")));
|
||||||
|
assertThat(encoded, (containsString("BARFOO")));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEncodeContained() {
|
public void testEncodeContained() {
|
||||||
IParser xmlParser = ourCtx.newJsonParser().setPrettyPrint(true);
|
IParser xmlParser = ourCtx.newJsonParser().setPrettyPrint(true);
|
||||||
|
@ -603,7 +626,7 @@ public class JsonParserTest {
|
||||||
|
|
||||||
DiagnosticReport rpt = new DiagnosticReport();
|
DiagnosticReport rpt = new DiagnosticReport();
|
||||||
Specimen spm = new Specimen();
|
Specimen spm = new Specimen();
|
||||||
spm.getText().setDiv("AAA");
|
rpt.getText().setDiv("AAA");
|
||||||
rpt.addSpecimen().setResource(spm);
|
rpt.addSpecimen().setResource(spm);
|
||||||
|
|
||||||
IParser p = new FhirContext(DiagnosticReport.class).newJsonParser().setPrettyPrint(true);
|
IParser p = new FhirContext(DiagnosticReport.class).newJsonParser().setPrettyPrint(true);
|
||||||
|
|
|
@ -1,9 +1,18 @@
|
||||||
package ca.uhn.fhir.parser;
|
package ca.uhn.fhir.parser;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.junit.Assert.*;
|
import static org.hamcrest.Matchers.not;
|
||||||
import static org.mockito.Matchers.*;
|
import static org.hamcrest.Matchers.stringContainsInOrder;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Matchers.eq;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
@ -12,7 +21,6 @@ import java.io.StringReader;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@ -115,6 +123,29 @@ public class XmlParserTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEncodeContainedWithNarrativeIsSuppresed() {
|
||||||
|
IParser parser = ourCtx.newXmlParser().setPrettyPrint(true);
|
||||||
|
|
||||||
|
// Create an organization, note that the organization does not have an ID
|
||||||
|
Organization org = new Organization();
|
||||||
|
org.getName().setValue("Contained Test Organization");
|
||||||
|
org.getText().setDiv("<div>FOOBAR</div>");
|
||||||
|
|
||||||
|
// Create a patient
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.setId("Patient/1333");
|
||||||
|
patient.addIdentifier("urn:mrns", "253345");
|
||||||
|
patient.getText().setDiv("<div>BARFOO</div>");
|
||||||
|
patient.getManagingOrganization().setResource(org);
|
||||||
|
|
||||||
|
String encoded = parser.encodeResourceToString(patient);
|
||||||
|
ourLog.info(encoded);
|
||||||
|
assertThat(encoded, not(containsString("FOOBAR")));
|
||||||
|
assertThat(encoded, (containsString("BARFOO")));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEncodeContained() {
|
public void testEncodeContained() {
|
||||||
|
@ -388,7 +419,8 @@ public class XmlParserTest {
|
||||||
|
|
||||||
DiagnosticReport rpt = new DiagnosticReport();
|
DiagnosticReport rpt = new DiagnosticReport();
|
||||||
Specimen spm = new Specimen();
|
Specimen spm = new Specimen();
|
||||||
spm.getText().setDiv("AAA");
|
spm.addIdentifier("urn", "123");
|
||||||
|
rpt.getText().setDiv("AAA");
|
||||||
rpt.addSpecimen().setResource(spm);
|
rpt.addSpecimen().setResource(spm);
|
||||||
|
|
||||||
IParser p = ourCtx.newXmlParser().setPrettyPrint(true);
|
IParser p = ourCtx.newXmlParser().setPrettyPrint(true);
|
||||||
|
|
|
@ -174,6 +174,28 @@ public class CompleteResourceProviderTest {
|
||||||
assertThat(actual.getText().getDiv().getValueAsString(), containsString("<td>Identifier</td><td>testSearchByResourceChain01</td>"));
|
assertThat(actual.getText().getDiv().getValueAsString(), containsString("<td>Identifier</td><td>testSearchByResourceChain01</td>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSaveAndRetrieveWithContained() {
|
||||||
|
Patient p1 = new Patient();
|
||||||
|
p1.addIdentifier().setSystem("urn:system").setValue("testSaveAndRetrieveWithContained01");
|
||||||
|
|
||||||
|
Organization o1 = new Organization();
|
||||||
|
o1.addIdentifier().setSystem("urn:system").setValue("testSaveAndRetrieveWithContained02");
|
||||||
|
|
||||||
|
p1.getManagingOrganization().setResource(o1);
|
||||||
|
|
||||||
|
IdDt newId = ourClient.create().resource(p1).execute().getId();
|
||||||
|
|
||||||
|
Patient actual = ourClient.read(Patient.class, newId);
|
||||||
|
assertEquals(1, actual.getContained().getContainedResources().size());
|
||||||
|
assertThat(actual.getText().getDiv().getValueAsString(), containsString("<td>Identifier</td><td>testSaveAndRetrieveWithContained01</td>"));
|
||||||
|
|
||||||
|
Bundle b = ourClient.search().forResource("Patient").where(Patient.IDENTIFIER.exactly().systemAndCode("urn:system","testSaveAndRetrieveWithContained01")).execute();
|
||||||
|
assertEquals(1, b.size());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchByIdentifier() {
|
public void testSearchByIdentifier() {
|
||||||
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSearchByIdentifier01");
|
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSearchByIdentifier01");
|
||||||
|
|
Loading…
Reference in New Issue