From 4d1ab2734f937ec60a58f7439f772b3c46740046 Mon Sep 17 00:00:00 2001 From: James Date: Mon, 2 Oct 2017 19:21:52 -0400 Subject: [PATCH] Use correct parameter name for expand operation --- .../BaseJpaResourceProviderValueSetDstu3.java | 96 +++-- .../r4/BaseJpaResourceProviderValueSetR4.java | 86 ++-- .../ResourceProviderDstu3ValueSetTest.java | 381 ++++++++++-------- .../r4/ResourceProviderR4ValueSetTest.java | 350 ++++++++-------- src/changes/changes.xml | 15 + 5 files changed, 492 insertions(+), 436 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/BaseJpaResourceProviderValueSetDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/BaseJpaResourceProviderValueSetDstu3.java index dc4f88e9a6b..d4bcb91db47 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/BaseJpaResourceProviderValueSetDstu3.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/BaseJpaResourceProviderValueSetDstu3.java @@ -20,35 +20,42 @@ package ca.uhn.fhir.jpa.provider.dstu3; * #L% */ -import static org.apache.commons.lang3.StringUtils.isNotBlank; +import ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet; +import ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.ValidateCodeResult; +import ca.uhn.fhir.rest.annotation.IdParam; +import ca.uhn.fhir.rest.annotation.Operation; +import ca.uhn.fhir.rest.annotation.OperationParam; +import ca.uhn.fhir.rest.api.server.RequestDetails; +import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; +import org.hl7.fhir.dstu3.model.*; import javax.servlet.http.HttpServletRequest; -import org.hl7.fhir.dstu3.model.*; - -import ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet; -import ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.ValidateCodeResult; -import ca.uhn.fhir.rest.annotation.*; -import ca.uhn.fhir.rest.api.server.RequestDetails; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; +import static org.apache.commons.lang3.StringUtils.isNotBlank; public class BaseJpaResourceProviderValueSetDstu3 extends JpaResourceProviderDstu3 { - //@formatter:off @Operation(name = "$expand", idempotent = true) public ValueSet expand( - HttpServletRequest theServletRequest, - @IdParam(optional=true) IdType theId, - @OperationParam(name="valueSet", min=0, max=1) ValueSet theValueSet, - @OperationParam(name="identifier", min=0, max=1) UriType theIdentifier, - @OperationParam(name = "filter", min=0, max=1) StringType theFilter, - RequestDetails theRequestDetails) { - //@formatter:on - + HttpServletRequest theServletRequest, + @IdParam(optional = true) IdType theId, + @OperationParam(name = "valueSet", min = 0, max = 1) ValueSet theValueSet, + // Note: url is correct and identifier is not, but identifier was only added as + // of 3.1.0 so we'll leave url for now. See: https://groups.google.com/d/msgid/hapi-fhir/CAN2Cfy8kW%2BAOkgC6VjPsU3gRCpExCNZBmJdi-k5R_TWeyWH4tA%40mail.gmail.com?utm_medium=email&utm_source=footer + @OperationParam(name = "url", min = 0, max = 1) UriType theUrl, + @OperationParam(name = "identifier", min = 0, max = 1) UriType theIdentifier, + @OperationParam(name = "filter", min = 0, max = 1) StringType theFilter, + RequestDetails theRequestDetails) { + boolean haveId = theId != null && theId.hasIdPart(); - boolean haveIdentifier = theIdentifier != null && isNotBlank(theIdentifier.getValue()); + UriType url = theIdentifier; + if (theUrl != null && isNotBlank(theUrl.getValue())) { + url = theUrl; + } + + boolean haveIdentifier = url != null && isNotBlank(url.getValue()); boolean haveValueSet = theValueSet != null && theValueSet.isEmpty() == false; - + if (!haveId && !haveIdentifier && !haveValueSet) { throw new InvalidRequestException("$expand operation at the type level (no ID specified) requires an identifier or a valueSet as a part of the request"); } @@ -56,18 +63,18 @@ public class BaseJpaResourceProviderValueSetDstu3 extends JpaResourceProviderDst if (moreThanOneTrue(haveId, haveIdentifier, haveValueSet)) { throw new InvalidRequestException("$expand must EITHER be invoked at the instance level, or have an identifier specified, or have a ValueSet specified. Can not combine these options."); } - + startRequest(theServletRequest); try { IFhirResourceDaoValueSet dao = (IFhirResourceDaoValueSet) getDao(); if (haveId) { return dao.expand(theId, toFilterString(theFilter), theRequestDetails); } else if (haveIdentifier) { - return dao.expandByIdentifier(theIdentifier.getValue(), toFilterString(theFilter)); + return dao.expandByIdentifier(url.getValue(), toFilterString(theFilter)); } else { return dao.expand(theValueSet, toFilterString(theFilter)); } - + } finally { endRequest(theServletRequest); } @@ -79,30 +86,34 @@ public class BaseJpaResourceProviderValueSetDstu3 extends JpaResourceProviderDst } - //@formatter:off @SuppressWarnings("unchecked") - @Operation(name = "$validate-code", idempotent = true, returnParameters= { - @OperationParam(name="result", type=BooleanType.class, min=1), - @OperationParam(name="message", type=StringType.class), - @OperationParam(name="display", type=StringType.class) + @Operation(name = "$validate-code", idempotent = true, returnParameters = { + @OperationParam(name = "result", type = BooleanType.class, min = 1), + @OperationParam(name = "message", type = StringType.class), + @OperationParam(name = "display", type = StringType.class) }) public Parameters validateCode( - HttpServletRequest theServletRequest, - @IdParam(optional=true) IdType theId, - @OperationParam(name="identifier", min=0, max=1) UriType theValueSetIdentifier, - @OperationParam(name="code", min=0, max=1) CodeType theCode, - @OperationParam(name="system", min=0, max=1) UriType theSystem, - @OperationParam(name="display", min=0, max=1) StringType theDisplay, - @OperationParam(name="coding", min=0, max=1) Coding theCoding, - @OperationParam(name="codeableConcept", min=0, max=1) CodeableConcept theCodeableConcept, - RequestDetails theRequestDetails - ) { - //@formatter:on - + HttpServletRequest theServletRequest, + @IdParam(optional = true) IdType theId, + @OperationParam(name = "identifier", min = 0, max = 1) UriType theValueSetIdentifier, + @OperationParam(name = "url", min = 0, max = 1) UriType theValueSetUrl, + @OperationParam(name = "code", min = 0, max = 1) CodeType theCode, + @OperationParam(name = "system", min = 0, max = 1) UriType theSystem, + @OperationParam(name = "display", min = 0, max = 1) StringType theDisplay, + @OperationParam(name = "coding", min = 0, max = 1) Coding theCoding, + @OperationParam(name = "codeableConcept", min = 0, max = 1) CodeableConcept theCodeableConcept, + RequestDetails theRequestDetails + ) { + + UriType url = theValueSetIdentifier; + if (theValueSetUrl != null && isNotBlank(theValueSetUrl.getValue())) { + url = theValueSetUrl; + } + startRequest(theServletRequest); try { IFhirResourceDaoValueSet dao = (IFhirResourceDaoValueSet) getDao(); - ValidateCodeResult result = dao.validateCode(theValueSetIdentifier, theId, theCode, theSystem, theDisplay, theCoding, theCodeableConcept, theRequestDetails); + ValidateCodeResult result = dao.validateCode(url, theId, theCode, theSystem, theDisplay, theCoding, theCodeableConcept, theRequestDetails); Parameters retVal = new Parameters(); retVal.addParameter().setName("result").setValue(new BooleanType(result.isResult())); if (isNotBlank(result.getMessage())) { @@ -117,8 +128,7 @@ public class BaseJpaResourceProviderValueSetDstu3 extends JpaResourceProviderDst } } - - + private static boolean moreThanOneTrue(boolean... theBooleans) { boolean haveOne = false; for (boolean next : theBooleans) { @@ -133,5 +143,5 @@ public class BaseJpaResourceProviderValueSetDstu3 extends JpaResourceProviderDst return false; } - + } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/BaseJpaResourceProviderValueSetR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/BaseJpaResourceProviderValueSetR4.java index e6fc680de59..998c86faabf 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/BaseJpaResourceProviderValueSetR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/BaseJpaResourceProviderValueSetR4.java @@ -20,54 +20,53 @@ package ca.uhn.fhir.jpa.provider.r4; * #L% */ -import static org.apache.commons.lang3.StringUtils.isNotBlank; +import ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet; +import ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.ValidateCodeResult; +import ca.uhn.fhir.rest.annotation.IdParam; +import ca.uhn.fhir.rest.annotation.Operation; +import ca.uhn.fhir.rest.annotation.OperationParam; +import ca.uhn.fhir.rest.api.server.RequestDetails; +import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; +import org.hl7.fhir.r4.model.*; import javax.servlet.http.HttpServletRequest; -import org.hl7.fhir.r4.model.*; - -import ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet; -import ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.ValidateCodeResult; -import ca.uhn.fhir.rest.annotation.*; -import ca.uhn.fhir.rest.api.server.RequestDetails; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; +import static org.apache.commons.lang3.StringUtils.isNotBlank; public class BaseJpaResourceProviderValueSetR4 extends JpaResourceProviderR4 { - //@formatter:off @Operation(name = "$expand", idempotent = true) public ValueSet expand( - HttpServletRequest theServletRequest, - @IdParam(optional=true) IdType theId, - @OperationParam(name="valueSet", min=0, max=1) ValueSet theValueSet, - @OperationParam(name="identifier", min=0, max=1) UriType theIdentifier, - @OperationParam(name = "filter", min=0, max=1) StringType theFilter, - RequestDetails theRequestDetails) { - //@formatter:on - + HttpServletRequest theServletRequest, + @IdParam(optional = true) IdType theId, + @OperationParam(name = "valueSet", min = 0, max = 1) ValueSet theValueSet, + @OperationParam(name = "url", min = 0, max = 1) UriType theUrl, + @OperationParam(name = "filter", min = 0, max = 1) StringType theFilter, + RequestDetails theRequestDetails) { + boolean haveId = theId != null && theId.hasIdPart(); - boolean haveIdentifier = theIdentifier != null && isNotBlank(theIdentifier.getValue()); + boolean haveIdentifier = theUrl != null && isNotBlank(theUrl.getValue()); boolean haveValueSet = theValueSet != null && theValueSet.isEmpty() == false; - + if (!haveId && !haveIdentifier && !haveValueSet) { - throw new InvalidRequestException("$expand operation at the type level (no ID specified) requires an identifier or a valueSet as a part of the request"); + throw new InvalidRequestException("$expand operation at the type level (no ID specified) requires a url or a valueSet as a part of the request"); } if (moreThanOneTrue(haveId, haveIdentifier, haveValueSet)) { - throw new InvalidRequestException("$expand must EITHER be invoked at the instance level, or have an identifier specified, or have a ValueSet specified. Can not combine these options."); + throw new InvalidRequestException("$expand must EITHER be invoked at the instance level, or have a url specified, or have a ValueSet specified. Can not combine these options."); } - + startRequest(theServletRequest); try { IFhirResourceDaoValueSet dao = (IFhirResourceDaoValueSet) getDao(); if (haveId) { return dao.expand(theId, toFilterString(theFilter), theRequestDetails); } else if (haveIdentifier) { - return dao.expandByIdentifier(theIdentifier.getValue(), toFilterString(theFilter)); + return dao.expandByIdentifier(theUrl.getValue(), toFilterString(theFilter)); } else { return dao.expand(theValueSet, toFilterString(theFilter)); } - + } finally { endRequest(theServletRequest); } @@ -79,30 +78,28 @@ public class BaseJpaResourceProviderValueSetR4 extends JpaResourceProviderR4 dao = (IFhirResourceDaoValueSet) getDao(); - ValidateCodeResult result = dao.validateCode(theValueSetIdentifier, theId, theCode, theSystem, theDisplay, theCoding, theCodeableConcept, theRequestDetails); + ValidateCodeResult result = dao.validateCode(theValueSetUrl, theId, theCode, theSystem, theDisplay, theCoding, theCodeableConcept, theRequestDetails); Parameters retVal = new Parameters(); retVal.addParameter().setName("result").setValue(new BooleanType(result.isResult())); if (isNotBlank(result.getMessage())) { @@ -117,8 +114,7 @@ public class BaseJpaResourceProviderValueSetR4 extends JpaResourceProviderR4 codeSystemDao = myCodeSystemDao; IResourceTableDao resourceTableDao = myResourceTableDao; IHapiTerminologySvc termSvc = myTermSvc; - + return createExternalCs(codeSystemDao, resourceTableDao, termSvc, mySrd); } - public static CodeSystem createExternalCs(IFhirResourceDao theCodeSystemDao, IResourceTableDao theResourceTableDao, IHapiTerminologySvc theTermSvc, ServletRequestDetails theRequestDetails) { - CodeSystem codeSystem = new CodeSystem(); - codeSystem.setUrl(URL_MY_CODE_SYSTEM); - codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); - IIdType id = theCodeSystemDao.create(codeSystem, theRequestDetails).getId().toUnqualified(); - - ResourceTable table = theResourceTableDao.findOne(id.getIdPartAsLong()); - - TermCodeSystemVersion cs = new TermCodeSystemVersion(); - cs.setResource(table); - cs.setResourceVersionId(table.getVersion()); - - TermConcept parentA = new TermConcept(cs, "ParentA").setDisplay("Parent A"); - cs.getConcepts().add(parentA); - - TermConcept childAA = new TermConcept(cs, "childAA").setDisplay("Child AA"); - parentA.addChild(childAA, RelationshipTypeEnum.ISA); - - TermConcept childAAA = new TermConcept(cs, "childAAA").setDisplay("Child AAA"); - childAA.addChild(childAAA, RelationshipTypeEnum.ISA); - - TermConcept childAAB = new TermConcept(cs, "childAAB").setDisplay("Child AAB"); - childAA.addChild(childAAB, RelationshipTypeEnum.ISA); - - TermConcept childAB = new TermConcept(cs, "childAB").setDisplay("Child AB"); - parentA.addChild(childAB, RelationshipTypeEnum.ISA); - - TermConcept parentB = new TermConcept(cs, "ParentB").setDisplay("Parent B"); - cs.getConcepts().add(parentB); - - theTermSvc.storeNewCodeSystemVersion(table.getId(), URL_MY_CODE_SYSTEM, cs); - return codeSystem; - } - private void createExternalCsAndLocalVs() { CodeSystem codeSystem = createExternalCs(); @@ -131,17 +75,17 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3 //@formatter:off CodeSystem codeSystem = new CodeSystem(); codeSystem.setUrl(URL_MY_CODE_SYSTEM); - codeSystem.setContent(CodeSystemContentMode.COMPLETE); + codeSystem.setContent(CodeSystemContentMode.COMPLETE); codeSystem .addConcept().setCode("A").setDisplay("Code A") - .addConcept(new ConceptDefinitionComponent().setCode("AA").setDisplay("Code AA") - .addConcept(new ConceptDefinitionComponent().setCode("AAA").setDisplay("Code AAA")) - ) - .addConcept(new ConceptDefinitionComponent().setCode("AB").setDisplay("Code AB")); + .addConcept(new ConceptDefinitionComponent().setCode("AA").setDisplay("Code AA") + .addConcept(new ConceptDefinitionComponent().setCode("AAA").setDisplay("Code AAA")) + ) + .addConcept(new ConceptDefinitionComponent().setCode("AB").setDisplay("Code AB")); codeSystem .addConcept().setCode("B").setDisplay("Code B") - .addConcept(new ConceptDefinitionComponent().setCode("BA").setDisplay("Code BA")) - .addConcept(new ConceptDefinitionComponent().setCode("BB").setDisplay("Code BB")); + .addConcept(new ConceptDefinitionComponent().setCode("BA").setDisplay("Code BA")) + .addConcept(new ConceptDefinitionComponent().setCode("BB").setDisplay("Code BB")); //@formatter:on myCodeSystemDao.create(codeSystem, mySrd); @@ -185,49 +129,25 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3 .execute(); ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource(); //@formatter:on - + String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded); ourLog.info(resp); - assertThat(resp, containsString("")); + assertThat(resp, containsString("")); assertThat(resp, containsString("")); assertThat(resp, containsString("")); assertThat(resp, containsString("")); assertThat(resp, containsString("")); - assertThat(resp, containsString("")); + assertThat(resp, containsString("")); assertThat(resp, containsString("")); assertThat(resp, containsString("")); assertThat(resp, containsString("")); assertThat(resp, containsString("")); - assertThat(resp, containsString("")); + assertThat(resp, containsString("")); assertThat(resp, containsString("")); assertThat(resp, containsString("")); } - @Test - public void testExpandByIdentifier() { - //@formatter:off - Parameters respParam = ourClient - .operation() - .onType(ValueSet.class) - .named("expand") - .withParameter(Parameters.class, "identifier", new UriType("http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2")) - .execute(); - ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource(); - //@formatter:on - - String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded); - ourLog.info(resp); - //@formatter:off - assertThat(resp, stringContainsInOrder( - "", - "")); - //@formatter:on - - } - - // - @Test public void testExpandByIdWithFilter() throws IOException { @@ -245,13 +165,56 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3 ourLog.info(resp); assertThat(resp, containsString("")); assertThat(resp, not(containsString(""))); - + + } + + /** + * $expand?identifier=foo is legacy.. It's actually not valid in FHIR as of STU3 + * but we supported it for longer than we should have so I don't want to delete + * it right now. + * + * https://groups.google.com/d/msgid/hapi-fhir/CAN2Cfy8kW%2BAOkgC6VjPsU3gRCpExCNZBmJdi-k5R_TWeyWH4tA%40mail.gmail.com?utm_medium=email&utm_source=footer + */ + @Test + public void testExpandByIdentifier() { + Parameters respParam = ourClient + .operation() + .onType(ValueSet.class) + .named("expand") + .withParameter(Parameters.class, "identifier", new UriType("http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2")) + .execute(); + ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource(); + + String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded); + ourLog.info(resp); + assertThat(resp, stringContainsInOrder( + "", + "")); + + } + + @Test + public void testExpandByUrl() { + Parameters respParam = ourClient + .operation() + .onType(ValueSet.class) + .named("expand") + .withParameter(Parameters.class, "url", new UriType("http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2")) + .execute(); + ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource(); + + String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded); + ourLog.info(resp); + assertThat(resp, stringContainsInOrder( + "", + "")); + } @Test public void testExpandByValueSet() throws IOException { ValueSet toExpand = loadResourceFromClasspath(ValueSet.class, "/extensional-case-3-vs.xml"); - + //@formatter:off Parameters respParam = ourClient .operation() @@ -266,8 +229,8 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3 ourLog.info(resp); //@formatter:off assertThat(resp, stringContainsInOrder( - "", - "")); + "", + "")); //@formatter:on } @@ -276,7 +239,7 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3 public void testExpandInlineVsAgainstBuiltInCs() throws IOException { createLocalVsPointingAtBuiltInCodeSystem(); assertNotNull(myLocalValueSetId); - + //@formatter:off Parameters respParam = ourClient .operation() @@ -286,10 +249,10 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3 .execute(); ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource(); //@formatter:on - + String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded); ourLog.info(resp); - + assertThat(resp, containsStringIgnoringCase("")); } @@ -298,7 +261,7 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3 createExternalCsAndLocalVs(); assertNotNull(myLocalVs); myLocalVs.setId(""); - + //@formatter:off Parameters respParam = ourClient .operation() @@ -308,16 +271,15 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3 .execute(); ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource(); //@formatter:on - + String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded); ourLog.info(resp); - + assertThat(resp, containsStringIgnoringCase("")); assertThat(resp, containsStringIgnoringCase("")); assertThat(resp, not(containsStringIgnoringCase(""))); - - } + } @Test public void testExpandInvalidParams() throws IOException { @@ -373,7 +335,7 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3 public void testExpandLocalVsAgainstBuiltInCs() throws IOException { createLocalVsPointingAtBuiltInCodeSystem(); assertNotNull(myLocalValueSetId); - + //@formatter:off Parameters respParam = ourClient .operation() @@ -383,22 +345,18 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3 .execute(); ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource(); //@formatter:on - + String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded); ourLog.info(resp); - + assertThat(resp, containsStringIgnoringCase("")); } - - - - - + @Test public void testExpandLocalVsAgainstExternalCs() throws IOException { createExternalCsAndLocalVs(); assertNotNull(myLocalValueSetId); - + //@formatter:off Parameters respParam = ourClient .operation() @@ -408,21 +366,21 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3 .execute(); ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource(); //@formatter:on - + String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded); ourLog.info(resp); - + assertThat(resp, containsStringIgnoringCase("")); assertThat(resp, containsStringIgnoringCase("")); assertThat(resp, not(containsStringIgnoringCase(""))); - + } @Test public void testExpandLocalVsCanonicalAgainstExternalCs() throws IOException { createExternalCsAndLocalVs(); assertNotNull(myLocalValueSetId); - + //@formatter:off Parameters respParam = ourClient .operation() @@ -432,21 +390,21 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3 .execute(); ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource(); //@formatter:on - + String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded); ourLog.info(resp); - + assertThat(resp, containsStringIgnoringCase("")); assertThat(resp, containsStringIgnoringCase("")); assertThat(resp, not(containsStringIgnoringCase(""))); - + } @Test public void testExpandLocalVsWithUnknownCode() throws IOException { createExternalCsAndLocalVsWithUnknownCode(); assertNotNull(myLocalValueSetId); - + //@formatter:off try { ourClient @@ -461,34 +419,31 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3 //@formatter:on } + /** + * #516 + */ @Test - public void testValiedateCodeAgainstBuiltInSystem() { - //@formatter:off - Parameters respParam = ourClient - .operation() - .onType(ValueSet.class) - .named("validate-code") - .withParameter(Parameters.class, "code", new StringType("BRN")) - .andParameter("identifier", new StringType("http://hl7.org/fhir/ValueSet/v2-0487")) - .andParameter("system", new StringType("http://hl7.org/fhir/v2/0487")) - .useHttpGet() - .execute(); - //@formatter:on + public void testInvalidFilter() throws Exception { + String string = IOUtils.toString(getClass().getResourceAsStream("/bug_516_invalid_expansion.json"), StandardCharsets.UTF_8); + HttpPost post = new HttpPost(ourServerBase + "/ValueSet/%24expand"); + post.setEntity(new StringEntity(string, ContentType.parse(ca.uhn.fhir.rest.api.Constants.CT_FHIR_JSON_NEW))); - String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(respParam); - ourLog.info(resp); - - assertEquals("result", respParam.getParameter().get(0).getName()); - assertEquals(true, ((BooleanType)respParam.getParameter().get(0).getValue()).getValue().booleanValue()); - - assertEquals("message", respParam.getParameter().get(1).getName()); - assertThat(((StringType)respParam.getParameter().get(1).getValue()).getValue(), containsStringIgnoringCase("succeeded")); + CloseableHttpResponse resp = ourHttpClient.execute(post); + try { - assertEquals("display", respParam.getParameter().get(2).getName()); - assertEquals("Burn", ((StringType)respParam.getParameter().get(2).getValue()).getValue()); + String respString = IOUtils.toString(resp.getEntity().getContent(), StandardCharsets.UTF_8); + ourLog.info(respString); + + ourLog.info(resp.toString()); + + assertEquals(400, resp.getStatusLine().getStatusCode()); + assertThat(respString, containsString("Unknown FilterOperator code 'n'")); + + } finally { + IOUtils.closeQuietly(resp); + } } - @Test public void testValidateCodeOperationByCodeAndSystemInstance() { //@formatter:off @@ -503,8 +458,8 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3 String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(respParam); ourLog.info(resp); - - assertEquals(true, ((BooleanType)respParam.getParameter().get(0).getValue()).booleanValue()); + + assertEquals(true, ((BooleanType) respParam.getParameter().get(0).getValue()).booleanValue()); } @Test @@ -521,8 +476,64 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3 String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(respParam); ourLog.info(resp); - - assertEquals(true, ((BooleanType)respParam.getParameter().get(0).getValue()).booleanValue()); + + assertEquals(true, ((BooleanType) respParam.getParameter().get(0).getValue()).booleanValue()); + } + + /** + * Technically this is the wrong param name + */ + @Test + public void testValiedateCodeAgainstBuiltInSystem() { + Parameters respParam = ourClient + .operation() + .onType(ValueSet.class) + .named("validate-code") + .withParameter(Parameters.class, "code", new StringType("BRN")) + .andParameter("identifier", new StringType("http://hl7.org/fhir/ValueSet/v2-0487")) + .andParameter("system", new StringType("http://hl7.org/fhir/v2/0487")) + .useHttpGet() + .execute(); + + String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(respParam); + ourLog.info(resp); + + assertEquals("result", respParam.getParameter().get(0).getName()); + assertEquals(true, ((BooleanType) respParam.getParameter().get(0).getValue()).getValue().booleanValue()); + + assertEquals("message", respParam.getParameter().get(1).getName()); + assertThat(((StringType) respParam.getParameter().get(1).getValue()).getValue(), containsStringIgnoringCase("succeeded")); + + assertEquals("display", respParam.getParameter().get(2).getName()); + assertEquals("Burn", ((StringType) respParam.getParameter().get(2).getValue()).getValue()); + } + + /** + * Technically this is the right param name + */ + @Test + public void testValiedateCodeAgainstBuiltInSystemByUrl() { + Parameters respParam = ourClient + .operation() + .onType(ValueSet.class) + .named("validate-code") + .withParameter(Parameters.class, "code", new StringType("BRN")) + .andParameter("url", new StringType("http://hl7.org/fhir/ValueSet/v2-0487")) + .andParameter("system", new StringType("http://hl7.org/fhir/v2/0487")) + .useHttpGet() + .execute(); + + String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(respParam); + ourLog.info(resp); + + assertEquals("result", respParam.getParameter().get(0).getName()); + assertEquals(true, ((BooleanType) respParam.getParameter().get(0).getValue()).getValue().booleanValue()); + + assertEquals("message", respParam.getParameter().get(1).getName()); + assertThat(((StringType) respParam.getParameter().get(1).getValue()).getValue(), containsStringIgnoringCase("succeeded")); + + assertEquals("display", respParam.getParameter().get(2).getName()); + assertEquals("Burn", ((StringType) respParam.getParameter().get(2).getValue()).getValue()); } @AfterClass @@ -530,4 +541,38 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3 TestUtil.clearAllStaticFieldsForUnitTest(); } + public static CodeSystem createExternalCs(IFhirResourceDao theCodeSystemDao, IResourceTableDao theResourceTableDao, IHapiTerminologySvc theTermSvc, ServletRequestDetails theRequestDetails) { + CodeSystem codeSystem = new CodeSystem(); + codeSystem.setUrl(URL_MY_CODE_SYSTEM); + codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); + IIdType id = theCodeSystemDao.create(codeSystem, theRequestDetails).getId().toUnqualified(); + + ResourceTable table = theResourceTableDao.findOne(id.getIdPartAsLong()); + + TermCodeSystemVersion cs = new TermCodeSystemVersion(); + cs.setResource(table); + cs.setResourceVersionId(table.getVersion()); + + TermConcept parentA = new TermConcept(cs, "ParentA").setDisplay("Parent A"); + cs.getConcepts().add(parentA); + + TermConcept childAA = new TermConcept(cs, "childAA").setDisplay("Child AA"); + parentA.addChild(childAA, RelationshipTypeEnum.ISA); + + TermConcept childAAA = new TermConcept(cs, "childAAA").setDisplay("Child AAA"); + childAA.addChild(childAAA, RelationshipTypeEnum.ISA); + + TermConcept childAAB = new TermConcept(cs, "childAAB").setDisplay("Child AAB"); + childAA.addChild(childAAB, RelationshipTypeEnum.ISA); + + TermConcept childAB = new TermConcept(cs, "childAB").setDisplay("Child AB"); + parentA.addChild(childAB, RelationshipTypeEnum.ISA); + + TermConcept parentB = new TermConcept(cs, "ParentB").setDisplay("Parent B"); + cs.getConcepts().add(parentB); + + theTermSvc.storeNewCodeSystemVersion(table.getId(), URL_MY_CODE_SYSTEM, cs); + return codeSystem; + } + } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetTest.java index 2dacfaf2322..b8cb2a801bc 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetTest.java @@ -1,35 +1,38 @@ package ca.uhn.fhir.jpa.provider.r4; -import static ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoR4TerminologyTest.URL_MY_CODE_SYSTEM; -import static ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoR4TerminologyTest.URL_MY_VALUE_SET; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.StringEntity; -import org.hl7.fhir.r4.model.*; -import org.hl7.fhir.r4.model.CodeSystem.CodeSystemContentMode; -import org.hl7.fhir.r4.model.CodeSystem.ConceptDefinitionComponent; -import org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent; -import org.hl7.fhir.r4.model.ValueSet.FilterOperator; -import org.hl7.fhir.instance.model.api.IIdType; -import org.junit.*; -import org.springframework.transaction.annotation.Transactional; - import ca.uhn.fhir.jpa.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.dao.data.IResourceTableDao; -import ca.uhn.fhir.jpa.entity.*; +import ca.uhn.fhir.jpa.entity.ResourceTable; +import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion; +import ca.uhn.fhir.jpa.entity.TermConcept; import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum; import ca.uhn.fhir.jpa.term.IHapiTerminologySvc; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.util.TestUtil; +import org.apache.commons.io.IOUtils; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.hl7.fhir.instance.model.api.IIdType; +import org.hl7.fhir.r4.model.*; +import org.hl7.fhir.r4.model.CodeSystem.CodeSystemContentMode; +import org.hl7.fhir.r4.model.CodeSystem.ConceptDefinitionComponent; +import org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent; +import org.hl7.fhir.r4.model.ValueSet.FilterOperator; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; +import org.springframework.transaction.annotation.Transactional; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import static ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoR4TerminologyTest.URL_MY_CODE_SYSTEM; +import static ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoR4TerminologyTest.URL_MY_VALUE_SET; +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { @@ -48,73 +51,14 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { myExtensionalVsId = myValueSetDao.create(upload, mySrd).getId().toUnqualifiedVersionless(); } - /** - * #516 - */ - @Test - public void testInvalidFilter() throws Exception { - String string = IOUtils.toString(getClass().getResourceAsStream("/bug_516_invalid_expansion.json"), StandardCharsets.UTF_8); - HttpPost post = new HttpPost(ourServerBase+"/ValueSet/%24expand"); - post.setEntity(new StringEntity(string, ContentType.parse(ca.uhn.fhir.rest.api.Constants.CT_FHIR_JSON_NEW))); - - CloseableHttpResponse resp = ourHttpClient.execute(post); - try { - - String respString = IOUtils.toString(resp.getEntity().getContent(), StandardCharsets.UTF_8); - ourLog.info(respString); - - ourLog.info(resp.toString()); - - assertEquals(400, resp.getStatusLine().getStatusCode()); - assertThat(respString, containsString("Unknown FilterOperator code 'n'")); - - }finally { - IOUtils.closeQuietly(resp); - } - } - private CodeSystem createExternalCs() { IFhirResourceDao codeSystemDao = myCodeSystemDao; IResourceTableDao resourceTableDao = myResourceTableDao; IHapiTerminologySvc termSvc = myTermSvc; - + return createExternalCs(codeSystemDao, resourceTableDao, termSvc, mySrd); } - public static CodeSystem createExternalCs(IFhirResourceDao theCodeSystemDao, IResourceTableDao theResourceTableDao, IHapiTerminologySvc theTermSvc, ServletRequestDetails theRequestDetails) { - CodeSystem codeSystem = new CodeSystem(); - codeSystem.setUrl(URL_MY_CODE_SYSTEM); - codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); - IIdType id = theCodeSystemDao.create(codeSystem, theRequestDetails).getId().toUnqualified(); - - ResourceTable table = theResourceTableDao.findOne(id.getIdPartAsLong()); - - TermCodeSystemVersion cs = new TermCodeSystemVersion(); - cs.setResource(table); - cs.setResourceVersionId(table.getVersion()); - - TermConcept parentA = new TermConcept(cs, "ParentA").setDisplay("Parent A"); - cs.getConcepts().add(parentA); - - TermConcept childAA = new TermConcept(cs, "childAA").setDisplay("Child AA"); - parentA.addChild(childAA, RelationshipTypeEnum.ISA); - - TermConcept childAAA = new TermConcept(cs, "childAAA").setDisplay("Child AAA"); - childAA.addChild(childAAA, RelationshipTypeEnum.ISA); - - TermConcept childAAB = new TermConcept(cs, "childAAB").setDisplay("Child AAB"); - childAA.addChild(childAAB, RelationshipTypeEnum.ISA); - - TermConcept childAB = new TermConcept(cs, "childAB").setDisplay("Child AB"); - parentA.addChild(childAB, RelationshipTypeEnum.ISA); - - TermConcept parentB = new TermConcept(cs, "ParentB").setDisplay("Parent B"); - cs.getConcepts().add(parentB); - - theTermSvc.storeNewCodeSystemVersion(table.getId(), URL_MY_CODE_SYSTEM, cs); - return codeSystem; - } - private void createExternalCsAndLocalVs() { CodeSystem codeSystem = createExternalCs(); @@ -131,17 +75,17 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { //@formatter:off CodeSystem codeSystem = new CodeSystem(); codeSystem.setUrl(URL_MY_CODE_SYSTEM); - codeSystem.setContent(CodeSystemContentMode.COMPLETE); + codeSystem.setContent(CodeSystemContentMode.COMPLETE); codeSystem .addConcept().setCode("A").setDisplay("Code A") - .addConcept(new ConceptDefinitionComponent().setCode("AA").setDisplay("Code AA") - .addConcept(new ConceptDefinitionComponent().setCode("AAA").setDisplay("Code AAA")) - ) - .addConcept(new ConceptDefinitionComponent().setCode("AB").setDisplay("Code AB")); + .addConcept(new ConceptDefinitionComponent().setCode("AA").setDisplay("Code AA") + .addConcept(new ConceptDefinitionComponent().setCode("AAA").setDisplay("Code AAA")) + ) + .addConcept(new ConceptDefinitionComponent().setCode("AB").setDisplay("Code AB")); codeSystem .addConcept().setCode("B").setDisplay("Code B") - .addConcept(new ConceptDefinitionComponent().setCode("BA").setDisplay("Code BA")) - .addConcept(new ConceptDefinitionComponent().setCode("BB").setDisplay("Code BB")); + .addConcept(new ConceptDefinitionComponent().setCode("BA").setDisplay("Code BA")) + .addConcept(new ConceptDefinitionComponent().setCode("BB").setDisplay("Code BB")); //@formatter:on myCodeSystemDao.create(codeSystem, mySrd); @@ -185,49 +129,25 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { .execute(); ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource(); //@formatter:on - + String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded); ourLog.info(resp); - assertThat(resp, containsString("")); + assertThat(resp, containsString("")); assertThat(resp, containsString("")); assertThat(resp, containsString("")); assertThat(resp, containsString("")); assertThat(resp, containsString("")); - assertThat(resp, containsString("")); + assertThat(resp, containsString("")); assertThat(resp, containsString("")); assertThat(resp, containsString("")); assertThat(resp, containsString("")); assertThat(resp, containsString("")); - assertThat(resp, containsString("")); + assertThat(resp, containsString("")); assertThat(resp, containsString("")); assertThat(resp, containsString("")); } - @Test - public void testExpandByIdentifier() { - //@formatter:off - Parameters respParam = ourClient - .operation() - .onType(ValueSet.class) - .named("expand") - .withParameter(Parameters.class, "identifier", new UriType("http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2")) - .execute(); - ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource(); - //@formatter:on - - String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded); - ourLog.info(resp); - //@formatter:off - assertThat(resp, stringContainsInOrder( - "", - "")); - //@formatter:on - - } - - // - @Test public void testExpandByIdWithFilter() throws IOException { @@ -245,13 +165,31 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { ourLog.info(resp); assertThat(resp, containsString("")); assertThat(resp, not(containsString(""))); - + + } + + @Test + public void testExpandByUrl() { + Parameters respParam = ourClient + .operation() + .onType(ValueSet.class) + .named("expand") + .withParameter(Parameters.class, "url", new UriType("http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2")) + .execute(); + ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource(); + + String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded); + ourLog.info(resp); + assertThat(resp, stringContainsInOrder( + "", + "")); + } @Test public void testExpandByValueSet() throws IOException { ValueSet toExpand = loadResourceFromClasspath(ValueSet.class, "/extensional-case-3-vs.xml"); - + Parameters respParam = ourClient .operation() .onType(ValueSet.class) @@ -263,16 +201,17 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded); ourLog.info(resp); assertThat(resp, stringContainsInOrder( - "", - "")); + "", + "")); } + @Test public void testExpandInlineVsAgainstBuiltInCs() throws IOException { createLocalVsPointingAtBuiltInCodeSystem(); assertNotNull(myLocalValueSetId); - + //@formatter:off Parameters respParam = ourClient .operation() @@ -282,10 +221,10 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { .execute(); ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource(); //@formatter:on - + String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded); ourLog.info(resp); - + assertThat(resp, containsStringIgnoringCase("")); } @@ -294,7 +233,7 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { createExternalCsAndLocalVs(); assertNotNull(myLocalVs); myLocalVs.setId(""); - + //@formatter:off Parameters respParam = ourClient .operation() @@ -304,16 +243,15 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { .execute(); ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource(); //@formatter:on - + String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded); ourLog.info(resp); - + assertThat(resp, containsStringIgnoringCase("")); assertThat(resp, containsStringIgnoringCase("")); assertThat(resp, not(containsStringIgnoringCase(""))); - - } + } @Test public void testExpandInvalidParams() throws IOException { @@ -327,7 +265,7 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { .execute(); fail(); } catch (InvalidRequestException e) { - assertEquals("HTTP 400 Bad Request: $expand operation at the type level (no ID specified) requires an identifier or a valueSet as a part of the request", e.getMessage()); + assertEquals("HTTP 400 Bad Request: $expand operation at the type level (no ID specified) requires a url or a valueSet as a part of the request", e.getMessage()); } //@formatter:on @@ -339,11 +277,11 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { .onType(ValueSet.class) .named("expand") .withParameter(Parameters.class, "valueSet", toExpand) - .andParameter("identifier", new UriType("http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2")) + .andParameter("url", new UriType("http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2")) .execute(); fail(); } catch (InvalidRequestException e) { - assertEquals("HTTP 400 Bad Request: $expand must EITHER be invoked at the instance level, or have an identifier specified, or have a ValueSet specified. Can not combine these options.", e.getMessage()); + assertEquals("HTTP 400 Bad Request: $expand must EITHER be invoked at the instance level, or have a url specified, or have a ValueSet specified. Can not combine these options.", e.getMessage()); } //@formatter:on @@ -355,11 +293,11 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { .onInstance(myExtensionalVsId) .named("expand") .withParameter(Parameters.class, "valueSet", toExpand) - .andParameter("identifier", new UriType("http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2")) + .andParameter("url", new UriType("http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2")) .execute(); fail(); } catch (InvalidRequestException e) { - assertEquals("HTTP 400 Bad Request: $expand must EITHER be invoked at the instance level, or have an identifier specified, or have a ValueSet specified. Can not combine these options.", e.getMessage()); + assertEquals("HTTP 400 Bad Request: $expand must EITHER be invoked at the instance level, or have a url specified, or have a ValueSet specified. Can not combine these options.", e.getMessage()); } //@formatter:on @@ -369,7 +307,7 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { public void testExpandLocalVsAgainstBuiltInCs() throws IOException { createLocalVsPointingAtBuiltInCodeSystem(); assertNotNull(myLocalValueSetId); - + //@formatter:off Parameters respParam = ourClient .operation() @@ -379,22 +317,18 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { .execute(); ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource(); //@formatter:on - + String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded); ourLog.info(resp); - + assertThat(resp, containsStringIgnoringCase("")); } - - - - - + @Test public void testExpandLocalVsAgainstExternalCs() throws IOException { createExternalCsAndLocalVs(); assertNotNull(myLocalValueSetId); - + //@formatter:off Parameters respParam = ourClient .operation() @@ -404,45 +338,45 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { .execute(); ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource(); //@formatter:on - + String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded); ourLog.info(resp); - + assertThat(resp, containsStringIgnoringCase("")); assertThat(resp, containsStringIgnoringCase("")); assertThat(resp, not(containsStringIgnoringCase(""))); - + } @Test public void testExpandLocalVsCanonicalAgainstExternalCs() throws IOException { createExternalCsAndLocalVs(); assertNotNull(myLocalValueSetId); - + //@formatter:off Parameters respParam = ourClient .operation() .onType(ValueSet.class) .named("expand") - .withParameter(Parameters.class, "identifier", new UriType(URL_MY_VALUE_SET)) + .withParameter(Parameters.class, "url", new UriType(URL_MY_VALUE_SET)) .execute(); ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource(); //@formatter:on - + String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded); ourLog.info(resp); - + assertThat(resp, containsStringIgnoringCase("")); assertThat(resp, containsStringIgnoringCase("")); assertThat(resp, not(containsStringIgnoringCase(""))); - + } @Test public void testExpandLocalVsWithUnknownCode() throws IOException { createExternalCsAndLocalVsWithUnknownCode(); assertNotNull(myLocalValueSetId); - + //@formatter:off try { ourClient @@ -457,34 +391,31 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { //@formatter:on } + /** + * #516 + */ @Test - public void testValiedateCodeAgainstBuiltInSystem() { - //@formatter:off - Parameters respParam = ourClient - .operation() - .onType(ValueSet.class) - .named("validate-code") - .withParameter(Parameters.class, "code", new StringType("BRN")) - .andParameter("identifier", new StringType("http://hl7.org/fhir/ValueSet/v2-0487")) - .andParameter("system", new StringType("http://hl7.org/fhir/v2/0487")) - .useHttpGet() - .execute(); - //@formatter:on + public void testInvalidFilter() throws Exception { + String string = IOUtils.toString(getClass().getResourceAsStream("/bug_516_invalid_expansion.json"), StandardCharsets.UTF_8); + HttpPost post = new HttpPost(ourServerBase + "/ValueSet/%24expand"); + post.setEntity(new StringEntity(string, ContentType.parse(ca.uhn.fhir.rest.api.Constants.CT_FHIR_JSON_NEW))); - String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(respParam); - ourLog.info(resp); - - assertEquals("result", respParam.getParameter().get(0).getName()); - assertEquals(true, ((BooleanType)respParam.getParameter().get(0).getValue()).getValue().booleanValue()); - - assertEquals("message", respParam.getParameter().get(1).getName()); - assertThat(((StringType)respParam.getParameter().get(1).getValue()).getValue(), containsStringIgnoringCase("succeeded")); + CloseableHttpResponse resp = ourHttpClient.execute(post); + try { - assertEquals("display", respParam.getParameter().get(2).getName()); - assertEquals("Burn", ((StringType)respParam.getParameter().get(2).getValue()).getValue()); + String respString = IOUtils.toString(resp.getEntity().getContent(), StandardCharsets.UTF_8); + ourLog.info(respString); + + ourLog.info(resp.toString()); + + assertEquals(400, resp.getStatusLine().getStatusCode()); + assertThat(respString, containsString("Unknown FilterOperator code 'n'")); + + } finally { + IOUtils.closeQuietly(resp); + } } - @Test public void testValidateCodeOperationByCodeAndSystemInstance() { //@formatter:off @@ -499,8 +430,8 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(respParam); ourLog.info(resp); - - assertEquals(true, ((BooleanType)respParam.getParameter().get(0).getValue()).booleanValue()); + + assertEquals(true, ((BooleanType) respParam.getParameter().get(0).getValue()).booleanValue()); } @Test @@ -517,8 +448,33 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(respParam); ourLog.info(resp); - - assertEquals(true, ((BooleanType)respParam.getParameter().get(0).getValue()).booleanValue()); + + assertEquals(true, ((BooleanType) respParam.getParameter().get(0).getValue()).booleanValue()); + } + + @Test + public void testValiedateCodeAgainstBuiltInSystem() { + Parameters respParam = ourClient + .operation() + .onType(ValueSet.class) + .named("validate-code") + .withParameter(Parameters.class, "code", new StringType("BRN")) + .andParameter("url", new StringType("http://hl7.org/fhir/ValueSet/v2-0487")) + .andParameter("system", new StringType("http://hl7.org/fhir/v2/0487")) + .useHttpGet() + .execute(); + + String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(respParam); + ourLog.info(resp); + + assertEquals("result", respParam.getParameter().get(0).getName()); + assertEquals(true, ((BooleanType) respParam.getParameter().get(0).getValue()).getValue().booleanValue()); + + assertEquals("message", respParam.getParameter().get(1).getName()); + assertThat(((StringType) respParam.getParameter().get(1).getValue()).getValue(), containsStringIgnoringCase("succeeded")); + + assertEquals("display", respParam.getParameter().get(2).getName()); + assertEquals("Burn", ((StringType) respParam.getParameter().get(2).getValue()).getValue()); } @AfterClass @@ -526,4 +482,38 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test { TestUtil.clearAllStaticFieldsForUnitTest(); } + public static CodeSystem createExternalCs(IFhirResourceDao theCodeSystemDao, IResourceTableDao theResourceTableDao, IHapiTerminologySvc theTermSvc, ServletRequestDetails theRequestDetails) { + CodeSystem codeSystem = new CodeSystem(); + codeSystem.setUrl(URL_MY_CODE_SYSTEM); + codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); + IIdType id = theCodeSystemDao.create(codeSystem, theRequestDetails).getId().toUnqualified(); + + ResourceTable table = theResourceTableDao.findOne(id.getIdPartAsLong()); + + TermCodeSystemVersion cs = new TermCodeSystemVersion(); + cs.setResource(table); + cs.setResourceVersionId(table.getVersion()); + + TermConcept parentA = new TermConcept(cs, "ParentA").setDisplay("Parent A"); + cs.getConcepts().add(parentA); + + TermConcept childAA = new TermConcept(cs, "childAA").setDisplay("Child AA"); + parentA.addChild(childAA, RelationshipTypeEnum.ISA); + + TermConcept childAAA = new TermConcept(cs, "childAAA").setDisplay("Child AAA"); + childAA.addChild(childAAA, RelationshipTypeEnum.ISA); + + TermConcept childAAB = new TermConcept(cs, "childAAB").setDisplay("Child AAB"); + childAA.addChild(childAAB, RelationshipTypeEnum.ISA); + + TermConcept childAB = new TermConcept(cs, "childAB").setDisplay("Child AB"); + parentA.addChild(childAB, RelationshipTypeEnum.ISA); + + TermConcept parentB = new TermConcept(cs, "ParentB").setDisplay("Parent B"); + cs.getConcepts().add(parentB); + + theTermSvc.storeNewCodeSystemVersion(table.getId(), URL_MY_CODE_SYSTEM, cs); + return codeSystem; + } + } diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 99b8f3473c3..4cca7e235fc 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -12,6 +12,21 @@ of changes to index tables when updating a resource with contents that only make minor changes + + In FHIR DSTU3 the + ValueSet/$expand?identifier=foo]]> + and + ValueSet/$validate-code?identifier=foo]]> + parameters were changed to + ValueSet/$expand?url=foo]]> + and + ValueSet/$validate-code?url=foo]]> + respectively, but the JPA server had not caught up. The + JPA DSTU3 server has been adjusted to accept either "identifier" + or "url" (with "url" taking precedence), and the JPA R4 server + has been changed to only accept "url". + Thanks to Avinash Shanbhag for reporting! +