Core library bump 6.3.11 (#5772)

* Bump to core 6.2.6 + fix compilation errors

* Fix signature error

* Error ordering

* WIP 1 Fixing failing tests

* Fix FhirInstanceValidatorR4Test

* Fix FhirInstanceValidatorR5Test

* Fix FhirInstanceValidatorR4BTest

* Fix FhirInstanceValidatorDstu3Test.testValidateBuiltInProfiles()

* WIP Fix FhirInstanceValidatorDstu3Test

* Fix isPrimitiveType

* Add placeholder narratives to ServerCapabilityStatement

* Fix QuestionnaireResponseValidatorR4Test

* Newline cleanup

* Fix QuestionnaireResponseValidatorDstu3Test

* Fix QuestionnaireResponseValidatorR5Test

* Increase expected error messages by two because VALIDATION_HL7_WG_NEEDED

New validation requirement as of 2023-09-16

* Add placeholder fix for Balp narrative

* Fix expected validation messages

* Fix more expected validation messages

* Don't generate a master IPS narrative

* Fix IPS generation tests expecting old composition narrative

* Update fhir core and clinical-reasoning

* Remove commented code

* Bump to core 6.2.16-SNAPSHOT

* Add missing methods

* Add missing methods 2

* Fix error codes

* Fix error code

* Fix failing tests for Unsupported method 2488

* Fix error text

* Fix another expected error message

* Apply spotless

* Fix error strings

* Add minimal implementation to fix failing test

* Fix error message

* Fix some validation tests (r4)

* Fix more R5 tests

* Update for changing API

* Fix some R4B test failures

* Fix android incompatibility

* Fix more tests

* Switch back to LF

* Fix more tests 2

* Fix R4 IPS generation use of relative references, switch to random UUID

* Fix missing codes and patient ID in IPS test

* Fix missing codes in IPS R4 Test 2

* Fix display value

* Fix display value

* Reorg wrapper issue collection; fixes errors with Balp and others

* Update for API changes

* Fix code set typo causing test failure

* Fix DiffProviderR4Test

* Fix RepositoryValidatingInterceptorHttpR4Test fails

due to stricter code validation

* More code fixes

* Don't expect an extra error.

* Use more specific logic for details tx code

* Catch expected error

* Clean up

* Account for HAPI isEnabledValidationForCodingsLogicalAnd cases

* Apply spotless

* Change outputs for en_US single code test

* Add missing system from code to pass validation

* Account for DSTU3 and R4 including different code systems for race

* Add expected loinc codes to test dao

* Add some codesystem support for test

* Bump core version

* WIP pass on a list of CodeValidationIssue from CodeValidationResults

* Re-use v2 and v3 data from r4 in r4b

* CodeSystems can be supported, but not have a resource

* Remove hack around unitsofmeasure + return false LookupCodeResult

* Clean up chatter.

* Update test cases, remove FIXME

* Stop returning before adding all issues to ValidationResults

* Update for changes in core API

* Add severity to code issues + return to unknown system support

* Use new CollectionUtils

* Fix more issue messages and orders + null in TermReadSvcImpl

* After checking valueSet, also check codeSystem

* On second thought, always check the codesystem

* Improve validation message

* Refactor

* Add error consistent with core validator results

* Decrement query counts for validation

* Improve code validation messages + don't miss invalid display on cs

* Fix expected messages (added code details)

* More expected message fixes

* Remove redundant text from diagnostics + match core exception handling

* Explicitly send tx passthrough messages no longer managed in core

* Apply spotless

* Add issue to code validation in TermReadSvcImpl

* Adjust indexes of expected errors now that TermReadSvc is reporting

* Bump to released core version

* Code cleanup: commented code

* More commented code cleanup

* Fix parameter names

* Use Set.of and List.of + fix duplicate values in set

* Revert animal sniffed breakage, make field private

* Add comments to describe disabled test

* Remove System.out chatter

* Fix javadoc generation for r5 structures module

* More comments and move disabled annotation

It was working when it left the shop.

* Move older changelog into 7.4.0 and create core update changelog

* Switch changelog type to change

* Bump HAPI version

* Add validation utils for FATAL issue severity

* Handle FATAL codeValidationIssue severity

* Fix test (validation throws more warnings)

* Bump to version 7.3.4-SNAPSHOT

* Bump to SNAPSHOT version of core + add necessary method implementations

* Add comments to explain R4 terminology resources in R4B

* Add test for Observation vital signs profile validation

* Try using default validatorPolicyAdvisor

* Return an empty set for fetchCanonicalResourceVersions

* Profile now gives more explicit error instead of valueSet

* Revert commit

* Add CodeValidationIssues and additional error info

* Do not return first successful match from codings. Check all.

+ adjust for extra errors.

* apply spotless

* Fix failing test, add comments re: invocations

* Fix test to expect more informative error

* Fix stray compilation errors from merge.

* Fix merge overwrite of validation messages and indices

* Fix merge overwrite of new validation results

* Use core release 6.3.11

* Update HAPI version to 7.3.5-SNAPSHOT

* Fix changelog

* Remove commented code

---------

Co-authored-by: James Agnew <jamesagnew@gmail.com>
Co-authored-by: volodymyr <volodymyr.korzh@smilecdr.com>
This commit is contained in:
dotasek 2024-06-12 12:24:26 -05:00 committed by GitHub
parent b39e2f8909
commit 0abbb1a4f4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
162 changed files with 2557 additions and 609 deletions

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -123,8 +123,10 @@ class DefaultProfileValidationSupportBundleStrategy implements IValidationSuppor
break; break;
case R4B: case R4B:
terminologyResources.add("/org/hl7/fhir/r4b/model/valueset/valuesets.xml"); terminologyResources.add("/org/hl7/fhir/r4b/model/valueset/valuesets.xml");
terminologyResources.add("/org/hl7/fhir/r4b/model/valueset/v2-tables.xml"); // For R4B we can re-use the same v2 and v3 files as R4, as these will not be updated and it will reduce
terminologyResources.add("/org/hl7/fhir/r4b/model/valueset/v3-codesystems.xml"); // duplication.
terminologyResources.add("/org/hl7/fhir/r4/model/valueset/v2-tables.xml");
terminologyResources.add("/org/hl7/fhir/r4/model/valueset/v3-codesystems.xml");
structureDefinitionResources.add("/org/hl7/fhir/r4b/model/profile/profiles-resources.xml"); structureDefinitionResources.add("/org/hl7/fhir/r4b/model/profile/profiles-resources.xml");
structureDefinitionResources.add("/org/hl7/fhir/r4b/model/profile/profiles-types.xml"); structureDefinitionResources.add("/org/hl7/fhir/r4b/model/profile/profiles-types.xml");
structureDefinitionResources.add("/org/hl7/fhir/r4b/model/profile/profiles-others.xml"); structureDefinitionResources.add("/org/hl7/fhir/r4b/model/profile/profiles-others.xml");

View File

@ -459,6 +459,58 @@ public interface IValidationSupport {
INFORMATION INFORMATION
} }
enum CodeValidationIssueCode {
NOT_FOUND,
CODE_INVALID,
INVALID,
OTHER
}
enum CodeValidationIssueCoding {
VS_INVALID,
NOT_FOUND,
NOT_IN_VS,
INVALID_CODE,
INVALID_DISPLAY,
OTHER
}
class CodeValidationIssue {
private final String myMessage;
private final IssueSeverity mySeverity;
private final CodeValidationIssueCode myCode;
private final CodeValidationIssueCoding myCoding;
public CodeValidationIssue(
String theMessage,
IssueSeverity mySeverity,
CodeValidationIssueCode theCode,
CodeValidationIssueCoding theCoding) {
this.myMessage = theMessage;
this.mySeverity = mySeverity;
this.myCode = theCode;
this.myCoding = theCoding;
}
public String getMessage() {
return myMessage;
}
public IssueSeverity getSeverity() {
return mySeverity;
}
public CodeValidationIssueCode getCode() {
return myCode;
}
public CodeValidationIssueCoding getCoding() {
return myCoding;
}
}
class ConceptDesignation { class ConceptDesignation {
private String myLanguage; private String myLanguage;
@ -634,6 +686,8 @@ public interface IValidationSupport {
private String myDisplay; private String myDisplay;
private String mySourceDetails; private String mySourceDetails;
private List<CodeValidationIssue> myCodeValidationIssues;
public CodeValidationResult() { public CodeValidationResult() {
super(); super();
} }
@ -717,6 +771,23 @@ public interface IValidationSupport {
return this; return this;
} }
public List<CodeValidationIssue> getCodeValidationIssues() {
if (myCodeValidationIssues == null) {
myCodeValidationIssues = new ArrayList<>();
}
return myCodeValidationIssues;
}
public CodeValidationResult setCodeValidationIssues(List<CodeValidationIssue> theCodeValidationIssues) {
myCodeValidationIssues = new ArrayList<>(theCodeValidationIssues);
return this;
}
public CodeValidationResult addCodeValidationIssue(CodeValidationIssue theCodeValidationIssue) {
getCodeValidationIssues().add(theCodeValidationIssue);
return this;
}
public boolean isOk() { public boolean isOk() {
return isNotBlank(myCode); return isNotBlank(myCode);
} }
@ -777,14 +848,18 @@ public interface IValidationSupport {
private final IBaseResource myValueSet; private final IBaseResource myValueSet;
private final String myError; private final String myError;
public ValueSetExpansionOutcome(String theError) { private boolean myErrorIsFromServer;
public ValueSetExpansionOutcome(String theError, boolean theErrorIsFromServer) {
myValueSet = null; myValueSet = null;
myError = theError; myError = theError;
myErrorIsFromServer = theErrorIsFromServer;
} }
public ValueSetExpansionOutcome(IBaseResource theValueSet) { public ValueSetExpansionOutcome(IBaseResource theValueSet) {
myValueSet = theValueSet; myValueSet = theValueSet;
myError = null; myError = null;
myErrorIsFromServer = false;
} }
public String getError() { public String getError() {
@ -794,6 +869,10 @@ public interface IValidationSupport {
public IBaseResource getValueSet() { public IBaseResource getValueSet() {
return myValueSet; return myValueSet;
} }
public boolean getErrorIsFromServer() {
return myErrorIsFromServer;
}
} }
class LookupCodeResult { class LookupCodeResult {

View File

@ -1,5 +1,5 @@
org.hl7.fhir.common.hapi.validation.support.InMemoryTerminologyServerValidationSupport.displayMismatch=Concept Display "{0}" does not match expected "{1}" org.hl7.fhir.common.hapi.validation.support.InMemoryTerminologyServerValidationSupport.displayMismatch=Concept Display "{0}" does not match expected "{1}" for ''{2}#{3}''
org.hl7.fhir.common.hapi.validation.support.CommonCodeSystemsTerminologyService.unknownCodeInSystem=Unknown code "{0}#{1}" org.hl7.fhir.common.hapi.validation.support.CommonCodeSystemsTerminologyService.unknownCodeInSystem=Unknown code "{0}#{1}"
org.hl7.fhir.common.hapi.validation.support.CommonCodeSystemsTerminologyService.invalidCodeInSystem=Code {0} is not valid for system: {1} org.hl7.fhir.common.hapi.validation.support.CommonCodeSystemsTerminologyService.invalidCodeInSystem=Code {0} is not valid for system: {1}

View File

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-bom</artifactId> <artifactId>hapi-fhir-bom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>HAPI FHIR BOM</name> <name>HAPI FHIR BOM</name>
@ -12,7 +12,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -38,7 +38,7 @@ public class ValidateCommandTest {
@Test @Test
public void testValidateLocalProfileDstu3() { public void testValidateLocalProfileDstu3() {
String resourcePath = ValidateCommandTest.class.getResource("/patient-uslab-example1.xml").getFile(); String resourcePath = ValidateCommandTest.class.getResource("/patient-uslab-example1-dstu3.xml").getFile();
App.main(new String[]{ App.main(new String[]{
"validate", "validate",
@ -49,7 +49,7 @@ public class ValidateCommandTest {
@Test @Test
public void testValidateLocalProfileR4() { public void testValidateLocalProfileR4() {
String resourcePath = ValidateCommandTest.class.getResource("/patient-uslab-example1.xml").getFile(); String resourcePath = ValidateCommandTest.class.getResource("/patient-uslab-example1-r4.xml").getFile();
ourLog.info(resourcePath); ourLog.info(resourcePath);
App.main(new String[]{ App.main(new String[]{

View File

@ -40,6 +40,7 @@
<extension url="http://hl7.org/fhir/StructureDefinition/us-core-race"> <extension url="http://hl7.org/fhir/StructureDefinition/us-core-race">
<valueCodeableConcept> <valueCodeableConcept>
<coding> <coding>
<system value="http://hl7.org/fhir/v3/Race"/>
<code value="2106-3"/> <code value="2106-3"/>
</coding> </coding>
</valueCodeableConcept> </valueCodeableConcept>
@ -47,6 +48,7 @@
<extension url="http://hl7.org/fhir/StructureDefinition/us-core-ethnicity"> <extension url="http://hl7.org/fhir/StructureDefinition/us-core-ethnicity">
<valueCodeableConcept> <valueCodeableConcept>
<coding> <coding>
<system value="http://hl7.org/fhir/v3/Ethnicity"/>
<code value="2135-2"/> <code value="2135-2"/>
</coding> </coding>
</valueCodeableConcept> </valueCodeableConcept>

View File

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<Patient xmlns="http://hl7.org/fhir">
<id value="patient-uslab-example1"/>
<text>
<status value="generated"/>
<div xmlns="http://www.w3.org/1999/xhtml">
<p>
<b>Generated Narrative with Details</b>
</p>
<p>
<b>id</b>
: patient-uslab-example1
</p>
<p>
<b>identifier</b>
: 18547545 (USUAL)
</p>
<p>
<b>name</b>
: Todd G. Lerr (OFFICIAL)
</p>
<p>
<b>gender</b>
: male
</p>
<p>
<b>birthDate</b>
: Jun 7, 2012
</p>
<p>
<b>deceased</b>
: false
</p>
<p>
<b>address</b>
: 123 North 102nd Street Apt 4d Harrisburg PA 17102 USA (HOME)
</p>
</div>
</text>
<extension url="http://hl7.org/fhir/StructureDefinition/us-core-race">
<valueCodeableConcept>
<coding>
<system value="http://terminology.hl7.org/CodeSystem/v3-Race"/>
<code value="2106-3"/>
</coding>
</valueCodeableConcept>
</extension>
<extension url="http://hl7.org/fhir/StructureDefinition/us-core-ethnicity">
<valueCodeableConcept>
<coding>
<system value="http://terminology.hl7.org/CodeSystem/v3-Ethnicity"/>
<code value="2135-2"/>
</coding>
</valueCodeableConcept>
</extension>
<!-- EH: limit to single identifier that orderer can match to patient system can be URL -->
<identifier>
<use value="usual"/>
<system value="urn:oid:2.16.840.1.113883.3.72.5.30.2"/>
<value value="18547545"/>
</identifier>
<!-- name use limited to official and anonymous -->
<name>
<use value="official"/>
<family value="Lerr"/>
<given value="Todd"/>
<given value="G."/>
<suffix value="Jr"/>
</name>
<!-- use FHIR code system for male / female -->
<gender value="male"/>
<birthDate value="2012-06-07"/>
<deceasedBoolean value="false"/>
<address>
<use value="home"/>
<line value="123 North 102nd Street"/>
<line value="Apt 4d"/>
<city value="Harrisburg"/>
<state value="PA"/>
<postalCode value="17102"/>
<country value="USA"/>
</address>
</Patient>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-cli</artifactId> <artifactId>hapi-fhir-cli</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -250,7 +250,8 @@ public class VersionCanonicalizer {
String packageUserData = (String) theResource.getUserData("package"); String packageUserData = (String) theResource.getUserData("package");
if (packageUserData != null) { if (packageUserData != null) {
retVal.setUserData("package", packageUserData); retVal.setUserData("package", packageUserData);
retVal.setSourcePackage(new PackageInformation(packageUserData, new Date())); retVal.setSourcePackage(new PackageInformation(
packageUserData, theResource.getStructureFhirVersionEnum().getFhirVersionString(), new Date()));
} }
return retVal; return retVal;
} }

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -0,0 +1,7 @@
---
type: fix
issue: 5559
title: "The IPS narrative generator previously created narratives for each `Composition.section.text` entry,
but also combined these section narratives into a single concatenated narrative for `Composition.text`. This
caused validation issues as the narratives then contained duplicate IDs, and also wasted space. This has
been removed."

View File

@ -0,0 +1,4 @@
---
type: change
issue: 5939
title: "This brings the org.hl7.fhir.core dependency to version 6.3.11."

View File

@ -11,7 +11,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -58,7 +58,7 @@ import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.util.IMetaTagSorter; import ca.uhn.fhir.util.IMetaTagSorter;
import ca.uhn.fhir.util.MetaUtil; import ca.uhn.fhir.util.MetaUtil;
import jakarta.annotation.Nullable; import jakarta.annotation.Nullable;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseCoding; import org.hl7.fhir.instance.model.api.IBaseCoding;

View File

@ -300,6 +300,9 @@ public class TermReadSvcImpl implements ITermReadSvc, IHasScheduledJobs {
@Override @Override
public boolean isCodeSystemSupported(ValidationSupportContext theValidationSupportContext, String theSystem) { public boolean isCodeSystemSupported(ValidationSupportContext theValidationSupportContext, String theSystem) {
if (isBlank(theSystem)) {
return false;
}
TermCodeSystemVersionDetails cs = getCurrentCodeSystemVersion(theSystem); TermCodeSystemVersionDetails cs = getCurrentCodeSystemVersion(theSystem);
return cs != null; return cs != null;
} }
@ -1040,8 +1043,8 @@ public class TermReadSvcImpl implements ITermReadSvc, IHasScheduledJobs {
} catch (InMemoryTerminologyServerValidationSupport.ExpansionCouldNotBeCompletedInternallyException e) { } catch (InMemoryTerminologyServerValidationSupport.ExpansionCouldNotBeCompletedInternallyException e) {
if (theExpansionOptions != null if (theExpansionOptions != null
&& !theExpansionOptions.isFailOnMissingCodeSystem() && !theExpansionOptions.isFailOnMissingCodeSystem()
&& e.getFailureType() // Code system is unknown, therefore NOT_FOUND
== InMemoryTerminologyServerValidationSupport.FailureType.UNKNOWN_CODE_SYSTEM) { && e.getCodeValidationIssue().getCoding() == CodeValidationIssueCoding.NOT_FOUND) {
return; return;
} }
throw new InternalErrorException(Msg.code(888) + e); throw new InternalErrorException(Msg.code(888) + e);
@ -2151,6 +2154,7 @@ public class TermReadSvcImpl implements ITermReadSvc, IHasScheduledJobs {
theCode, theCode,
theDisplay, theDisplay,
expectedDisplay, expectedDisplay,
theSystem,
systemVersion, systemVersion,
myStorageSettings.getIssueSeverityForCodeDisplayMismatch()); myStorageSettings.getIssueSeverityForCodeDisplayMismatch());
} }
@ -2181,10 +2185,16 @@ public class TermReadSvcImpl implements ITermReadSvc, IHasScheduledJobs {
private CodeValidationResult createFailureCodeValidationResult( private CodeValidationResult createFailureCodeValidationResult(
String theSystem, String theCode, String theCodeSystemVersion, String theAppend) { String theSystem, String theCode, String theCodeSystemVersion, String theAppend) {
String theMessage = "Unable to validate code " + theSystem + "#" + theCode + theAppend;
return new CodeValidationResult() return new CodeValidationResult()
.setSeverity(IssueSeverity.ERROR) .setSeverity(IssueSeverity.ERROR)
.setCodeSystemVersion(theCodeSystemVersion) .setCodeSystemVersion(theCodeSystemVersion)
.setMessage("Unable to validate code " + theSystem + "#" + theCode + theAppend); .setMessage(theMessage)
.addCodeValidationIssue(new CodeValidationIssue(
theMessage,
IssueSeverity.ERROR,
CodeValidationIssueCode.CODE_INVALID,
CodeValidationIssueCoding.INVALID_CODE));
} }
private List<TermValueSetConcept> findByValueSetResourcePidSystemAndCode( private List<TermValueSetConcept> findByValueSetResourcePidSystemAndCode(
@ -2800,6 +2810,7 @@ public class TermReadSvcImpl implements ITermReadSvc, IHasScheduledJobs {
theCode, theCode,
theDisplay, theDisplay,
code.getDisplay(), code.getDisplay(),
code.getSystem(),
code.getSystemVersion(), code.getSystemVersion(),
myStorageSettings.getIssueSeverityForCodeDisplayMismatch()); myStorageSettings.getIssueSeverityForCodeDisplayMismatch());
} }

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -3,7 +3,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -3,7 +3,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -3,9 +3,5 @@ This template generates a composite narrative for the Composition, incorporating
all of the section narratives into a single narrative. all of the section narratives into a single narrative.
*/--> */-->
<div xmlns:th="http://www.thymeleaf.org"> <div xmlns:th="http://www.thymeleaf.org">
<div th:each="section : ${resource.section}"> <h1>International Patient Summary Document</h1>
<h1 th:text="${section.title}"></h1>
<div th:utext="${section.text.getDivAsString()}">
</div>
</div>
</div> </div>

View File

@ -6,6 +6,7 @@ import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.ValidationSupportContext; import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings; import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.ips.api.IIpsGenerationStrategy; import ca.uhn.fhir.jpa.ips.api.IIpsGenerationStrategy;
import ca.uhn.fhir.jpa.ips.api.IpsContext;
import ca.uhn.fhir.jpa.ips.jpa.DefaultJpaIpsGenerationStrategy; import ca.uhn.fhir.jpa.ips.jpa.DefaultJpaIpsGenerationStrategy;
import ca.uhn.fhir.jpa.ips.provider.IpsOperationProvider; import ca.uhn.fhir.jpa.ips.provider.IpsOperationProvider;
import ca.uhn.fhir.jpa.model.util.JpaConstants; import ca.uhn.fhir.jpa.model.util.JpaConstants;
@ -21,12 +22,14 @@ import org.hl7.fhir.common.hapi.validation.support.NpmPackageValidationSupport;
import org.hl7.fhir.common.hapi.validation.support.ValidationSupportChain; import org.hl7.fhir.common.hapi.validation.support.ValidationSupportChain;
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator; import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.CodeSystem; import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.CodeableConcept; import org.hl7.fhir.r4.model.CodeableConcept;
import org.hl7.fhir.r4.model.Composition; import org.hl7.fhir.r4.model.Composition;
import org.hl7.fhir.r4.model.Condition; import org.hl7.fhir.r4.model.Condition;
import org.hl7.fhir.r4.model.DateTimeType; import org.hl7.fhir.r4.model.DateTimeType;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.Immunization; import org.hl7.fhir.r4.model.Immunization;
import org.hl7.fhir.r4.model.MedicationStatement; import org.hl7.fhir.r4.model.MedicationStatement;
import org.hl7.fhir.r4.model.Parameters; import org.hl7.fhir.r4.model.Parameters;
@ -43,8 +46,12 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -100,7 +107,7 @@ public class IpsGenerationR4Test extends BaseResourceProviderR4Test {
validateDocument(output); validateDocument(output);
assertEquals(117, output.getEntry().size()); assertEquals(117, output.getEntry().size());
String patientId = findFirstEntryResource(output, Patient.class, 1).getIdElement().toUnqualifiedVersionless().getValue(); String patientId = findFirstEntryResource(output, Patient.class, 1).getIdElement().toUnqualifiedVersionless().getValue();
assertEquals("Patient/f15d2419-fbff-464a-826d-0afe8f095771", patientId); assertThat(patientId).matches("urn:uuid:.*");
MedicationStatement medicationStatement = findFirstEntryResource(output, MedicationStatement.class, 2); MedicationStatement medicationStatement = findFirstEntryResource(output, MedicationStatement.class, 2);
assertEquals(patientId, medicationStatement.getSubject().getReference()); assertEquals(patientId, medicationStatement.getSubject().getReference());
assertNull(medicationStatement.getInformationSource().getReference()); assertNull(medicationStatement.getInformationSource().getReference());
@ -196,7 +203,7 @@ public class IpsGenerationR4Test extends BaseResourceProviderR4Test {
validateDocument(output); validateDocument(output);
assertEquals(7, output.getEntry().size()); assertEquals(7, output.getEntry().size());
String patientId = findFirstEntryResource(output, Patient.class, 1).getIdElement().toUnqualifiedVersionless().getValue(); String patientId = findFirstEntryResource(output, Patient.class, 1).getIdElement().toUnqualifiedVersionless().getValue();
assertEquals("Patient/5342998", patientId); assertThat(patientId).matches("urn:uuid:.*");
assertEquals(patientId, findEntryResource(output, Condition.class, 0, 2).getSubject().getReference()); assertEquals(patientId, findEntryResource(output, Condition.class, 0, 2).getSubject().getReference());
assertEquals(patientId, findEntryResource(output, Condition.class, 1, 2).getSubject().getReference()); assertEquals(patientId, findEntryResource(output, Condition.class, 1, 2).getSubject().getReference());
@ -243,9 +250,8 @@ public class IpsGenerationR4Test extends BaseResourceProviderR4Test {
ourLog.info("Output: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(output)); ourLog.info("Output: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(output));
Composition composition = findCompositionSectionByDisplay(output, "History of Immunization Narrative"); Composition composition = findCompositionSectionByDisplay(output, "History of Immunization Narrative");
// Should be newest first assertThat(composition.getText().getDivAsString()).isEqualTo(
assertThat(composition.getText().getDivAsString()).containsSubsequence( "<div xmlns=\"http://www.w3.org/1999/xhtml\"><h1>International Patient Summary Document</h1></div>"
"Vax 2015", "Vax 2010", "Vax 2005"
); );
List<String> resourceDates = output List<String> resourceDates = output
@ -303,7 +309,12 @@ public class IpsGenerationR4Test extends BaseResourceProviderR4Test {
@Bean @Bean
public IIpsGenerationStrategy ipsGenerationStrategy() { public IIpsGenerationStrategy ipsGenerationStrategy() {
return new DefaultJpaIpsGenerationStrategy(); return new DefaultJpaIpsGenerationStrategy() {
@Override
public IIdType massageResourceId(@Nullable IpsContext theIpsContext, @javax.annotation.Nonnull IBaseResource theResource) {
return IdType.newRandomUuid();
}
};
} }
@Bean @Bean
@ -341,6 +352,73 @@ public class IpsGenerationR4Test extends BaseResourceProviderR4Test {
* package. * package.
*/ */
private class IpsTerminologySvc implements IValidationSupport { private class IpsTerminologySvc implements IValidationSupport {
final Set<String> loincValueSetCodes = Set.of(
"60591-5",
"75326-9",
"94306-8"
);
final Set<String> snomedValueSetCodes = Set.of(
"14657009",
"255604002",
"38341003",
"1208807009"
);
final Set<String> loincCodes = Set.of(
"10160-0",
"11369-6",
"11450-4",
"14682-9",
"14933-6",
"1988-5",
"20570-8",
"2157-6",
"26444-0",
"26449-9",
"26464-8",
"26474-7",
"26484-6",
"26515-7",
"2823-3",
"28539-5",
"2951-2",
"29953-7",
"30428-7",
"30449-3",
"30954-2",
"31348-6",
"31627-3",
"32677-7",
"48765-2",
"62238-1",
"718-7",
"8061-4",
"8076-2",
"8091-1",
"8092-9",
"8093-7",
"8094-5",
"94500-6"
);
final Set<String> snomedCodes = Set.of(
// Tiny patient summary
"38341003",
"1208807009",
// Large patient summary
"10312003",
"385055001",
"318913001",
"90560007",
"1240581000000104",
"16217701000119102",
"72098002",
"260415000"
);
@Override @Override
public boolean isValueSetSupported(ValidationSupportContext theValidationSupportContext, String theValueSetUrl) { public boolean isValueSetSupported(ValidationSupportContext theValidationSupportContext, String theValueSetUrl) {
return true; return true;
@ -350,12 +428,40 @@ public class IpsGenerationR4Test extends BaseResourceProviderR4Test {
@Override @Override
public CodeValidationResult validateCodeInValueSet(ValidationSupportContext theValidationSupportContext, ConceptValidationOptions theOptions, String theCodeSystem, String theCode, String theDisplay, @Nonnull IBaseResource theValueSet) { public CodeValidationResult validateCodeInValueSet(ValidationSupportContext theValidationSupportContext, ConceptValidationOptions theOptions, String theCodeSystem, String theCode, String theDisplay, @Nonnull IBaseResource theValueSet) {
if ("http://loinc.org".equals(theCodeSystem)) { if ("http://loinc.org".equals(theCodeSystem)) {
if ("60591-5".equals(theCode)) { if (loincValueSetCodes.contains(theCode)) {
return new CodeValidationResult().setCode(theCode); return new CodeValidationResult().setCode(theCode);
} }
} }
if ("http://snomed.info/sct".equals(theCodeSystem)) { if ("http://snomed.info/sct".equals(theCodeSystem)) {
if ("14657009".equals(theCode) || "255604002".equals(theCode)) { if (snomedValueSetCodes.contains(theCode)) {
return new CodeValidationResult().setCode(theCode);
}
}
return null;
}
@Override
public boolean isCodeSystemSupported(ValidationSupportContext theValidationSupportContext, String theSystem) {
return true;
}
@Nullable
@Override
public CodeValidationResult validateCode(
ValidationSupportContext theValidationSupportContext,
ConceptValidationOptions theOptions,
String theCodeSystem,
String theCode,
String theDisplay,
String theValueSetUrl) {
if ("http://loinc.org".equals(theCodeSystem)) {
if (loincCodes.contains(theCode)) {
return new CodeValidationResult().setCode(theCode);
}
}
if ("http://snomed.info/sct".equals(theCodeSystem)) {
if (snomedCodes.contains(theCode)) {
return new CodeValidationResult().setCode(theCode); return new CodeValidationResult().setCode(theCode);
} }
} }
@ -374,6 +480,15 @@ public class IpsGenerationR4Test extends BaseResourceProviderR4Test {
cs.addConcept().setCode("no-known-allergies"); cs.addConcept().setCode("no-known-allergies");
return cs; return cs;
} }
if ("http://hl7.org/fhir/sid/cvx".equals(theSystem)) {
CodeSystem cs = new CodeSystem();
cs.setUrl("http://hl7.org/fhir/sid/cvx");
cs.setContent(CodeSystem.CodeSystemContentMode.COMPLETE);
cs.addConcept().setCode("208");
cs.addConcept().setCode("121");
cs.addConcept().setCode("141");
return cs;
}
return null; return null;
} }

View File

@ -171,9 +171,9 @@ public class IpsGeneratorSvcImplTest {
// Composition itself should also have a narrative // Composition itself should also have a narrative
String compositionNarrative = composition.getText().getDivAsString(); String compositionNarrative = composition.getText().getDivAsString();
ourLog.info("Composition narrative: {}", compositionNarrative); ourLog.info("Composition narrative: {}", compositionNarrative);
assertThat(compositionNarrative).contains("Allergies and Intolerances"); assertThat(compositionNarrative).isEqualTo(
assertThat(compositionNarrative).doesNotContain("Pregnancy"); "<div xmlns=\"http://www.w3.org/1999/xhtml\"><h1>International Patient Summary Document</h1></div>"
);
} }
@Test @Test

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -26,9 +26,9 @@ import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import jakarta.annotation.PostConstruct; import jakarta.annotation.PostConstruct;
import org.hl7.fhir.dstu3.context.IWorkerContext; import org.hl7.fhir.dstu3.context.IWorkerContext;
import org.hl7.fhir.dstu3.fhirpath.FHIRPathEngine;
import org.hl7.fhir.dstu3.hapi.ctx.HapiWorkerContext; import org.hl7.fhir.dstu3.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.dstu3.model.Base; import org.hl7.fhir.dstu3.model.Base;
import org.hl7.fhir.dstu3.utils.FHIRPathEngine;
import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBase;
import java.util.ArrayList; import java.util.ArrayList;

View File

@ -32,16 +32,16 @@ import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.PathEngineException; import org.hl7.fhir.exceptions.PathEngineException;
import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.r4.context.IWorkerContext; import org.hl7.fhir.r4.context.IWorkerContext;
import org.hl7.fhir.r4.fhirpath.ExpressionNode;
import org.hl7.fhir.r4.fhirpath.FHIRPathEngine;
import org.hl7.fhir.r4.fhirpath.FHIRPathUtilityClasses.FunctionDetails;
import org.hl7.fhir.r4.fhirpath.TypeDetails;
import org.hl7.fhir.r4.hapi.ctx.HapiWorkerContext; import org.hl7.fhir.r4.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.r4.model.Base; import org.hl7.fhir.r4.model.Base;
import org.hl7.fhir.r4.model.ExpressionNode;
import org.hl7.fhir.r4.model.IdType; import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.Resource; import org.hl7.fhir.r4.model.Resource;
import org.hl7.fhir.r4.model.ResourceType; import org.hl7.fhir.r4.model.ResourceType;
import org.hl7.fhir.r4.model.TypeDetails;
import org.hl7.fhir.r4.model.ValueSet; import org.hl7.fhir.r4.model.ValueSet;
import org.hl7.fhir.r4.utils.FHIRPathEngine;
import org.hl7.fhir.r4.utils.FHIRPathUtilityClasses.FunctionDetails;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -106,13 +106,16 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements
private final Map<String, Base> myResourceTypeToStub = Collections.synchronizedMap(new HashMap<>()); private final Map<String, Base> myResourceTypeToStub = Collections.synchronizedMap(new HashMap<>());
@Override @Override
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) public List<Base> resolveConstant(
FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant)
throws PathEngineException { throws PathEngineException {
return Collections.emptyList(); return Collections.emptyList();
} }
@Override @Override
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException { public TypeDetails resolveConstantType(
FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant)
throws PathEngineException {
return null; return null;
} }
@ -122,24 +125,33 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements
} }
@Override @Override
public FunctionDetails resolveFunction(String functionName) { public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
return null; return null;
} }
@Override @Override
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters) public TypeDetails checkFunction(
FHIRPathEngine engine,
Object appContext,
String functionName,
TypeDetails focus,
List<TypeDetails> parameters)
throws PathEngineException { throws PathEngineException {
return null; return null;
} }
@Override @Override
public List<Base> executeFunction( public List<Base> executeFunction(
Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) { FHIRPathEngine engine,
Object appContext,
List<Base> focus,
String functionName,
List<List<Base>> parameters) {
return null; return null;
} }
@Override @Override
public Base resolveReference(Object theAppContext, String theUrl, Base theRefContext) throws FHIRException { public Base resolveReference(FHIRPathEngine engine, Object theAppContext, String theUrl, Base refContext) {
Base retVal = (Base) BundleUtil.getReferenceInBundle(getContext(), theUrl, theAppContext); Base retVal = (Base) BundleUtil.getReferenceInBundle(getContext(), theUrl, theAppContext);
if (retVal != null) { if (retVal != null) {
return retVal; return retVal;
@ -187,12 +199,13 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements
} }
@Override @Override
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException { public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url)
throws FHIRException {
return false; return false;
} }
@Override @Override
public ValueSet resolveValueSet(Object appContext, String url) { public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
return null; return null;
} }
} }

View File

@ -32,16 +32,16 @@ import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.PathEngineException; import org.hl7.fhir.exceptions.PathEngineException;
import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.r4b.context.IWorkerContext; import org.hl7.fhir.r4b.context.IWorkerContext;
import org.hl7.fhir.r4b.fhirpath.ExpressionNode;
import org.hl7.fhir.r4b.fhirpath.FHIRPathEngine;
import org.hl7.fhir.r4b.fhirpath.FHIRPathUtilityClasses.FunctionDetails;
import org.hl7.fhir.r4b.fhirpath.TypeDetails;
import org.hl7.fhir.r4b.hapi.ctx.HapiWorkerContext; import org.hl7.fhir.r4b.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.r4b.model.Base; import org.hl7.fhir.r4b.model.Base;
import org.hl7.fhir.r4b.model.ExpressionNode;
import org.hl7.fhir.r4b.model.IdType; import org.hl7.fhir.r4b.model.IdType;
import org.hl7.fhir.r4b.model.Resource; import org.hl7.fhir.r4b.model.Resource;
import org.hl7.fhir.r4b.model.ResourceType; import org.hl7.fhir.r4b.model.ResourceType;
import org.hl7.fhir.r4b.model.TypeDetails;
import org.hl7.fhir.r4b.model.ValueSet; import org.hl7.fhir.r4b.model.ValueSet;
import org.hl7.fhir.r4b.utils.FHIRPathEngine;
import org.hl7.fhir.r4b.utils.FHIRPathUtilityClasses.FunctionDetails;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -106,13 +106,16 @@ public class SearchParamExtractorR4B extends BaseSearchParamExtractor implements
private final Map<String, Base> myResourceTypeToStub = Collections.synchronizedMap(new HashMap<>()); private final Map<String, Base> myResourceTypeToStub = Collections.synchronizedMap(new HashMap<>());
@Override @Override
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) public List<Base> resolveConstant(
FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant)
throws PathEngineException { throws PathEngineException {
return Collections.emptyList(); return Collections.emptyList();
} }
@Override @Override
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException { public TypeDetails resolveConstantType(
FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant)
throws PathEngineException {
return null; return null;
} }
@ -122,24 +125,33 @@ public class SearchParamExtractorR4B extends BaseSearchParamExtractor implements
} }
@Override @Override
public FunctionDetails resolveFunction(String functionName) { public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
return null; return null;
} }
@Override @Override
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters) public TypeDetails checkFunction(
FHIRPathEngine engine,
Object appContext,
String functionName,
TypeDetails focus,
List<TypeDetails> parameters)
throws PathEngineException { throws PathEngineException {
return null; return null;
} }
@Override @Override
public List<Base> executeFunction( public List<Base> executeFunction(
Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) { FHIRPathEngine engine,
Object appContext,
List<Base> focus,
String functionName,
List<List<Base>> parameters) {
return null; return null;
} }
@Override @Override
public Base resolveReference(Object theAppContext, String theUrl, Base refContext) throws FHIRException { public Base resolveReference(FHIRPathEngine engine, Object theAppContext, String theUrl, Base refContext) {
Base retVal = (Base) BundleUtil.getReferenceInBundle(getContext(), theUrl, theAppContext); Base retVal = (Base) BundleUtil.getReferenceInBundle(getContext(), theUrl, theAppContext);
if (retVal != null) { if (retVal != null) {
return retVal; return retVal;
@ -187,12 +199,13 @@ public class SearchParamExtractorR4B extends BaseSearchParamExtractor implements
} }
@Override @Override
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException { public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url)
throws FHIRException {
return false; return false;
} }
@Override @Override
public ValueSet resolveValueSet(Object appContext, String url) { public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
return null; return null;
} }
} }

View File

@ -31,16 +31,16 @@ import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.PathEngineException; import org.hl7.fhir.exceptions.PathEngineException;
import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.r5.context.IWorkerContext; import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.fhirpath.ExpressionNode;
import org.hl7.fhir.r5.fhirpath.FHIRPathEngine;
import org.hl7.fhir.r5.fhirpath.FHIRPathUtilityClasses.FunctionDetails;
import org.hl7.fhir.r5.fhirpath.TypeDetails;
import org.hl7.fhir.r5.hapi.ctx.HapiWorkerContext; import org.hl7.fhir.r5.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.r5.model.Base; import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.ExpressionNode;
import org.hl7.fhir.r5.model.IdType; import org.hl7.fhir.r5.model.IdType;
import org.hl7.fhir.r5.model.Resource; import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.ResourceType; import org.hl7.fhir.r5.model.ResourceType;
import org.hl7.fhir.r5.model.TypeDetails;
import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.utils.FHIRPathEngine;
import org.hl7.fhir.r5.utils.FHIRPathUtilityClasses.FunctionDetails;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -103,13 +103,16 @@ public class SearchParamExtractorR5 extends BaseSearchParamExtractor implements
private final Map<String, Base> myResourceTypeToStub = Collections.synchronizedMap(new HashMap<>()); private final Map<String, Base> myResourceTypeToStub = Collections.synchronizedMap(new HashMap<>());
@Override @Override
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) public List<Base> resolveConstant(
FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant)
throws PathEngineException { throws PathEngineException {
return Collections.emptyList(); return Collections.emptyList();
} }
@Override @Override
public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException { public TypeDetails resolveConstantType(
FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant)
throws PathEngineException {
return null; return null;
} }
@ -119,24 +122,33 @@ public class SearchParamExtractorR5 extends BaseSearchParamExtractor implements
} }
@Override @Override
public FunctionDetails resolveFunction(String functionName) { public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
return null; return null;
} }
@Override @Override
public TypeDetails checkFunction(Object appContext, String functionName, List<TypeDetails> parameters) public TypeDetails checkFunction(
FHIRPathEngine engine,
Object appContext,
String functionName,
TypeDetails focus,
List<TypeDetails> parameters)
throws PathEngineException { throws PathEngineException {
return null; return null;
} }
@Override @Override
public List<Base> executeFunction( public List<Base> executeFunction(
Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) { FHIRPathEngine engine,
Object appContext,
List<Base> focus,
String functionName,
List<List<Base>> parameters) {
return null; return null;
} }
@Override @Override
public Base resolveReference(Object appContext, String theUrl, Base refContext) throws FHIRException { public Base resolveReference(FHIRPathEngine engine, Object appContext, String theUrl, Base refContext) {
Base retVal = (Base) BundleUtil.getReferenceInBundle(getContext(), theUrl, appContext); Base retVal = (Base) BundleUtil.getReferenceInBundle(getContext(), theUrl, appContext);
if (retVal != null) { if (retVal != null) {
return retVal; return retVal;
@ -184,13 +196,19 @@ public class SearchParamExtractorR5 extends BaseSearchParamExtractor implements
} }
@Override @Override
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException { public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url)
throws FHIRException {
return false; return false;
} }
@Override @Override
public ValueSet resolveValueSet(Object theO, String theS) { public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
return null; return null;
} }
@Override
public boolean paramIsType(String name, int index) {
return false;
}
} }
} }

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -123,7 +123,6 @@ public class FhirResourceDaoDstu2ValidateTest extends BaseJpaDstu2Test {
Observation input = new Observation(); Observation input = new Observation();
String profileUri = "http://example.com/StructureDefinition/" + methodName; String profileUri = "http://example.com/StructureDefinition/" + methodName;
ResourceMetadataKeyEnum.PROFILES.put(input, Collections.singletonList(new IdDt(profileUri))); ResourceMetadataKeyEnum.PROFILES.put(input, Collections.singletonList(new IdDt(profileUri)));
input.addIdentifier().setSystem("http://acme").setValue("12345"); input.addIdentifier().setSystem("http://acme").setValue("12345");
input.getEncounter().setReference("http://foo.com/Encounter/9"); input.getEncounter().setReference("http://foo.com/Encounter/9");
input.setStatus(ObservationStatusEnum.FINAL); input.setStatus(ObservationStatusEnum.FINAL);
@ -137,7 +136,7 @@ public class FhirResourceDaoDstu2ValidateTest extends BaseJpaDstu2Test {
assertHasErrors(oo); assertHasErrors(oo);
String ooString = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo); String ooString = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo);
ourLog.info(ooString); ourLog.info(ooString);
assertThat(ooString).contains("Profile reference 'http://example.com/StructureDefinition/testValidateResourceContainingProfileDeclarationInvalid' has not been checked because it is unknown"); assertThat(ooString).contains("Profile reference 'http://example.com/StructureDefinition/testValidateResourceContainingProfileDeclarationInvalid' has not been checked because it could not be found");
} }
@Test @Test

View File

@ -102,7 +102,7 @@ public class FhirResourceDaoValueSetDstu2Test extends BaseJpaDstu2Test {
CodeableConceptDt codeableConcept = null; CodeableConceptDt codeableConcept = null;
IValidationSupport.CodeValidationResult result = myValueSetDao.validateCode(valueSetIdentifier, id, code, system, display, coding, codeableConcept, mySrd); IValidationSupport.CodeValidationResult result = myValueSetDao.validateCode(valueSetIdentifier, id, code, system, display, coding, codeableConcept, mySrd);
assertTrue(result.isOk()); assertTrue(result.isOk());
assertEquals("Concept Display \"Systolic blood pressure at First encounterXXXX\" does not match expected \"Systolic blood pressure at First encounter\" for in-memory expansion of ValueSet: http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2", result.getMessage()); assertEquals("Concept Display \"Systolic blood pressure at First encounterXXXX\" does not match expected \"Systolic blood pressure at First encounter\" for 'http://acme.org#11378-7' for in-memory expansion of ValueSet: http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2", result.getMessage());
assertEquals("Systolic blood pressure at First encounter", result.getDisplay()); assertEquals("Systolic blood pressure at First encounter", result.getDisplay());
assertEquals(IValidationSupport.IssueSeverity.WARNING, result.getSeverity()); assertEquals(IValidationSupport.IssueSeverity.WARNING, result.getSeverity());
} }

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -325,7 +325,7 @@ public class FhirResourceDaoDstu3ValidateTest extends BaseJpaDstu3Test {
assertHasErrors(oo); assertHasErrors(oo);
String outputString = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo); String outputString = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo);
ourLog.info(outputString); ourLog.info(outputString);
assertThat(outputString).contains("Profile reference 'http://example.com/StructureDefinition/testValidateResourceContainingProfileDeclarationInvalid' has not been checked because it is unknown"); assertThat(outputString).contains("Profile reference 'http://example.com/StructureDefinition/testValidateResourceContainingProfileDeclarationInvalid' has not been checked because it could not be found");
} }
@Test @Test

View File

@ -328,7 +328,7 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
try { try {
CodeableConcept codeableConcept = new CodeableConcept(); CodeableConcept codeableConcept = new CodeableConcept();
Coding codingCode = codeableConcept.addCoding(); Coding codingCode = codeableConcept.addCoding();
codingCode.setSystem(DeviceStatus.ACTIVE.toCode()); codingCode.setCode(DeviceStatus.ACTIVE.toCode());
codingCode.setSystem(DeviceStatus.ACTIVE.getSystem()); codingCode.setSystem(DeviceStatus.ACTIVE.getSystem());
Task task = new Task(); Task task = new Task();

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -75,7 +75,7 @@ public class JpaPersistedResourceValidationSupportFromValidationChainTest {
final ValidationResult validationResult = validator.validateWithResult(bundleWithBadLibrary); final ValidationResult validationResult = validator.validateWithResult(bundleWithBadLibrary);
assertEquals(10, validationResult.getMessages().stream().filter(errorMessagePredicate()).count()); assertEquals(12, validationResult.getMessages().stream().filter(errorMessagePredicate()).count());
} }
@Test @Test
@ -92,7 +92,7 @@ public class JpaPersistedResourceValidationSupportFromValidationChainTest {
final ValidationResult validationResult = validator.validateWithResult(bundleWithMeasureOnly ); final ValidationResult validationResult = validator.validateWithResult(bundleWithMeasureOnly );
assertEquals(8, validationResult.getMessages().stream().filter(errorMessagePredicate()).count()); assertEquals(10, validationResult.getMessages().stream().filter(errorMessagePredicate()).count());
} }
@Test @Test
@ -106,7 +106,7 @@ public class JpaPersistedResourceValidationSupportFromValidationChainTest {
final ValidationResult validationResult = validator.validateWithResult(bundleWithMeasureOnlyNoLibraryReference); final ValidationResult validationResult = validator.validateWithResult(bundleWithMeasureOnlyNoLibraryReference);
assertEquals(7, validationResult.getMessages().stream().filter(errorMessagePredicate()).count()); assertEquals(9, validationResult.getMessages().stream().filter(errorMessagePredicate()).count());
} }
@Test @Test

View File

@ -594,24 +594,24 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
fail(myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome())); fail(myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome()));
} }
myCaptureQueriesListener.logSelectQueriesForCurrentThread(); myCaptureQueriesListener.logSelectQueriesForCurrentThread();
assertEquals(14, myCaptureQueriesListener.getSelectQueriesForCurrentThread().size()); assertEquals(8, myCaptureQueriesListener.getSelectQueriesForCurrentThread().size());
assertEquals(0, myCaptureQueriesListener.getUpdateQueriesForCurrentThread().size()); assertEquals(0, myCaptureQueriesListener.getUpdateQueriesForCurrentThread().size());
assertEquals(0, myCaptureQueriesListener.getInsertQueriesForCurrentThread().size()); assertEquals(0, myCaptureQueriesListener.getInsertQueriesForCurrentThread().size());
assertEquals(0, myCaptureQueriesListener.getDeleteQueriesForCurrentThread().size()); assertEquals(0, myCaptureQueriesListener.getDeleteQueriesForCurrentThread().size());
assertEquals(12, myCaptureQueriesListener.getCommitCount()); assertEquals(6, myCaptureQueriesListener.getCommitCount());
// Validate again (should rely only on caches) // Validate again (should rely only on caches)
myCaptureQueriesListener.clear(); myCaptureQueriesListener.clear();
myObservationDao.validate(obs, null, null, null, null, null, null); myObservationDao.validate(obs, null, null, null, null, null, null);
myCaptureQueriesListener.logSelectQueriesForCurrentThread(); myCaptureQueriesListener.logSelectQueriesForCurrentThread();
assertEquals(6, myCaptureQueriesListener.getSelectQueriesForCurrentThread().size()); assertEquals(0, myCaptureQueriesListener.getSelectQueriesForCurrentThread().size());
myCaptureQueriesListener.logUpdateQueriesForCurrentThread(); myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
assertThat(myCaptureQueriesListener.getUpdateQueriesForCurrentThread()).isEmpty(); assertThat(myCaptureQueriesListener.getUpdateQueriesForCurrentThread()).isEmpty();
myCaptureQueriesListener.logInsertQueriesForCurrentThread(); myCaptureQueriesListener.logInsertQueriesForCurrentThread();
assertThat(myCaptureQueriesListener.getInsertQueriesForCurrentThread()).isEmpty(); assertThat(myCaptureQueriesListener.getInsertQueriesForCurrentThread()).isEmpty();
myCaptureQueriesListener.logDeleteQueriesForCurrentThread(); myCaptureQueriesListener.logDeleteQueriesForCurrentThread();
assertEquals(0, myCaptureQueriesListener.getDeleteQueriesForCurrentThread().size()); assertEquals(0, myCaptureQueriesListener.getDeleteQueriesForCurrentThread().size());
assertEquals(6, myCaptureQueriesListener.getCommitCount()); assertEquals(0, myCaptureQueriesListener.getCommitCount());
} }
/** /**

View File

@ -68,7 +68,6 @@ import static org.awaitility.Awaitility.await;
import static org.hl7.fhir.common.hapi.validation.support.CommonCodeSystemsTerminologyService.CURRENCIES_CODESYSTEM_URL; import static org.hl7.fhir.common.hapi.validation.support.CommonCodeSystemsTerminologyService.CURRENCIES_CODESYSTEM_URL;
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_LOW; import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_LOW;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
@ -133,7 +132,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
encoded = encode(oo); encoded = encode(oo);
ourLog.info(encoded); ourLog.info(encoded);
assertThat(oo.getIssue().size()).as(encoded).isEqualTo(1); assertThat(oo.getIssue().size()).as(encoded).isEqualTo(1);
assertThat(oo.getIssue().get(0).getDiagnostics()).contains("provided (http://cs#code99) is not in the value set"); assertThat(oo.getIssue().get(0).getDiagnostics()).contains("provided (http://cs#code99) was not found in the value set");
assertThat(oo.getIssue().get(0).getDiagnostics()).contains("Unknown code 'http://cs#code99' for in-memory expansion of ValueSet 'http://vs'"); assertThat(oo.getIssue().get(0).getDiagnostics()).contains("Unknown code 'http://cs#code99' for in-memory expansion of ValueSet 'http://vs'");
assertThat(oo.getIssueFirstRep().getSeverity()).as(encoded).isEqualTo(OperationOutcome.IssueSeverity.ERROR); assertThat(oo.getIssueFirstRep().getSeverity()).as(encoded).isEqualTo(OperationOutcome.IssueSeverity.ERROR);
@ -165,7 +164,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
encoded = encode(oo); encoded = encode(oo);
ourLog.info(encoded); ourLog.info(encoded);
assertThat(oo.getIssue()).hasSize(1); assertThat(oo.getIssue()).hasSize(1);
assertThat(oo.getIssueFirstRep().getDiagnostics()).contains("provided (http://cs#code99) is not in the value set"); assertThat(oo.getIssueFirstRep().getDiagnostics()).contains("provided (http://cs#code99) was not found in the value set");
assertThat(oo.getIssueFirstRep().getDiagnostics()).contains("Unknown code 'http://cs#code99' for in-memory expansion of ValueSet 'http://vs'"); assertThat(oo.getIssueFirstRep().getDiagnostics()).contains("Unknown code 'http://cs#code99' for in-memory expansion of ValueSet 'http://vs'");
assertEquals(OperationOutcome.IssueSeverity.ERROR, oo.getIssueFirstRep().getSeverity()); assertEquals(OperationOutcome.IssueSeverity.ERROR, oo.getIssueFirstRep().getSeverity());
} }
@ -202,7 +201,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
assertThat(oo.getIssue()).hasSize(2); assertThat(oo.getIssue()).hasSize(2);
assertThat(oo.getIssue().get(0).getDiagnostics()).contains("CodeSystem is unknown and can't be validated: http://cs for 'http://cs#code99'"); assertThat(oo.getIssue().get(0).getDiagnostics()).contains("CodeSystem is unknown and can't be validated: http://cs for 'http://cs#code99'");
assertEquals(OperationOutcome.IssueSeverity.WARNING, oo.getIssue().get(0).getSeverity()); assertEquals(OperationOutcome.IssueSeverity.WARNING, oo.getIssue().get(0).getSeverity());
assertThat(oo.getIssue().get(1).getDiagnostics()).contains("provided (http://cs#code99) is not in the value set 'ValueSet[http://vs]'"); assertThat(oo.getIssue().get(1).getDiagnostics()).contains("Unknown code 'http://cs#code99' for in-memory expansion of ValueSet 'http://vs'");
assertEquals(OperationOutcome.IssueSeverity.ERROR, oo.getIssue().get(1).getSeverity()); assertEquals(OperationOutcome.IssueSeverity.ERROR, oo.getIssue().get(1).getSeverity());
} }
@ -241,7 +240,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
encoded = encode(oo); encoded = encode(oo);
ourLog.info(encoded); ourLog.info(encoded);
assertThat(oo.getIssue()).hasSize(1); assertThat(oo.getIssue()).hasSize(1);
assertThat(oo.getIssue().get(0).getDiagnostics()).contains("provided (http://cs#code99) is not in the value set"); assertThat(oo.getIssue().get(0).getDiagnostics()).contains("provided (http://cs#code99) was not found in the value set");
assertEquals(OperationOutcome.IssueSeverity.ERROR, oo.getIssueFirstRep().getSeverity()); assertEquals(OperationOutcome.IssueSeverity.ERROR, oo.getIssueFirstRep().getSeverity());
} }
@ -335,19 +334,25 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
oo = validateAndReturnOutcome(obs, true); oo = validateAndReturnOutcome(obs, true);
encoded = encode(oo); encoded = encode(oo);
ourLog.info(encoded); ourLog.info(encoded);
assertThat(oo.getIssue()).hasSize(1); assertThat(oo.getIssue()).hasSize(2);
assertThat(oo.getIssue().get(0).getDiagnostics()).contains("provided (http://cs#code1) is not in the value set"); OperationOutcome.OperationOutcomeIssueComponent unableToExpandError = oo.getIssue().get(0);
assertThat(oo.getIssue().get(0).getDiagnostics()).contains("Failed to expand ValueSet 'http://vs' (in-memory). Could not validate code http://cs#code1"); assertThat(unableToExpandError.getDiagnostics()).contains("Unable to expand ValueSet because CodeSystem could not be found: http://cs");
assertThat(oo.getIssue().get(0).getDiagnostics()).contains("HAPI-0702: Unable to expand ValueSet because CodeSystem could not be found: http://cs");
assertEquals(OperationOutcome.IssueSeverity.ERROR, oo.getIssueFirstRep().getSeverity()); assertEquals(OperationOutcome.IssueSeverity.ERROR, oo.getIssueFirstRep().getSeverity());
assertEquals(27, ((IntegerType) oo.getIssue().get(0).getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-line").getValue()).getValue());
assertEquals(4, ((IntegerType) oo.getIssue().get(0).getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-col").getValue()).getValue()); OperationOutcome.OperationOutcomeIssueComponent notInValueSetError = oo.getIssue().get(1);
assertEquals("Terminology_TX_NoValid_12", ((StringType) oo.getIssue().get(0).getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/operationoutcome-message-id").getValue()).getValue()); assertThat(notInValueSetError.getDiagnostics()).contains("provided (http://cs#code1) was not found in the value set");
assertEquals(OperationOutcome.IssueType.PROCESSING, oo.getIssue().get(0).getCode()); assertThat(notInValueSetError.getDiagnostics()).contains("Failed to expand ValueSet 'http://vs' (in-memory). Could not validate code http://cs#code1");
assertEquals(OperationOutcome.IssueSeverity.ERROR, oo.getIssue().get(0).getSeverity()); assertThat(notInValueSetError.getDiagnostics()).contains("HAPI-0702: Unable to expand ValueSet because CodeSystem could not be found: http://cs");
assertThat(oo.getIssue().get(0).getLocation()).hasSize(2); assertEquals(OperationOutcome.IssueSeverity.ERROR, oo.getIssueFirstRep().getSeverity());
assertEquals("Observation.value.ofType(Quantity)", oo.getIssue().get(0).getLocation().get(0).getValue()); assertEquals(27, ((IntegerType) notInValueSetError.getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-line").getValue()).getValue());
assertEquals("Line[27] Col[4]", oo.getIssue().get(0).getLocation().get(1).getValue()); assertEquals(4, ((IntegerType) notInValueSetError.getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-col").getValue()).getValue());
assertEquals("Terminology_TX_NoValid_12", ((StringType) notInValueSetError.getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/operationoutcome-message-id").getValue()).getValue());
assertEquals(OperationOutcome.IssueType.PROCESSING, notInValueSetError.getCode());
assertEquals(OperationOutcome.IssueSeverity.ERROR, notInValueSetError.getSeverity());
assertThat(notInValueSetError.getLocation()).hasSize(2);
assertEquals("Observation.value.ofType(Quantity)", notInValueSetError.getLocation().get(0).getValue());
assertEquals("Line[27] Col[4]", notInValueSetError.getLocation().get(1).getValue());
} }
@ -507,7 +512,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
assertHasErrors(outcome); assertHasErrors(outcome);
String outcomeStr = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome); String outcomeStr = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome);
ourLog.info("Validation outcome: {}", outcomeStr); ourLog.info("Validation outcome: {}", outcomeStr);
assertThat(outcomeStr).contains("provided (http://unitsofmeasure.org#cm) is not in the value set"); assertThat(outcomeStr).contains("provided (http://unitsofmeasure.org#cm) was not found in the value set");
// Before, the VS wasn't pre-expanded. Try again with it pre-expanded // Before, the VS wasn't pre-expanded. Try again with it pre-expanded
runInTransaction(() -> { runInTransaction(() -> {
@ -535,7 +540,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
assertHasErrors(outcome); assertHasErrors(outcome);
outcomeStr = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome); outcomeStr = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome);
ourLog.info("Validation outcome: {}", outcomeStr); ourLog.info("Validation outcome: {}", outcomeStr);
assertThat(outcomeStr).contains("provided (http://unitsofmeasure.org#cm) is not in the value set"); assertThat(outcomeStr).contains("provided (http://unitsofmeasure.org#cm) was not found in the value set");
} }
@ -623,7 +628,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED); obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://loinc.org").setCode("non-existing-code").setDisplay("Display 3"); obs.getCode().getCodingFirstRep().setSystem("http://loinc.org").setCode("non-existing-code").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs); oo = validateAndReturnOutcome(obs);
assertThat(oo.getIssueFirstRep().getDiagnostics()).as(encode(oo)).isEqualTo("None of the codings provided are in the value set 'ValueSet[http://example.com/fhir/ValueSet/observation-vitalsignresult]' (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = http://loinc.org#non-existing-code)"); assertThat(oo.getIssue().get(1).getDiagnostics()).as(encode(oo)).isEqualTo("None of the codings provided are in the value set 'ValueSet[http://example.com/fhir/ValueSet/observation-vitalsignresult]' (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = http://loinc.org#non-existing-code)");
// Valid code with no system // Valid code with no system
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED); obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
@ -639,7 +644,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
// Code that exists but isn't in the valueset // Code that exists but isn't in the valueset
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED); obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://terminology.hl7.org/CodeSystem/observation-category").setCode("vital-signs").setDisplay("Display 3"); obs.getCode().getCodingFirstRep().setSystem("http://terminology.hl7.org/CodeSystem/observation-category").setCode("vital-signs").setDisplay("Vital Signs");
oo = validateAndReturnOutcome(obs); oo = validateAndReturnOutcome(obs);
assertThat(oo.getIssueFirstRep().getDiagnostics()).as(encode(oo)).isEqualTo("None of the codings provided are in the value set 'ValueSet[http://example.com/fhir/ValueSet/observation-vitalsignresult]' (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = http://terminology.hl7.org/CodeSystem/observation-category#vital-signs)"); assertThat(oo.getIssueFirstRep().getDiagnostics()).as(encode(oo)).isEqualTo("None of the codings provided are in the value set 'ValueSet[http://example.com/fhir/ValueSet/observation-vitalsignresult]' (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = http://terminology.hl7.org/CodeSystem/observation-category#vital-signs)");
@ -648,7 +653,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
obs.getCode().getCodingFirstRep().setSystem("http://loinc.org").setCode("CODE3").setDisplay("Display 3"); obs.getCode().getCodingFirstRep().setSystem("http://loinc.org").setCode("CODE3").setDisplay("Display 3");
obs.getCategoryFirstRep().addCoding().setSystem("http://terminology.hl7.org/CodeSystem/observation-category").setCode("FOO"); obs.getCategoryFirstRep().addCoding().setSystem("http://terminology.hl7.org/CodeSystem/observation-category").setCode("FOO");
oo = validateAndReturnOutcome(obs); oo = validateAndReturnOutcome(obs);
assertThat(oo.getIssueFirstRep().getDiagnostics()).as(encode(oo)).isEqualTo("Unknown code 'http://terminology.hl7.org/CodeSystem/observation-category#FOO' for in-memory expansion of ValueSet 'http://hl7.org/fhir/ValueSet/observation-category'"); assertThat(oo.getIssueFirstRep().getDiagnostics()).as(encode(oo)).isEqualTo("Unknown code 'http://terminology.hl7.org/CodeSystem/observation-category#FOO'");
// Make sure we're caching the validations as opposed to hitting the DB every time // Make sure we're caching the validations as opposed to hitting the DB every time
myCaptureQueriesListener.clear(); myCaptureQueriesListener.clear();
@ -931,7 +936,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
OperationOutcome oo = validateAndReturnOutcome(vs); OperationOutcome oo = validateAndReturnOutcome(vs);
ourLog.debug(myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo)); ourLog.debug(myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo));
assertEquals("The code '123' is not valid in the system https://bb", oo.getIssue().get(0).getDiagnostics()); assertEquals("The code '123' is not valid in the system https://bb (Validation failed)", oo.getIssue().get(0).getDiagnostics());
} }
@Test @Test
@ -986,7 +991,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
obs.getCode().getCodingFirstRep().setDisplay("Some Code"); obs.getCode().getCodingFirstRep().setDisplay("Some Code");
outcome = (OperationOutcome) myObservationDao.validate(obs, null, null, null, ValidationModeEnum.CREATE, "http://example.com/structuredefinition", mySrd).getOperationOutcome(); outcome = (OperationOutcome) myObservationDao.validate(obs, null, null, null, ValidationModeEnum.CREATE, "http://example.com/structuredefinition", mySrd).getOperationOutcome();
ourLog.debug("Outcome: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome)); ourLog.debug("Outcome: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
assertEquals("Unknown code in fragment CodeSystem 'http://example.com/codesystem#foo-foo' for in-memory expansion of ValueSet 'http://example.com/valueset'", outcome.getIssueFirstRep().getDiagnostics()); assertEquals("Unknown code in fragment CodeSystem 'http://example.com/codesystem#foo-foo'", outcome.getIssueFirstRep().getDiagnostics());
assertEquals(OperationOutcome.IssueSeverity.WARNING, outcome.getIssueFirstRep().getSeverity()); assertEquals(OperationOutcome.IssueSeverity.WARNING, outcome.getIssueFirstRep().getSeverity());
// Correct codesystem, Code in codesystem // Correct codesystem, Code in codesystem
@ -1077,7 +1082,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED); obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://loinc.org").setCode("non-existing-code").setDisplay("Display 3"); obs.getCode().getCodingFirstRep().setSystem("http://loinc.org").setCode("non-existing-code").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs); oo = validateAndReturnOutcome(obs);
assertThat(oo.getIssueFirstRep().getDiagnostics()).as(encode(oo)).isEqualTo("None of the codings provided are in the value set 'ValueSet[http://example.com/fhir/ValueSet/observation-vitalsignresult]' (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = http://loinc.org#non-existing-code)"); assertThat(oo.getIssue().get(2).getDiagnostics()).as(encode(oo)).isEqualTo("None of the codings provided are in the value set 'ValueSet[http://example.com/fhir/ValueSet/observation-vitalsignresult]' (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = http://loinc.org#non-existing-code)");
// Valid code with no system // Valid code with no system
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED); obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
@ -1089,20 +1094,20 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED); obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://foo").setCode("CODE3").setDisplay("Display 3"); obs.getCode().getCodingFirstRep().setSystem("http://foo").setCode("CODE3").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs); oo = validateAndReturnOutcome(obs);
assertThat(oo.getIssueFirstRep().getDiagnostics()).as(encode(oo)).isEqualTo("None of the codings provided are in the value set 'ValueSet[http://example.com/fhir/ValueSet/observation-vitalsignresult]' (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = http://foo#CODE3)"); assertThat(oo.getIssue().get(1).getDiagnostics()).as(encode(oo)).isEqualTo("None of the codings provided are in the value set 'ValueSet[http://example.com/fhir/ValueSet/observation-vitalsignresult]' (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = http://foo#CODE3)");
// Code that exists but isn't in the valueset // Code that exists but isn't in the valueset
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED); obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://terminology.hl7.org/CodeSystem/observation-category").setCode("vital-signs").setDisplay("Display 3"); obs.getCode().getCodingFirstRep().setSystem("http://terminology.hl7.org/CodeSystem/observation-category").setCode("vital-signs").setDisplay("Vital Signs");
oo = validateAndReturnOutcome(obs); oo = validateAndReturnOutcome(obs);
assertThat(oo.getIssueFirstRep().getDiagnostics()).as(encode(oo)).isEqualTo("None of the codings provided are in the value set 'ValueSet[http://example.com/fhir/ValueSet/observation-vitalsignresult]' (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = http://terminology.hl7.org/CodeSystem/observation-category#vital-signs)"); assertThat(oo.getIssue().get(1).getDiagnostics()).as(encode(oo)).isEqualTo("None of the codings provided are in the value set 'ValueSet[http://example.com/fhir/ValueSet/observation-vitalsignresult]' (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = http://terminology.hl7.org/CodeSystem/observation-category#vital-signs)");
// Invalid code in built-in VS/CS // Invalid code in built-in VS/CS
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED); obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://loinc.org").setCode("CODE3").setDisplay("Display 3"); obs.getCode().getCodingFirstRep().setSystem("http://loinc.org").setCode("CODE3").setDisplay("Display 3");
obs.getCategoryFirstRep().addCoding().setSystem("http://terminology.hl7.org/CodeSystem/observation-category").setCode("FOO"); obs.getCategoryFirstRep().addCoding().setSystem("http://terminology.hl7.org/CodeSystem/observation-category").setCode("FOO");
oo = validateAndReturnOutcome(obs); oo = validateAndReturnOutcome(obs);
assertThat(oo.getIssueFirstRep().getDiagnostics()).as(encode(oo)).isEqualTo("Unknown code 'http://terminology.hl7.org/CodeSystem/observation-category#FOO' for in-memory expansion of ValueSet 'http://hl7.org/fhir/ValueSet/observation-category'"); assertThat(oo.getIssueFirstRep().getDiagnostics()).as(encode(oo)).isEqualTo("Unknown code 'http://terminology.hl7.org/CodeSystem/observation-category#FOO'");
} }
@ -1214,8 +1219,8 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
OperationOutcome oo = validateAndReturnOutcome(obs); OperationOutcome oo = validateAndReturnOutcome(obs);
ourLog.debug(myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo)); ourLog.debug(myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo));
assertEquals("Error MY ERROR validating Coding: java.lang.NullPointerException: MY ERROR", oo.getIssueFirstRep().getDiagnostics()); assertEquals("Error MY ERROR validating CodeableConcept", oo.getIssueFirstRep().getDiagnostics());
assertEquals(OperationOutcome.IssueSeverity.ERROR, oo.getIssueFirstRep().getSeverity()); assertEquals(OperationOutcome.IssueSeverity.WARNING, oo.getIssueFirstRep().getSeverity());
} }
@Test @Test
@ -1366,7 +1371,9 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
TermCodeSystemVersion csv = new TermCodeSystemVersion(); TermCodeSystemVersion csv = new TermCodeSystemVersion();
csv.addConcept().setCode("bar").setDisplay("Bar Code"); csv.addConcept().setCode("bar").setDisplay("Bar Code");
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(codeSystem, csv, mySrd, Collections.emptyList(), Collections.emptyList()); IIdType updatedCsId = myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(codeSystem, csv, mySrd, Collections.emptyList(), Collections.emptyList());
// Validate a resource containing this codesystem in a field with an extendable binding // Validate a resource containing this codesystem in a field with an extendable binding
Patient patient = new Patient(); Patient patient = new Patient();
@ -1386,10 +1393,11 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
// It would be ok for this to produce 0 issues, or just an information message too // It would be ok for this to produce 0 issues, or just an information message too
assertEquals(2, OperationOutcomeUtil.getIssueCount(myFhirContext, oo)); assertEquals(2, OperationOutcomeUtil.getIssueCount(myFhirContext, oo));
assertThat(OperationOutcomeUtil.getFirstIssueDetails(myFhirContext, oo)).contains("None of the codings provided are in the value set 'IdentifierType'"); OperationOutcome.OperationOutcomeIssueComponent notInValueSetIssue = oo.getIssue().get(1);
assertThat(OperationOutcomeUtil.getFirstIssueDetails(myFhirContext, oo)).contains("a coding should come from this value set unless it has no suitable code (note that the validator cannot judge what is suitable) (codes = http://foo#bar)"); assertThat(notInValueSetIssue.getDiagnostics()).contains("None of the codings provided are in the value set 'IdentifierType'");
assertEquals(OperationOutcome.IssueSeverity.WARNING, oo.getIssue().get(1).getSeverity()); assertThat(notInValueSetIssue.getDiagnostics()).contains("a coding should come from this value set unless it has no suitable code (note that the validator cannot judge what is suitable) (codes = http://foo#bar)");
assertEquals("Concept Display \"not bar code\" does not match expected \"Bar Code\" for 'http://foo#bar'", oo.getIssue().get(1).getDiagnostics()); assertEquals(OperationOutcome.IssueSeverity.WARNING, notInValueSetIssue.getSeverity());
assertEquals("Concept Display \"not bar code\" does not match expected \"Bar Code\" for 'http://foo#bar'", oo.getIssue().get(0).getDiagnostics());
} }
private OperationOutcome doTestValidateResourceContainingProfileDeclaration(String methodName, EncodingEnum enc) throws IOException { private OperationOutcome doTestValidateResourceContainingProfileDeclaration(String methodName, EncodingEnum enc) throws IOException {
@ -1465,7 +1473,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
assertHasErrors(oo); assertHasErrors(oo);
String outputString = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo); String outputString = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo);
ourLog.info(outputString); ourLog.info(outputString);
assertThat(outputString).contains("Profile reference 'http://example.com/StructureDefinition/testValidateResourceContainingProfileDeclarationInvalid' has not been checked because it is unknown"); assertThat(outputString).contains("Profile reference 'http://example.com/StructureDefinition/testValidateResourceContainingProfileDeclarationInvalid' has not been checked because it could not be found");
} }
@Test @Test
@ -1498,7 +1506,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
assertHasErrors(oo); assertHasErrors(oo);
String outputString = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo); String outputString = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo);
ourLog.info(outputString); ourLog.info(outputString);
assertThat(outputString).contains("Profile reference 'http://example.com/StructureDefinition/testValidateResourceContainingProfileDeclarationInvalid' has not been checked because it is unknown"); assertThat(outputString).contains("Profile reference 'http://example.com/StructureDefinition/testValidateResourceContainingProfileDeclarationInvalid' has not been checked because it could not be found");
} }
@Test @Test
@ -1572,10 +1580,14 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
@Test @Test
void testValidateCommonCodes_Ucum_ErrorMessageIsPreserved() { void testValidateCommonCodes_Ucum_ErrorMessageIsPreserved() {
String loincCode = "1234";
addLoincCodeToCodeSystemDao(loincCode);
Observation input = new Observation(); Observation input = new Observation();
input.getText().setDiv(new XhtmlNode().setValue("<div>AA</div>")).setStatus(Narrative.NarrativeStatus.GENERATED); input.getText().setDiv(new XhtmlNode().setValue("<div>AA</div>")).setStatus(Narrative.NarrativeStatus.GENERATED);
input.setStatus(ObservationStatus.AMENDED); input.setStatus(ObservationStatus.AMENDED);
input.getCode().addCoding().setSystem("http://loinc.org").setCode("1234").setDisplay("FOO"); input.getCode().addCoding().setSystem("http://loinc.org").setCode(loincCode).setDisplay("FOO");
input.setValue(new Quantity( input.setValue(new Quantity(
null, null,
123, 123,
@ -1592,7 +1604,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
assertEquals(15, ((IntegerType) oo.getIssue().get(0).getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-line").getValue()).getValue()); assertEquals(15, ((IntegerType) oo.getIssue().get(0).getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-line").getValue()).getValue());
assertEquals(4, ((IntegerType) oo.getIssue().get(0).getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-col").getValue()).getValue()); assertEquals(4, ((IntegerType) oo.getIssue().get(0).getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-col").getValue()).getValue());
assertEquals("Terminology_PassThrough_TX_Message", ((StringType) oo.getIssue().get(0).getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/operationoutcome-message-id").getValue()).getValue()); assertEquals("Terminology_PassThrough_TX_Message", ((StringType) oo.getIssue().get(0).getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/operationoutcome-message-id").getValue()).getValue());
assertEquals("Error processing unit 'MG/DL': The unit 'DL' is unknown' at position 3 for 'http://unitsofmeasure.org#MG/DL'", oo.getIssue().get(0).getDiagnostics()); assertEquals("Error processing unit 'MG/DL': The unit 'DL' is unknown' at position 3 (for 'http://unitsofmeasure.org#MG/DL')", oo.getIssue().get(0).getDiagnostics());
assertEquals(OperationOutcome.IssueType.PROCESSING, oo.getIssue().get(0).getCode()); assertEquals(OperationOutcome.IssueType.PROCESSING, oo.getIssue().get(0).getCode());
assertEquals(OperationOutcome.IssueSeverity.ERROR, oo.getIssue().get(0).getSeverity()); assertEquals(OperationOutcome.IssueSeverity.ERROR, oo.getIssue().get(0).getSeverity());
assertThat(oo.getIssue().get(0).getLocation()).hasSize(2); assertThat(oo.getIssue().get(0).getLocation()).hasSize(2);
@ -1602,10 +1614,14 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
@Test @Test
void testValidateCommonCodes_Currency_ErrorMessageIsPreserved() { void testValidateCommonCodes_Currency_ErrorMessageIsPreserved() {
String loincCode = "1234";
addLoincCodeToCodeSystemDao(loincCode);
Observation input = new Observation(); Observation input = new Observation();
input.getText().setDiv(new XhtmlNode().setValue("<div>AA</div>")).setStatus(Narrative.NarrativeStatus.GENERATED); input.getText().setDiv(new XhtmlNode().setValue("<div>AA</div>")).setStatus(Narrative.NarrativeStatus.GENERATED);
input.setStatus(ObservationStatus.AMENDED); input.setStatus(ObservationStatus.AMENDED);
input.getCode().addCoding().setSystem("http://loinc.org").setCode("1234").setDisplay("FOO"); input.getCode().addCoding().setSystem("http://loinc.org").setCode(loincCode).setDisplay("FOO");
input.setValue(new Quantity( input.setValue(new Quantity(
null, null,
123, 123,
@ -1622,7 +1638,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
assertEquals(15, ((IntegerType) oo.getIssue().get(0).getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-line").getValue()).getValue()); assertEquals(15, ((IntegerType) oo.getIssue().get(0).getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-line").getValue()).getValue());
assertEquals(4, ((IntegerType) oo.getIssue().get(0).getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-col").getValue()).getValue()); assertEquals(4, ((IntegerType) oo.getIssue().get(0).getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-col").getValue()).getValue());
assertEquals("Terminology_PassThrough_TX_Message", ((StringType) oo.getIssue().get(0).getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/operationoutcome-message-id").getValue()).getValue()); assertEquals("Terminology_PassThrough_TX_Message", ((StringType) oo.getIssue().get(0).getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/operationoutcome-message-id").getValue()).getValue());
assertEquals("Unknown code 'urn:iso:std:iso:4217#blah' for 'urn:iso:std:iso:4217#blah'", oo.getIssue().get(0).getDiagnostics()); assertEquals("Unknown code 'urn:iso:std:iso:4217#blah'", oo.getIssue().get(0).getDiagnostics());
assertEquals(OperationOutcome.IssueType.PROCESSING, oo.getIssue().get(0).getCode()); assertEquals(OperationOutcome.IssueType.PROCESSING, oo.getIssue().get(0).getCode());
assertEquals(OperationOutcome.IssueSeverity.ERROR, oo.getIssue().get(0).getSeverity()); assertEquals(OperationOutcome.IssueSeverity.ERROR, oo.getIssue().get(0).getSeverity());
assertThat(oo.getIssue().get(0).getLocation()).hasSize(2); assertThat(oo.getIssue().get(0).getLocation()).hasSize(2);
@ -2064,6 +2080,8 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
codeElement.addType().setCode("CodeableConcept"); codeElement.addType().setCode("CodeableConcept");
codeElement.getBinding().setStrength(Enumerations.BindingStrength.REQUIRED); codeElement.getBinding().setStrength(Enumerations.BindingStrength.REQUIRED);
codeElement.getBinding().setValueSet("http://vs"); codeElement.getBinding().setValueSet("http://vs");
String encodedStructureDefinition = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(sd);
myStructureDefinitionDao.create(sd, new SystemRequestDetails()); myStructureDefinitionDao.create(sd, new SystemRequestDetails());
CodeSystem cs = new CodeSystem(); CodeSystem cs = new CodeSystem();
@ -2073,12 +2091,17 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
cs.addConcept() cs.addConcept()
.setCode("8302-2") .setCode("8302-2")
.setDisplay("Body Height"); .setDisplay("Body Height");
String encodedCodeSystem = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(cs);
myCodeSystemDao.create(cs, new SystemRequestDetails()); myCodeSystemDao.create(cs, new SystemRequestDetails());
ValueSet vs = new ValueSet(); ValueSet vs = new ValueSet();
vs.setUrl("http://vs"); vs.setUrl("http://vs");
vs.setStatus(Enumerations.PublicationStatus.ACTIVE); vs.setStatus(Enumerations.PublicationStatus.ACTIVE);
vs.getCompose().addInclude().setSystem("http://cs"); vs.getCompose().addInclude().setSystem("http://cs");
String encodedValueSet = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(vs);
myValueSetDao.create(vs, new SystemRequestDetails()); myValueSetDao.create(vs, new SystemRequestDetails());
if (thePreCalculateExpansion) { if (thePreCalculateExpansion) {
@ -2099,8 +2122,8 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
obs.setSubject(new Reference("Patient/123")); obs.setSubject(new Reference("Patient/123"));
obs.setValue(new Quantity(null, 123, "http://unitsofmeasure.org", "[in_i]", "in")); obs.setValue(new Quantity(null, 123, "http://unitsofmeasure.org", "[in_i]", "in"));
String encoded = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs); String encodedResource = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs);
MethodOutcome outcome = myObservationDao.validate(obs, null, encoded, EncodingEnum.JSON, ValidationModeEnum.CREATE, null, new SystemRequestDetails()); MethodOutcome outcome = myObservationDao.validate(obs, null, encodedResource, EncodingEnum.JSON, ValidationModeEnum.CREATE, null, new SystemRequestDetails());
OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome(); OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome();
ourLog.info("Outcome: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo).replace("\"resourceType\"", "\"resType\"")); ourLog.info("Outcome: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo).replace("\"resourceType\"", "\"resType\""));
@ -2111,7 +2134,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
assertThat(oo.getIssue()).hasSize(2); assertThat(oo.getIssue()).hasSize(2);
badDisplayIssue = oo.getIssue().get(1); badDisplayIssue = oo.getIssue().get(1);
OperationOutcome.OperationOutcomeIssueComponent noGoodCodings = oo.getIssue().get(0); OperationOutcome.OperationOutcomeIssueComponent noGoodCodings = oo.getIssue().get(1);
assertEquals("error", noGoodCodings.getSeverity().toCode()); assertEquals("error", noGoodCodings.getSeverity().toCode());
assertEquals("None of the codings provided are in the value set 'ValueSet[http://vs]' (http://vs), and a coding from this value set is required) (codes = http://cs#8302-2)", noGoodCodings.getDiagnostics()); assertEquals("None of the codings provided are in the value set 'ValueSet[http://vs]' (http://vs), and a coding from this value set is required) (codes = http://cs#8302-2)", noGoodCodings.getDiagnostics());
@ -2160,18 +2183,42 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
@Test @Test
public void testKnownCodeSystemUnknownValueSetUri() { public void testKnownCodeSystemUnknownValueSetUri() {
CodeSystem cs = new CodeSystem(); String loincCode = "10013-1";
cs.setUrl(ITermLoaderSvc.LOINC_URI);
cs.setContent(CodeSystem.CodeSystemContentMode.COMPLETE);
cs.addConcept().setCode("10013-1");
cs.setId(LOINC_LOW);
myCodeSystemDao.update(cs);
IValidationSupport.CodeValidationResult result = myValueSetDao.validateCode(new UriType("http://fooVs"), null, new StringType("10013-1"), new StringType(ITermLoaderSvc.LOINC_URI), null, null, null, mySrd); addLoincCodeToCodeSystemDao(loincCode);
IValidationSupport.CodeValidationResult result = myValueSetDao.validateCode(new UriType("http://fooVs"), null, new StringType(loincCode), new StringType(ITermLoaderSvc.LOINC_URI), null, null, null, mySrd);
assertFalse(result.isOk()); assertFalse(result.isOk());
assertEquals("Validator is unable to provide validation for 10013-1#http://loinc.org - Unknown or unusable ValueSet[http://fooVs]", result.getMessage()); assertEquals("Validator is unable to provide validation for 10013-1#http://loinc.org - Unknown or unusable ValueSet[http://fooVs]", result.getMessage());
} }
private void addLoincCodeToCodeSystemDao(String loincCode) {
CodeSystem cs = new CodeSystem();
cs.setUrl(ITermLoaderSvc.LOINC_URI);
cs.setContent(CodeSystem.CodeSystemContentMode.COMPLETE);
cs.addConcept().setCode(loincCode);
cs.setId(LOINC_LOW);
myCodeSystemDao.update(cs);
}
@Test
public void testValidateObservationWithVitalSignsLoincCode() {
Observation obs = new Observation();
obs.setStatus(ObservationStatus.FINAL);
obs.setCode(
new CodeableConcept().addCoding(
new Coding().setSystem("http://loinc.org").setCode("8302-2").setDisplay("Body height")
));
obs.getSubject().setReference("Patient/A");
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getText().getDiv().setValue("<div>hello</div>");
obs.setEffective(new DateTimeType("2020-01-01"));
obs.setValue(new Quantity().setUnit("cm").setValue(51));
OperationOutcome oo = validateAndReturnOutcome(obs);
assertHasNoErrors(oo);
}
} }

View File

@ -343,7 +343,7 @@ public class FhirResourceDaoR4ValueSetTest extends BaseJpaR4Test {
IValidationSupport.CodeValidationResult result = myValueSetDao.validateCode(valueSetIdentifier, id, code, system, display, coding, codeableConcept, mySrd); IValidationSupport.CodeValidationResult result = myValueSetDao.validateCode(valueSetIdentifier, id, code, system, display, coding, codeableConcept, mySrd);
assertTrue(result.isOk()); assertTrue(result.isOk());
assertEquals("Systolic blood pressure at First encounter", result.getDisplay()); assertEquals("Systolic blood pressure at First encounter", result.getDisplay());
assertEquals("Concept Display \"Systolic blood pressure at First encounterXXXX\" does not match expected \"Systolic blood pressure at First encounter\" for in-memory expansion of ValueSet: http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2", result.getMessage()); assertEquals("Concept Display \"Systolic blood pressure at First encounterXXXX\" does not match expected \"Systolic blood pressure at First encounter\" for 'http://acme.org#11378-7' for in-memory expansion of ValueSet: http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2", result.getMessage());
} }
@Test @Test

View File

@ -49,6 +49,7 @@ public class RepositoryValidatingInterceptorHttpR4Test extends BaseJpaR4Test {
@Test @Test
public void testValidationIsSkippedOnAutoCreatedPlaceholderReferencesIfConfiguredToDoSo() { public void testValidationIsSkippedOnAutoCreatedPlaceholderReferencesIfConfiguredToDoSo() {
createLocalCsAndVs();
List<IRepositoryValidatingRule> rules = newRuleBuilder() List<IRepositoryValidatingRule> rules = newRuleBuilder()
.forResourcesOfType("Observation") .forResourcesOfType("Observation")
.requireValidationToDeclaredProfiles() .requireValidationToDeclaredProfiles()
@ -56,7 +57,7 @@ public class RepositoryValidatingInterceptorHttpR4Test extends BaseJpaR4Test {
myValInterceptor.setRules(rules); myValInterceptor.setRules(rules);
Observation obs = new Observation(); Observation obs = new Observation();
obs.getCode().addCoding().setSystem("http://foo").setCode("123").setDisplay("help im a bug"); obs.getCode().addCoding().setSystem("http://example.com/my_code_system").setCode("A").setDisplay("Code A");
obs.setStatus(Observation.ObservationStatus.AMENDED); obs.setStatus(Observation.ObservationStatus.AMENDED);
MethodOutcome outcome = myRestfulServerExtension MethodOutcome outcome = myRestfulServerExtension
@ -68,11 +69,12 @@ public class RepositoryValidatingInterceptorHttpR4Test extends BaseJpaR4Test {
String operationOutcomeEncoded = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome.getOperationOutcome()); String operationOutcomeEncoded = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome.getOperationOutcome());
ourLog.info("Outcome: {}", operationOutcomeEncoded); ourLog.info("Outcome: {}", operationOutcomeEncoded);
assertThat(operationOutcomeEncoded).contains("All observations should have a subject"); assertThat(operationOutcomeEncoded).contains("In general, all observations should have a subject");
} }
@Test @Test
public void testValidationOutcomeAddedToRequestResponse() { public void testValidationOutcomeAddedToRequestResponse() {
createLocalCsAndVs();
List<IRepositoryValidatingRule> rules = newRuleBuilder() List<IRepositoryValidatingRule> rules = newRuleBuilder()
.forResourcesOfType("Observation") .forResourcesOfType("Observation")
.requireValidationToDeclaredProfiles() .requireValidationToDeclaredProfiles()
@ -81,7 +83,7 @@ public class RepositoryValidatingInterceptorHttpR4Test extends BaseJpaR4Test {
myValInterceptor.setRules(rules); myValInterceptor.setRules(rules);
Observation obs = new Observation(); Observation obs = new Observation();
obs.getCode().addCoding().setSystem("http://foo").setCode("123").setDisplay("help im a bug"); obs.getCode().addCoding().setSystem("http://example.com/my_code_system").setCode("A").setDisplay("Code A");
obs.setStatus(Observation.ObservationStatus.AMENDED); obs.setStatus(Observation.ObservationStatus.AMENDED);
MethodOutcome outcome = myRestfulServerExtension MethodOutcome outcome = myRestfulServerExtension
@ -93,7 +95,7 @@ public class RepositoryValidatingInterceptorHttpR4Test extends BaseJpaR4Test {
String operationOutcomeEncoded = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome.getOperationOutcome()); String operationOutcomeEncoded = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome.getOperationOutcome());
ourLog.info("Outcome: {}", operationOutcomeEncoded); ourLog.info("Outcome: {}", operationOutcomeEncoded);
assertThat(operationOutcomeEncoded).contains("All observations should have a subject"); assertThat(operationOutcomeEncoded).contains("In general, all observations should have a subject");
} }

View File

@ -64,7 +64,7 @@ public class ValidationMessageSuppressingInterceptorTest extends BaseResourcePro
assertHasWarnings(oo); assertHasWarnings(oo);
String encode = encode(oo); String encode = encode(oo);
ourLog.info(encode); ourLog.info(encode);
assertThat(encode).contains("All observations should have a performer"); assertThat(encode).contains("In general, all observations should have a performer");
} }
@Test @Test
@ -92,13 +92,16 @@ public class ValidationMessageSuppressingInterceptorTest extends BaseResourcePro
} catch (UnprocessableEntityException e) { } catch (UnprocessableEntityException e) {
String encode = encode(e.getOperationOutcome()); String encode = encode(e.getOperationOutcome());
ourLog.info(encode); ourLog.info(encode);
assertThat(encode).contains("Unknown code 'http://loinc.org#59408-5'"); assertThat(encode).contains("Slice 'Observation.code.coding:PulseOx': a matching slice is required, but not found");
} }
} }
// With suppression // With suppression
ValidationMessageSuppressingInterceptor interceptor = new ValidationMessageSuppressingInterceptor(); ValidationMessageSuppressingInterceptor interceptor = new ValidationMessageSuppressingInterceptor();
interceptor.addMessageSuppressionPatterns("Unknown code 'http://loinc.org#59408-5'"); interceptor.addMessageSuppressionPatterns("Unable to validate code http://loinc.org#not-a-real-code - Code is not found in CodeSystem: http://loinc.org",
"Slice 'Observation.code.coding:PulseOx': a matching slice is required, but not found (from http://hl7.org/fhir/us/core/StructureDefinition/us-core-pulse-oximetry|3.1.1)",
"This element does not match any known slice defined in the profile http://hl7.org/fhir/us/core/StructureDefinition/us-core-pulse-oximetry|3.1.1");
myInterceptorRegistry.registerInterceptor(interceptor); myInterceptorRegistry.registerInterceptor(interceptor);
{ {
Observation inputObs = loadResource(myFhirContext, Observation.class, "/r4/uscore/observation-pulseox.json"); Observation inputObs = loadResource(myFhirContext, Observation.class, "/r4/uscore/observation-pulseox.json");

View File

@ -47,8 +47,8 @@ public class DiffProviderR4Test extends BaseResourceProviderR4Test {
assertEquals("replace", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 0, "operation", "type")); assertEquals("replace", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 0, "operation", "type"));
assertEquals("Patient.text.div", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 0, "operation", "path")); assertEquals("Patient.text.div", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 0, "operation", "path"));
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\"><table class=\"hapiPropertyTable\"><tbody></tbody></table></div>", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 0, "operation", "previousValue")); assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\"><table class=\"hapiPropertyTable\"><tbody/></table></div>", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 0, "operation", "previousValue"));
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\"><div class=\"hapiHeaderText\"><b>SMITH </b></div><table class=\"hapiPropertyTable\"><tbody></tbody></table></div>", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 0, "operation", "value")); assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\"><div class=\"hapiHeaderText\"><b>SMITH </b></div><table class=\"hapiPropertyTable\"><tbody/></table></div>", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 0, "operation", "value"));
assertEquals("insert", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 1, "operation", "type")); assertEquals("insert", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 1, "operation", "type"));
assertEquals("Patient.name", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 1, "operation", "path")); assertEquals("Patient.name", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 1, "operation", "path"));
@ -86,8 +86,8 @@ public class DiffProviderR4Test extends BaseResourceProviderR4Test {
assertEquals("replace", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 2, "operation", "type")); assertEquals("replace", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 2, "operation", "type"));
assertEquals("Patient.text.div", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 2, "operation", "path")); assertEquals("Patient.text.div", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 2, "operation", "path"));
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\"><table class=\"hapiPropertyTable\"><tbody></tbody></table></div>", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 2, "operation", "previousValue")); assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\"><table class=\"hapiPropertyTable\"><tbody/></table></div>", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 2, "operation", "previousValue"));
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\"><div class=\"hapiHeaderText\"><b>SMITH </b></div><table class=\"hapiPropertyTable\"><tbody></tbody></table></div>", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 2, "operation", "value")); assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\"><div class=\"hapiHeaderText\"><b>SMITH </b></div><table class=\"hapiPropertyTable\"><tbody/></table></div>", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 2, "operation", "value"));
assertEquals("insert", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 3, "operation", "type")); assertEquals("insert", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 3, "operation", "type"));
assertEquals("Patient.name", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 3, "operation", "path")); assertEquals("Patient.name", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 3, "operation", "path"));

View File

@ -573,7 +573,7 @@ public class ResourceProviderR4CodeSystemTest extends BaseResourceProviderR4Test
ourLog.info(resp); ourLog.info(resp);
assertTrue(((BooleanType) respParam.getParameter().get(0).getValue()).booleanValue()); assertTrue(((BooleanType) respParam.getParameter().get(0).getValue()).booleanValue());
assertEquals("Concept Display \"Old Systolic blood pressure.inspiration - expiration\" does not match expected \"Systolic blood pressure.inspiration - expiration\"", ((StringType) respParam.getParameter().get(1).getValue()).getValueAsString()); assertEquals("Concept Display \"Old Systolic blood pressure.inspiration - expiration\" does not match expected \"Systolic blood pressure.inspiration - expiration\" for 'http://acme.org#8452-5'", ((StringType) respParam.getParameter().get(1).getValue()).getValueAsString());
} }
@Test @Test

View File

@ -1,11 +1,5 @@
package ca.uhn.fhir.jpa.provider.r4; package ca.uhn.fhir.jpa.provider.r4;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertFalse;
import ca.uhn.fhir.context.RuntimeSearchParam; import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.i18n.HapiLocalizer; import ca.uhn.fhir.i18n.HapiLocalizer;
import ca.uhn.fhir.i18n.Msg; import ca.uhn.fhir.i18n.Msg;
@ -203,8 +197,16 @@ import static ca.uhn.fhir.rest.param.BaseParamWithPrefix.MSG_PREFIX_INVALID_FORM
import static ca.uhn.fhir.util.TestUtil.sleepAtLeast; import static ca.uhn.fhir.util.TestUtil.sleepAtLeast;
import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@SuppressWarnings("Duplicates") @SuppressWarnings("Duplicates")
@ -2108,7 +2110,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
String respString = IOUtils.toString(resp.getEntity().getContent(), Charsets.UTF_8); String respString = IOUtils.toString(resp.getEntity().getContent(), Charsets.UTF_8);
ourLog.debug(respString); ourLog.debug(respString);
assertEquals(200, resp.getStatusLine().getStatusCode()); assertEquals(200, resp.getStatusLine().getStatusCode());
assertThat(respString).contains("Profile reference 'http://foo/structuredefinition/myprofile' has not been checked because it is unknown"); assertThat(respString).contains("Profile reference 'http://foo/structuredefinition/myprofile' has not been checked because it could not be found");
} }
} }

View File

@ -1642,7 +1642,7 @@ public class ValueSetExpansionR4Test extends BaseTermR4Test implements IValueSet
assertTrue(outcome.isOk()); assertTrue(outcome.isOk());
assertEquals("28571000087109", outcome.getCode()); assertEquals("28571000087109", outcome.getCode());
assertEquals("MODERNA COVID-19 mRNA-1273", outcome.getDisplay()); assertEquals("MODERNA COVID-19 mRNA-1273", outcome.getDisplay());
assertEquals("Concept Display \"BLAH\" does not match expected \"MODERNA COVID-19 mRNA-1273\" for in-memory expansion of ValueSet: http://ehealthontario.ca/fhir/ValueSet/vaccinecode", outcome.getMessage()); assertEquals("Concept Display \"BLAH\" does not match expected \"MODERNA COVID-19 mRNA-1273\" for 'http://snomed.info/sct#28571000087109' for in-memory expansion of ValueSet: http://ehealthontario.ca/fhir/ValueSet/vaccinecode", outcome.getMessage());
assertEquals("Code was validated against in-memory expansion of ValueSet: http://ehealthontario.ca/fhir/ValueSet/vaccinecode", outcome.getSourceDetails()); assertEquals("Code was validated against in-memory expansion of ValueSet: http://ehealthontario.ca/fhir/ValueSet/vaccinecode", outcome.getSourceDetails());
assertEquals("0.17", outcome.getCodeSystemVersion()); assertEquals("0.17", outcome.getCodeSystemVersion());
@ -1689,7 +1689,7 @@ public class ValueSetExpansionR4Test extends BaseTermR4Test implements IValueSet
assertEquals("28571000087109", outcome.getCode()); assertEquals("28571000087109", outcome.getCode());
assertEquals("MODERNA COVID-19 mRNA-1273", outcome.getDisplay()); assertEquals("MODERNA COVID-19 mRNA-1273", outcome.getDisplay());
assertEquals("0.17", outcome.getCodeSystemVersion()); assertEquals("0.17", outcome.getCodeSystemVersion());
assertEquals("Concept Display \"BLAH\" does not match expected \"MODERNA COVID-19 mRNA-1273\"", outcome.getMessage()); assertEquals("Concept Display \"BLAH\" does not match expected \"MODERNA COVID-19 mRNA-1273\" for 'http://snomed.info/sct#28571000087109'", outcome.getMessage());
// Validate code - good code, good display // Validate code - good code, good display
codeSystemUrl = "http://snomed.info/sct"; codeSystemUrl = "http://snomed.info/sct";

View File

@ -38,7 +38,7 @@
}, },
{ {
"system": "http://loinc.org", "system": "http://loinc.org",
"code": "59408-5", "code": "not-a-real-code",
"display": "Oxygen saturation in Arterial blood by Pulse oximetry" "display": "Oxygen saturation in Arterial blood by Pulse oximetry"
}, },
{ {

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -116,7 +116,7 @@ public class FhirResourceDaoR5ValueSetTest extends BaseJpaR5Test {
IValidationSupport.CodeValidationResult result = myValueSetDao.validateCode(valueSetIdentifier, id, code, system, display, coding, codeableConcept, mySrd); IValidationSupport.CodeValidationResult result = myValueSetDao.validateCode(valueSetIdentifier, id, code, system, display, coding, codeableConcept, mySrd);
assertTrue(result.isOk()); assertTrue(result.isOk());
assertEquals("Systolic blood pressure at First encounter", result.getDisplay()); assertEquals("Systolic blood pressure at First encounter", result.getDisplay());
assertEquals("Concept Display \"Systolic blood pressure at First encounterXXXX\" does not match expected \"Systolic blood pressure at First encounter\" for in-memory expansion of ValueSet: http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2", result.getMessage()); assertEquals("Concept Display \"Systolic blood pressure at First encounterXXXX\" does not match expected \"Systolic blood pressure at First encounter\" for 'http://acme.org#11378-7' for in-memory expansion of ValueSet: http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2", result.getMessage());
} }
@Test @Test

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -187,6 +187,7 @@ import org.hl7.fhir.r4.model.UriType;
import org.hl7.fhir.r4.model.ValueSet; import org.hl7.fhir.r4.model.ValueSet;
import org.hl7.fhir.r5.elementmodel.Element; import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.model.ElementDefinition; import org.hl7.fhir.r5.model.ElementDefinition;
import org.hl7.fhir.r5.utils.validation.IMessagingServices;
import org.hl7.fhir.r5.utils.validation.IResourceValidator; import org.hl7.fhir.r5.utils.validation.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor; import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor;
import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel; import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel;
@ -194,6 +195,7 @@ import org.hl7.fhir.r5.utils.validation.constants.BindingKind;
import org.hl7.fhir.r5.utils.validation.constants.CodedContentValidationPolicy; import org.hl7.fhir.r5.utils.validation.constants.CodedContentValidationPolicy;
import org.hl7.fhir.r5.utils.validation.constants.ContainedReferenceValidationPolicy; import org.hl7.fhir.r5.utils.validation.constants.ContainedReferenceValidationPolicy;
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy; import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Order;
@ -211,6 +213,7 @@ import org.springframework.transaction.PlatformTransactionManager;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
@ -1022,12 +1025,44 @@ public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuil
} }
@Override @Override
public CodedContentValidationPolicy policyForCodedContent(IResourceValidator iResourceValidator, Object o, String s, ElementDefinition elementDefinition, org.hl7.fhir.r5.model.StructureDefinition structureDefinition, BindingKind bindingKind, org.hl7.fhir.r5.model.ValueSet valueSet, List<String> list) { public EnumSet<ResourceValidationAction> policyForResource(IResourceValidator validator, Object appContext,
return CodedContentValidationPolicy.CODE; org.hl7.fhir.r5.model.StructureDefinition type, String path) {
return EnumSet.allOf(ResourceValidationAction.class);
} }
@Override @Override
public ContainedReferenceValidationPolicy policyForContained(IResourceValidator validator, Object appContext, String containerType, String containerId, Element.SpecialElement containingResourceType, String path, String url) { public EnumSet<ElementValidationAction> policyForElement(IResourceValidator validator, Object appContext,
org.hl7.fhir.r5.model.StructureDefinition structure, ElementDefinition element, String path) {
return EnumSet.allOf(ElementValidationAction.class);
}
@Override
public EnumSet<CodedContentValidationAction> policyForCodedContent(IResourceValidator validator,
Object appContext,
String stackPath,
ElementDefinition definition,
org.hl7.fhir.r5.model.StructureDefinition structure,
BindingKind kind,
AdditionalBindingPurpose purpose,
org.hl7.fhir.r5.model.ValueSet valueSet,
List<String> systems) {
return EnumSet.allOf(CodedContentValidationAction.class);
}
@Override
public List<org.hl7.fhir.r5.model.StructureDefinition> getImpliedProfilesForResource(IResourceValidator validator, Object appContext, String stackPath, ElementDefinition definition, org.hl7.fhir.r5.model.StructureDefinition structure, Element resource, boolean valid, IMessagingServices msgServices, List<ValidationMessage> messages) {
return List.of();
}
@Override
public ContainedReferenceValidationPolicy policyForContained(IResourceValidator validator,
Object appContext,
org.hl7.fhir.r5.model.StructureDefinition structure,
ElementDefinition element,
String containerType,
String containerId,
Element.SpecialElement containingResourceType,
String path,
String url) {
return ContainedReferenceValidationPolicy.CHECK_VALID; return ContainedReferenceValidationPolicy.CHECK_VALID;
} }
} }

View File

@ -30,6 +30,10 @@ public final class R4ValidationTestUtil {
private R4ValidationTestUtil() { private R4ValidationTestUtil() {
} }
public static void assertHasFatals(OperationOutcome theOperationOutcome) {
assertThat(hasValidationIssuesWithSeverity(theOperationOutcome, OperationOutcome.IssueSeverity.FATAL)).as("Expected validation errors, found none").isTrue();
}
public static void assertHasErrors(OperationOutcome theOperationOutcome) { public static void assertHasErrors(OperationOutcome theOperationOutcome) {
assertThat(hasValidationIssuesWithSeverity(theOperationOutcome, OperationOutcome.IssueSeverity.ERROR)).as("Expected validation errors, found none").isTrue(); assertThat(hasValidationIssuesWithSeverity(theOperationOutcome, OperationOutcome.IssueSeverity.ERROR)).as("Expected validation errors, found none").isTrue();
} }
@ -55,4 +59,8 @@ public final class R4ValidationTestUtil {
public static void assertErrorDiagnosticContainsString(OperationOutcome theOo, String theExpectedDiagnosticSubstring) { public static void assertErrorDiagnosticContainsString(OperationOutcome theOo, String theExpectedDiagnosticSubstring) {
assertThat(theOo.getIssue().stream().anyMatch(t -> t.getSeverity() == OperationOutcome.IssueSeverity.ERROR && t.getDiagnostics().contains(theExpectedDiagnosticSubstring))).as("Expected a validation error with diagnostic containing '" + theExpectedDiagnosticSubstring + "', found none").isTrue(); assertThat(theOo.getIssue().stream().anyMatch(t -> t.getSeverity() == OperationOutcome.IssueSeverity.ERROR && t.getDiagnostics().contains(theExpectedDiagnosticSubstring))).as("Expected a validation error with diagnostic containing '" + theExpectedDiagnosticSubstring + "', found none").isTrue();
} }
public static void assertFatalDiagnosticContainsString(OperationOutcome theOo, String theExpectedDiagnosticSubstring) {
assertThat(theOo.getIssue().stream().anyMatch(t -> t.getSeverity() == OperationOutcome.IssueSeverity.FATAL && t.getDiagnostics().contains(theExpectedDiagnosticSubstring))).as("Expected a validation error with diagnostic containing '" + theExpectedDiagnosticSubstring+ "', found none").isTrue();
}
} }

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>
@ -78,6 +78,12 @@
<groupId>info.debatty</groupId> <groupId>info.debatty</groupId>
<artifactId>java-string-similarity</artifactId> <artifactId>java-string-similarity</artifactId>
<version>1.2.1</version> <version>1.2.1</version>
<exclusions>
<exclusion>
<groupId>net.jcip</groupId>
<artifactId>jcip-annotations</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -53,11 +53,13 @@ import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.commons.text.StringEscapeUtils; import org.apache.commons.text.StringEscapeUtils;
import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseBinary; import org.hl7.fhir.instance.model.api.IBaseBinary;
import org.hl7.fhir.instance.model.api.IBaseConformance; import org.hl7.fhir.instance.model.api.IBaseConformance;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome; import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType; import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.utilities.xhtml.NodeType;
import org.hl7.fhir.utilities.xhtml.XhtmlNode; import org.hl7.fhir.utilities.xhtml.XhtmlNode;
import java.io.IOException; import java.io.IOException;
@ -858,7 +860,7 @@ public class ResponseHighlighterInterceptor {
// Try to extract the narrative from the resource. First, just see if there // Try to extract the narrative from the resource. First, just see if there
// is a narrative in the normal spot. // is a narrative in the normal spot.
XhtmlNode xhtmlNode = extractNarrativeFromDomainResource(theResource, ctx); XhtmlNode xhtmlNode = extractNarrativeFromElement(theResource, ctx);
// If the resource is a document, see if the Composition has a narrative // If the resource is a document, see if the Composition has a narrative
if (xhtmlNode == null && "Bundle".equals(ctx.getResourceType(theResource))) { if (xhtmlNode == null && "Bundle".equals(ctx.getResourceType(theResource))) {
@ -866,7 +868,7 @@ public class ResponseHighlighterInterceptor {
IBaseResource firstResource = IBaseResource firstResource =
ctx.newTerser().getSingleValueOrNull(theResource, "entry.resource", IBaseResource.class); ctx.newTerser().getSingleValueOrNull(theResource, "entry.resource", IBaseResource.class);
if (firstResource != null && "Composition".equals(ctx.getResourceType(firstResource))) { if (firstResource != null && "Composition".equals(ctx.getResourceType(firstResource))) {
xhtmlNode = extractNarrativeFromDomainResource(firstResource, ctx); xhtmlNode = extractNarrativeFromComposition(firstResource, ctx);
} }
} }
} }
@ -897,6 +899,34 @@ public class ResponseHighlighterInterceptor {
return null; return null;
} }
private XhtmlNode extractNarrativeFromComposition(IBaseResource theComposition, FhirContext theCtx) {
XhtmlNode retVal = new XhtmlNode(NodeType.Element, "div");
XhtmlNode xhtmlNode = extractNarrativeFromElement(theComposition, theCtx);
if (xhtmlNode != null) {
retVal.add(xhtmlNode);
}
List<IBase> sections = theCtx.newTerser().getValues(theComposition, "section");
for (IBase section : sections) {
String title = theCtx.newTerser().getSinglePrimitiveValueOrNull(section, "title");
if (isNotBlank(title)) {
XhtmlNode sectionNarrative = extractNarrativeFromElement(section, theCtx);
if (sectionNarrative != null && sectionNarrative.hasChildren()) {
XhtmlNode titleNode = new XhtmlNode(NodeType.Element, "h1");
titleNode.addText(title);
retVal.add(titleNode);
retVal.add(sectionNarrative);
}
}
}
if (retVal.isEmpty()) {
return null;
}
return retVal;
}
private void writeLength(HttpServletResponse theServletResponse, int theLength) throws IOException { private void writeLength(HttpServletResponse theServletResponse, int theLength) throws IOException {
double kb = ((double) theLength) / FileUtils.ONE_KB; double kb = ((double) theLength) / FileUtils.ONE_KB;
if (kb <= 1000) { if (kb <= 1000) {
@ -1014,11 +1044,15 @@ public class ResponseHighlighterInterceptor {
myShowNarrative = theShowNarrative; myShowNarrative = theShowNarrative;
} }
/**
* Extracts the narrative from an element (typically a FHIR resource) that holds
* a "text" element
*/
@Nullable @Nullable
private static XhtmlNode extractNarrativeFromDomainResource(@Nonnull IBaseResource theResource, FhirContext ctx) { private static XhtmlNode extractNarrativeFromElement(@Nonnull IBase theElement, FhirContext ctx) {
if (ctx.getResourceDefinition(theResource).getChildByName("text") != null) { if (ctx.getElementDefinition(theElement.getClass()).getChildByName("text") != null) {
return ctx.newTerser() return ctx.newTerser()
.getSingleValue(theResource, "text.div", XhtmlNode.class) .getSingleValue(theElement, "text.div", XhtmlNode.class)
.orElse(null); .orElse(null);
} }
return null; return null;

View File

@ -206,6 +206,9 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
terser.addElement(retVal, "id", UUID.randomUUID().toString()); terser.addElement(retVal, "id", UUID.randomUUID().toString());
terser.addElement(retVal, "name", "RestServer"); terser.addElement(retVal, "name", "RestServer");
IBase text = terser.addElement(retVal, "text");
terser.addElement(text, "status", "generated");
terser.addElement(text, "div", "<div xmlns=\"http://www.w3.org/1999/xhtml\">HAPI-FHIR Server</div>");
terser.addElement(retVal, "publisher", myPublisher); terser.addElement(retVal, "publisher", myPublisher);
terser.addElement(retVal, "date", conformanceDate(configuration)); terser.addElement(retVal, "date", conformanceDate(configuration));
terser.addElement( terser.addElement(
@ -704,6 +707,10 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
myContext.getResourceDefinition("OperationDefinition").newInstance(); myContext.getResourceDefinition("OperationDefinition").newInstance();
FhirTerser terser = myContext.newTerser(); FhirTerser terser = myContext.newTerser();
IBase text = terser.addElement(op, "text");
terser.addElement(text, "status", "generated");
terser.addElement(text, "div", "<div xmlns=\"http://www.w3.org/1999/xhtml\">Operation Named Search</div>");
terser.addElement(op, "status", "active"); terser.addElement(op, "status", "active");
terser.addElement(op, "kind", "query"); terser.addElement(op, "kind", "query");
terser.addElement(op, "affectsState", "false"); terser.addElement(op, "affectsState", "false");
@ -765,6 +772,10 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
myContext.getResourceDefinition("OperationDefinition").newInstance(); myContext.getResourceDefinition("OperationDefinition").newInstance();
FhirTerser terser = myContext.newTerser(); FhirTerser terser = myContext.newTerser();
IBase text = terser.addElement(op, "text");
terser.addElement(text, "status", "generated");
terser.addElement(text, "div", "<div xmlns=\"http://www.w3.org/1999/xhtml\">Operation</div>");
terser.addElement(op, "status", "active"); terser.addElement(op, "status", "active");
terser.addElement(op, "kind", "operation"); terser.addElement(op, "kind", "operation");

View File

@ -7,7 +7,7 @@
<parent> <parent>
<artifactId>hapi-fhir-serviceloaders</artifactId> <artifactId>hapi-fhir-serviceloaders</artifactId>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -7,7 +7,7 @@
<parent> <parent>
<artifactId>hapi-fhir-serviceloaders</artifactId> <artifactId>hapi-fhir-serviceloaders</artifactId>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
@ -21,7 +21,7 @@
<dependency> <dependency>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-caching-api</artifactId> <artifactId>hapi-fhir-caching-api</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -7,7 +7,7 @@
<parent> <parent>
<artifactId>hapi-fhir-serviceloaders</artifactId> <artifactId>hapi-fhir-serviceloaders</artifactId>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -7,7 +7,7 @@
<parent> <parent>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot-samples</artifactId> <artifactId>hapi-fhir-spring-boot-samples</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
</parent> </parent>
<artifactId>hapi-fhir-spring-boot-sample-client-apache</artifactId> <artifactId>hapi-fhir-spring-boot-sample-client-apache</artifactId>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot-samples</artifactId> <artifactId>hapi-fhir-spring-boot-samples</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot-samples</artifactId> <artifactId>hapi-fhir-spring-boot-samples</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot</artifactId> <artifactId>hapi-fhir-spring-boot</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>
@ -166,6 +166,11 @@
<version>${project.version}</version> <version>${project.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>org.hl7.fhir.r5</artifactId>
<version>${fhir_core_version}</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -24,16 +24,19 @@ import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.model.ElementDefinition; import org.hl7.fhir.r5.model.ElementDefinition;
import org.hl7.fhir.r5.model.StructureDefinition; import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.utils.validation.IMessagingServices;
import org.hl7.fhir.r5.utils.validation.IResourceValidator; import org.hl7.fhir.r5.utils.validation.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor; import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor;
import org.hl7.fhir.r5.utils.validation.constants.BindingKind; import org.hl7.fhir.r5.utils.validation.constants.BindingKind;
import org.hl7.fhir.r5.utils.validation.constants.CodedContentValidationPolicy;
import org.hl7.fhir.r5.utils.validation.constants.ContainedReferenceValidationPolicy; import org.hl7.fhir.r5.utils.validation.constants.ContainedReferenceValidationPolicy;
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy; import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List; import java.util.List;
public class ValidatorPolicyAdvisor implements IValidationPolicyAdvisor { public class ValidatorPolicyAdvisor implements IValidationPolicyAdvisor {
@ -58,22 +61,41 @@ public class ValidatorPolicyAdvisor implements IValidationPolicyAdvisor {
} }
@Override @Override
public CodedContentValidationPolicy policyForCodedContent( public EnumSet<ResourceValidationAction> policyForResource(
IResourceValidator iResourceValidator, IResourceValidator validator, Object appContext, StructureDefinition type, String path) {
Object o, return EnumSet.allOf(ResourceValidationAction.class);
String s, }
ElementDefinition elementDefinition,
StructureDefinition structureDefinition, @Override
BindingKind bindingKind, public EnumSet<ElementValidationAction> policyForElement(
IResourceValidator validator,
Object appContext,
StructureDefinition structure,
ElementDefinition element,
String path) {
return EnumSet.allOf(ElementValidationAction.class);
}
@Override
public EnumSet<CodedContentValidationAction> policyForCodedContent(
IResourceValidator validator,
Object appContext,
String stackPath,
ElementDefinition definition,
StructureDefinition structure,
BindingKind kind,
AdditionalBindingPurpose purpose,
ValueSet valueSet, ValueSet valueSet,
List<String> list) { List<String> systems) {
return CodedContentValidationPolicy.CODE; return EnumSet.allOf(CodedContentValidationAction.class);
} }
@Override @Override
public ContainedReferenceValidationPolicy policyForContained( public ContainedReferenceValidationPolicy policyForContained(
IResourceValidator validator, IResourceValidator validator,
Object appContext, Object appContext,
StructureDefinition structure,
ElementDefinition element,
String containerType, String containerType,
String containerId, String containerId,
Element.SpecialElement containingResourceType, Element.SpecialElement containingResourceType,
@ -81,4 +103,18 @@ public class ValidatorPolicyAdvisor implements IValidationPolicyAdvisor {
String url) { String url) {
return ContainedReferenceValidationPolicy.CHECK_VALID; return ContainedReferenceValidationPolicy.CHECK_VALID;
} }
@Override
public List<StructureDefinition> getImpliedProfilesForResource(
IResourceValidator validator,
Object appContext,
String stackPath,
ElementDefinition definition,
StructureDefinition structure,
Element resource,
boolean valid,
IMessagingServices msgServices,
List<ValidationMessage> messages) {
return Arrays.asList();
}
} }

View File

@ -43,8 +43,11 @@ import org.hl7.fhir.utilities.CanonicalPair;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Set;
public class ValidatorResourceFetcher implements IValidatorResourceFetcher { public class ValidatorResourceFetcher implements IValidatorResourceFetcher {
@ -131,7 +134,8 @@ public class ValidatorResourceFetcher implements IValidatorResourceFetcher {
} }
@Override @Override
public CanonicalResource fetchCanonicalResource(IResourceValidator iResourceValidator, String s) { public CanonicalResource fetchCanonicalResource(IResourceValidator validator, Object appContext, String url)
throws URISyntaxException {
return null; return null;
} }
@ -139,4 +143,9 @@ public class ValidatorResourceFetcher implements IValidatorResourceFetcher {
public boolean fetchesCanonicalResource(IResourceValidator iResourceValidator, String s) { public boolean fetchesCanonicalResource(IResourceValidator iResourceValidator, String s) {
return false; return false;
} }
@Override
public Set<String> fetchCanonicalResourceVersions(IResourceValidator validator, Object appContext, String url) {
return Collections.emptySet();
}
} }

View File

@ -33,6 +33,7 @@ import jakarta.annotation.Nonnull;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.AuditEvent; import org.hl7.fhir.r4.model.AuditEvent;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Date; import java.util.Date;
@ -306,6 +307,10 @@ public class BalpAuditCaptureInterceptor {
AuditEvent auditEvent = new AuditEvent(); AuditEvent auditEvent = new AuditEvent();
auditEvent.getMeta().addProfile(theProfile.getProfileUrl()); auditEvent.getMeta().addProfile(theProfile.getProfileUrl());
auditEvent
.getText()
.setDiv(new XhtmlNode().setValue("<div>Audit Event</div>"))
.setStatus(org.hl7.fhir.r4.model.Narrative.NarrativeStatus.GENERATED);
auditEvent auditEvent
.getType() .getType()
.setSystem(BalpConstants.CS_AUDIT_EVENT_TYPE) .setSystem(BalpConstants.CS_AUDIT_EVENT_TYPE)

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version> <version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -31,6 +31,7 @@ import org.hl7.fhir.dstu3.terminologies.ValueSetExpander;
import org.hl7.fhir.dstu3.utils.INarrativeGenerator; import org.hl7.fhir.dstu3.utils.INarrativeGenerator;
import org.hl7.fhir.dstu3.utils.validation.IResourceValidator; import org.hl7.fhir.dstu3.utils.validation.IResourceValidator;
import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.utilities.FhirPublication;
import org.hl7.fhir.utilities.i18n.I18nBase; import org.hl7.fhir.utilities.i18n.I18nBase;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
import org.hl7.fhir.utilities.validation.ValidationOptions; import org.hl7.fhir.utilities.validation.ValidationOptions;
@ -313,7 +314,8 @@ public final class HapiWorkerContext extends I18nBase implements IWorkerContext
@Override @Override
public ValidationResult validateCode(String theSystem, String theCode, String theDisplay) { public ValidationResult validateCode(String theSystem, String theCode, String theDisplay) {
ValidationOptions options = new ValidationOptions(); ValidationOptions options = new ValidationOptions(FhirPublication.fromCode(
myValidationSupport.getFhirContext().getVersion().toString()));
IValidationSupport.CodeValidationResult result = myValidationSupport.validateCode( IValidationSupport.CodeValidationResult result = myValidationSupport.validateCode(
new ValidationSupportContext(myValidationSupport), new ValidationSupportContext(myValidationSupport),
convertConceptValidationOptions(options), convertConceptValidationOptions(options),
@ -351,7 +353,8 @@ public final class HapiWorkerContext extends I18nBase implements IWorkerContext
public ValidationResult validateCode(String theSystem, String theCode, String theDisplay, ValueSet theVs) { public ValidationResult validateCode(String theSystem, String theCode, String theDisplay, ValueSet theVs) {
IValidationSupport.CodeValidationResult outcome; IValidationSupport.CodeValidationResult outcome;
ValidationOptions options = new ValidationOptions(); ValidationOptions options = new ValidationOptions(FhirPublication.fromCode(
myValidationSupport.getFhirContext().getVersion().toString()));
if (isNotBlank(theVs.getUrl())) { if (isNotBlank(theVs.getUrl())) {
outcome = myValidationSupport.validateCode( outcome = myValidationSupport.validateCode(
new ValidationSupportContext(myValidationSupport), new ValidationSupportContext(myValidationSupport),

Some files were not shown because too many files have changed in this diff Show More