Prevent accidental deletion of deeply nested resources in JPA server

This commit is contained in:
James Agnew 2017-11-22 18:17:35 -05:00
parent c668dcd1f8
commit 4042a3a353
6 changed files with 132 additions and 2 deletions

View File

@ -1115,7 +1115,7 @@ public abstract class BaseParser implements IParser {
}
}
return true;
return false;
}
public BaseRuntimeChildDefinition getDef() {

View File

@ -1434,7 +1434,7 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
}
BaseRuntimeElementDefinition<?> childDef = extDef.getChildElementDefinitionByDatatype(value.getClass());
if (childDef == null) {
throw new ConfigurationException("Unable to encode extension, unregognized child element type: " + value.getClass().getCanonicalName());
throw new ConfigurationException("Unable to encode extension, unrecognized child element type: " + value.getClass().getCanonicalName());
}
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, value, childDef, childName, true, false, myParent, false);
managePrimitiveExtension(value, theResDef, theResource, theEventWriter, childDef, childName);

View File

@ -4301,6 +4301,56 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
}
}
@Test
public void testParseAndEncodeExtensionWithValueWithExtension() throws IOException {
String input = "<Patient xmlns=\"http://hl7.org/fhir\">\n" +
" <extension url=\"https://purl.org/elab/fhir/network/StructureDefinition/1/BirthWeight\">\n" +
" <valueDecimal>\n" +
" <extension url=\"http://www.hl7.org/fhir/extension-data-absent-reason.html\">\n" +
" <valueCoding>\n" +
" <system value=\"http://hl7.org/fhir/ValueSet/birthweight\"/>\n" +
" <code value=\"Underweight\"/>\n" +
" <userSelected value=\"false\"/>\n" +
" </valueCoding>\n" +
" </extension>\n" +
" </valueDecimal>\n" +
" </extension>\n" +
" <identifier>\n" +
" <system value=\"https://purl.org/elab/fhir/network/StructureDefinition/1/EuroPrevallStudySubjects\"/>\n" +
" <value value=\"1\"/>\n" +
" </identifier>\n" +
" <gender value=\"female\"/>\n" +
"</Patient>";
HttpPost post = new HttpPost(ourServerBase + "/Patient");
post.setEntity(new StringEntity(input, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
CloseableHttpResponse response = ourHttpClient.execute(post);
IdType id;
try {
assertEquals(201, response.getStatusLine().getStatusCode());
String newIdString = response.getFirstHeader(Constants.HEADER_LOCATION_LC).getValue();
assertThat(newIdString, startsWith(ourServerBase + "/Patient/"));
id = new IdType(newIdString);
} finally {
response.close();
}
HttpGet get = new HttpGet(ourServerBase + "/Patient/" + id.getIdPart() + "?_pretty=true");
response = ourHttpClient.execute(get);
try {
String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
ourLog.info(resp);
assertEquals(200, response.getStatusLine().getStatusCode());
assertThat(resp, containsString("Underweight"));
} finally {
IOUtils.closeQuietly(response.getEntity().getContent());
response.close();
}
}
@Test
public void testValueSetExpandOperation() throws IOException {
CodeSystem cs = myFhirCtx.newXmlParser().parseResource(CodeSystem.class, new InputStreamReader(ResourceProviderR4Test.class.getResourceAsStream("/extensional-case-3-cs.xml")));

View File

@ -2,6 +2,7 @@ package ca.uhn.fhir.parser;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.util.TestUtil;
import com.google.common.collect.Sets;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Patient;
import org.junit.AfterClass;
@ -110,6 +111,51 @@ public class JsonParserR4Test {
return b;
}
@Test
public void testParseAndEncodeExtensionWithValueWithExtension() {
String input = "{\n" +
" \"resourceType\": \"Patient\",\n" +
" \"extension\": [\n" +
" {\n" +
" \"url\": \"https://purl.org/elab/fhir/network/StructureDefinition/1/BirthWeight\",\n" +
" \"_valueDecimal\": {\n" +
" \"extension\": [\n" +
" {\n" +
" \"url\": \"http://www.hl7.org/fhir/extension-data-absent-reason.html\",\n" +
" \"valueCoding\": {\n" +
" \"system\": \"http://hl7.org/fhir/ValueSet/birthweight\",\n" +
" \"code\": \"Underweight\",\n" +
" \"userSelected\": false\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
" }\n" +
" ],\n" +
" \"identifier\": [\n" +
" {\n" +
" \"system\": \"https://purl.org/elab/fhir/network/StructureDefinition/1/EuroPrevallStudySubjects\",\n" +
" \"value\": \"1\"\n" +
" }\n" +
" ],\n" +
" \"gender\": \"female\"\n" +
"}";
IParser jsonParser = ourCtx.newJsonParser();
IParser xmlParser = ourCtx.newXmlParser();
jsonParser.setDontEncodeElements(Sets.newHashSet("id", "meta"));
xmlParser.setDontEncodeElements(Sets.newHashSet("id", "meta"));
Patient parsed = jsonParser.parseResource(Patient.class, input);
ourLog.info(jsonParser.setPrettyPrint(true).encodeResourceToString(parsed));
assertThat(xmlParser.encodeResourceToString(parsed), containsString("Underweight"));
assertThat(jsonParser.encodeResourceToString(parsed), containsString("Underweight"));
}
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();

View File

@ -110,6 +110,36 @@ public class XmlParserR4Test {
return b;
}
@Test
public void testParseAndEncodeExtensionWithValueWithExtension() {
String input = "<Patient xmlns=\"http://hl7.org/fhir\">\n" +
" <extension url=\"https://purl.org/elab/fhir/network/StructureDefinition/1/BirthWeight\">\n" +
" <valueDecimal>\n" +
" <extension url=\"http://www.hl7.org/fhir/extension-data-absent-reason.html\">\n" +
" <valueCoding>\n" +
" <system value=\"http://hl7.org/fhir/ValueSet/birthweight\"/>\n" +
" <code value=\"Underweight\"/>\n" +
" <userSelected value=\"false\"/>\n" +
" </valueCoding>\n" +
" </extension>\n" +
" </valueDecimal>\n" +
" </extension>\n" +
" <identifier>\n" +
" <system value=\"https://purl.org/elab/fhir/network/StructureDefinition/1/EuroPrevallStudySubjects\"/>\n" +
" <value value=\"1\"/>\n" +
" </identifier>\n" +
" <gender value=\"female\"/>\n" +
"</Patient>";
Patient parsed = ourCtx.newXmlParser().parseResource(Patient.class, input);
ourLog.info(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(parsed));
assertThat(ourCtx.newXmlParser().encodeResourceToString(parsed), containsString("Underweight"));
assertThat(ourCtx.newJsonParser().encodeResourceToString(parsed), containsString("Underweight"));
}
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();

View File

@ -212,6 +212,10 @@
client requests.
Thanks to Clayton Bodendein for the pull request!
</action>
<action type="fix">
An issue was fixed in JPA server where extensions on primitives which
are nestedt several layers deep are lost when resources are retrieved
</action>
</release>
<release version="3.0.0" date="2017-09-27">
<action type="add">