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>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>7.3.4-SNAPSHOT</version>
<version>7.3.5-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

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

View File

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

View File

@ -123,8 +123,10 @@ class DefaultProfileValidationSupportBundleStrategy implements IValidationSuppor
break;
case R4B:
terminologyResources.add("/org/hl7/fhir/r4b/model/valueset/valuesets.xml");
terminologyResources.add("/org/hl7/fhir/r4b/model/valueset/v2-tables.xml");
terminologyResources.add("/org/hl7/fhir/r4b/model/valueset/v3-codesystems.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
// 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-types.xml");
structureDefinitionResources.add("/org/hl7/fhir/r4b/model/profile/profiles-others.xml");

View File

@ -459,6 +459,58 @@ public interface IValidationSupport {
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 {
private String myLanguage;
@ -634,6 +686,8 @@ public interface IValidationSupport {
private String myDisplay;
private String mySourceDetails;
private List<CodeValidationIssue> myCodeValidationIssues;
public CodeValidationResult() {
super();
}
@ -717,6 +771,23 @@ public interface IValidationSupport {
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() {
return isNotBlank(myCode);
}
@ -777,14 +848,18 @@ public interface IValidationSupport {
private final IBaseResource myValueSet;
private final String myError;
public ValueSetExpansionOutcome(String theError) {
private boolean myErrorIsFromServer;
public ValueSetExpansionOutcome(String theError, boolean theErrorIsFromServer) {
myValueSet = null;
myError = theError;
myErrorIsFromServer = theErrorIsFromServer;
}
public ValueSetExpansionOutcome(IBaseResource theValueSet) {
myValueSet = theValueSet;
myError = null;
myErrorIsFromServer = false;
}
public String getError() {
@ -794,6 +869,10 @@ public interface IValidationSupport {
public IBaseResource getValueSet() {
return myValueSet;
}
public boolean getErrorIsFromServer() {
return myErrorIsFromServer;
}
}
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.invalidCodeInSystem=Code {0} is not valid for system: {1}

View File

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

View File

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

View File

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

View File

@ -38,7 +38,7 @@ public class ValidateCommandTest {
@Test
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[]{
"validate",
@ -49,7 +49,7 @@ public class ValidateCommandTest {
@Test
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);
App.main(new String[]{

View File

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

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>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-cli</artifactId>
<version>7.3.4-SNAPSHOT</version>
<version>7.3.5-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version>
<version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</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.MetaUtil;
import jakarta.annotation.Nullable;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseCoding;

View File

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

View File

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

View File

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

View File

@ -3,7 +3,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version>
<version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</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.
*/-->
<div xmlns:th="http://www.thymeleaf.org">
<div th:each="section : ${resource.section}">
<h1 th:text="${section.title}"></h1>
<div th:utext="${section.text.getDivAsString()}">
</div>
</div>
<h1>International Patient Summary Document</h1>
</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.jpa.api.config.JpaStorageSettings;
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.provider.IpsOperationProvider;
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.validator.FhirInstanceValidator;
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.CodeSystem;
import org.hl7.fhir.r4.model.CodeableConcept;
import org.hl7.fhir.r4.model.Composition;
import org.hl7.fhir.r4.model.Condition;
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.MedicationStatement;
import org.hl7.fhir.r4.model.Parameters;
@ -43,8 +46,12 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
@ -100,7 +107,7 @@ public class IpsGenerationR4Test extends BaseResourceProviderR4Test {
validateDocument(output);
assertEquals(117, output.getEntry().size());
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);
assertEquals(patientId, medicationStatement.getSubject().getReference());
assertNull(medicationStatement.getInformationSource().getReference());
@ -196,7 +203,7 @@ public class IpsGenerationR4Test extends BaseResourceProviderR4Test {
validateDocument(output);
assertEquals(7, output.getEntry().size());
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, 1, 2).getSubject().getReference());
@ -243,9 +250,8 @@ public class IpsGenerationR4Test extends BaseResourceProviderR4Test {
ourLog.info("Output: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(output));
Composition composition = findCompositionSectionByDisplay(output, "History of Immunization Narrative");
// Should be newest first
assertThat(composition.getText().getDivAsString()).containsSubsequence(
"Vax 2015", "Vax 2010", "Vax 2005"
assertThat(composition.getText().getDivAsString()).isEqualTo(
"<div xmlns=\"http://www.w3.org/1999/xhtml\"><h1>International Patient Summary Document</h1></div>"
);
List<String> resourceDates = output
@ -303,7 +309,12 @@ public class IpsGenerationR4Test extends BaseResourceProviderR4Test {
@Bean
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
@ -341,6 +352,73 @@ public class IpsGenerationR4Test extends BaseResourceProviderR4Test {
* package.
*/
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
public boolean isValueSetSupported(ValidationSupportContext theValidationSupportContext, String theValueSetUrl) {
return true;
@ -350,12 +428,40 @@ public class IpsGenerationR4Test extends BaseResourceProviderR4Test {
@Override
public CodeValidationResult validateCodeInValueSet(ValidationSupportContext theValidationSupportContext, ConceptValidationOptions theOptions, String theCodeSystem, String theCode, String theDisplay, @Nonnull IBaseResource theValueSet) {
if ("http://loinc.org".equals(theCodeSystem)) {
if ("60591-5".equals(theCode)) {
if (loincValueSetCodes.contains(theCode)) {
return new CodeValidationResult().setCode(theCode);
}
}
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);
}
}
@ -374,6 +480,15 @@ public class IpsGenerationR4Test extends BaseResourceProviderR4Test {
cs.addConcept().setCode("no-known-allergies");
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;
}

View File

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

View File

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

View File

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

View File

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

View File

@ -26,9 +26,9 @@ import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
import com.google.common.annotations.VisibleForTesting;
import jakarta.annotation.PostConstruct;
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.model.Base;
import org.hl7.fhir.dstu3.utils.FHIRPathEngine;
import org.hl7.fhir.instance.model.api.IBase;
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.instance.model.api.IBase;
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.model.Base;
import org.hl7.fhir.r4.model.ExpressionNode;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.Resource;
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.utils.FHIRPathEngine;
import org.hl7.fhir.r4.utils.FHIRPathUtilityClasses.FunctionDetails;
import java.util.Collections;
import java.util.HashMap;
@ -106,13 +106,16 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements
private final Map<String, Base> myResourceTypeToStub = Collections.synchronizedMap(new HashMap<>());
@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 {
return Collections.emptyList();
}
@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;
}
@ -122,24 +125,33 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements
}
@Override
public FunctionDetails resolveFunction(String functionName) {
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
return null;
}
@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 {
return null;
}
@Override
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;
}
@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);
if (retVal != null) {
return retVal;
@ -187,12 +199,13 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements
}
@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;
}
@Override
public ValueSet resolveValueSet(Object appContext, String url) {
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
return null;
}
}

View File

@ -32,16 +32,16 @@ import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.PathEngineException;
import org.hl7.fhir.instance.model.api.IBase;
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.model.Base;
import org.hl7.fhir.r4b.model.ExpressionNode;
import org.hl7.fhir.r4b.model.IdType;
import org.hl7.fhir.r4b.model.Resource;
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.utils.FHIRPathEngine;
import org.hl7.fhir.r4b.utils.FHIRPathUtilityClasses.FunctionDetails;
import java.util.Collections;
import java.util.HashMap;
@ -106,13 +106,16 @@ public class SearchParamExtractorR4B extends BaseSearchParamExtractor implements
private final Map<String, Base> myResourceTypeToStub = Collections.synchronizedMap(new HashMap<>());
@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 {
return Collections.emptyList();
}
@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;
}
@ -122,24 +125,33 @@ public class SearchParamExtractorR4B extends BaseSearchParamExtractor implements
}
@Override
public FunctionDetails resolveFunction(String functionName) {
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
return null;
}
@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 {
return null;
}
@Override
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;
}
@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);
if (retVal != null) {
return retVal;
@ -187,12 +199,13 @@ public class SearchParamExtractorR4B extends BaseSearchParamExtractor implements
}
@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;
}
@Override
public ValueSet resolveValueSet(Object appContext, String url) {
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
return null;
}
}

View File

@ -31,16 +31,16 @@ import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.PathEngineException;
import org.hl7.fhir.instance.model.api.IBase;
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.model.Base;
import org.hl7.fhir.r5.model.ExpressionNode;
import org.hl7.fhir.r5.model.IdType;
import org.hl7.fhir.r5.model.Resource;
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.utils.FHIRPathEngine;
import org.hl7.fhir.r5.utils.FHIRPathUtilityClasses.FunctionDetails;
import java.util.Collections;
import java.util.HashMap;
@ -103,13 +103,16 @@ public class SearchParamExtractorR5 extends BaseSearchParamExtractor implements
private final Map<String, Base> myResourceTypeToStub = Collections.synchronizedMap(new HashMap<>());
@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 {
return Collections.emptyList();
}
@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;
}
@ -119,24 +122,33 @@ public class SearchParamExtractorR5 extends BaseSearchParamExtractor implements
}
@Override
public FunctionDetails resolveFunction(String functionName) {
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
return null;
}
@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 {
return null;
}
@Override
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;
}
@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);
if (retVal != null) {
return retVal;
@ -184,13 +196,19 @@ public class SearchParamExtractorR5 extends BaseSearchParamExtractor implements
}
@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;
}
@Override
public ValueSet resolveValueSet(Object theO, String theS) {
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
return null;
}
@Override
public boolean paramIsType(String name, int index) {
return false;
}
}
}

View File

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

View File

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

View File

@ -123,7 +123,6 @@ public class FhirResourceDaoDstu2ValidateTest extends BaseJpaDstu2Test {
Observation input = new Observation();
String profileUri = "http://example.com/StructureDefinition/" + methodName;
ResourceMetadataKeyEnum.PROFILES.put(input, Collections.singletonList(new IdDt(profileUri)));
input.addIdentifier().setSystem("http://acme").setValue("12345");
input.getEncounter().setReference("http://foo.com/Encounter/9");
input.setStatus(ObservationStatusEnum.FINAL);
@ -137,7 +136,7 @@ public class FhirResourceDaoDstu2ValidateTest extends BaseJpaDstu2Test {
assertHasErrors(oo);
String ooString = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo);
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

View File

@ -102,7 +102,7 @@ public class FhirResourceDaoValueSetDstu2Test extends BaseJpaDstu2Test {
CodeableConceptDt codeableConcept = null;
IValidationSupport.CodeValidationResult result = myValueSetDao.validateCode(valueSetIdentifier, id, code, system, display, coding, codeableConcept, mySrd);
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(IValidationSupport.IssueSeverity.WARNING, result.getSeverity());
}

View File

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

View File

@ -325,7 +325,7 @@ public class FhirResourceDaoDstu3ValidateTest extends BaseJpaDstu3Test {
assertHasErrors(oo);
String outputString = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo);
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

View File

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

View File

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

View File

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

View File

@ -594,24 +594,24 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
fail(myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome()));
}
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
assertEquals(14, myCaptureQueriesListener.getSelectQueriesForCurrentThread().size());
assertEquals(8, myCaptureQueriesListener.getSelectQueriesForCurrentThread().size());
assertEquals(0, myCaptureQueriesListener.getUpdateQueriesForCurrentThread().size());
assertEquals(0, myCaptureQueriesListener.getInsertQueriesForCurrentThread().size());
assertEquals(0, myCaptureQueriesListener.getDeleteQueriesForCurrentThread().size());
assertEquals(12, myCaptureQueriesListener.getCommitCount());
assertEquals(6, myCaptureQueriesListener.getCommitCount());
// Validate again (should rely only on caches)
myCaptureQueriesListener.clear();
myObservationDao.validate(obs, null, null, null, null, null, null);
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
assertEquals(6, myCaptureQueriesListener.getSelectQueriesForCurrentThread().size());
assertEquals(0, myCaptureQueriesListener.getSelectQueriesForCurrentThread().size());
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
assertThat(myCaptureQueriesListener.getUpdateQueriesForCurrentThread()).isEmpty();
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
assertThat(myCaptureQueriesListener.getInsertQueriesForCurrentThread()).isEmpty();
myCaptureQueriesListener.logDeleteQueriesForCurrentThread();
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.ValidationConstants.LOINC_LOW;
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.Mockito.mock;
@ -133,7 +132,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
encoded = encode(oo);
ourLog.info(encoded);
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.getIssueFirstRep().getSeverity()).as(encoded).isEqualTo(OperationOutcome.IssueSeverity.ERROR);
@ -165,7 +164,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
encoded = encode(oo);
ourLog.info(encoded);
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'");
assertEquals(OperationOutcome.IssueSeverity.ERROR, oo.getIssueFirstRep().getSeverity());
}
@ -202,7 +201,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
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'");
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());
}
@ -241,7 +240,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
encoded = encode(oo);
ourLog.info(encoded);
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());
}
@ -335,19 +334,25 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
oo = validateAndReturnOutcome(obs, true);
encoded = encode(oo);
ourLog.info(encoded);
assertThat(oo.getIssue()).hasSize(1);
assertThat(oo.getIssue().get(0).getDiagnostics()).contains("provided (http://cs#code1) is not in the value set");
assertThat(oo.getIssue().get(0).getDiagnostics()).contains("Failed to expand ValueSet 'http://vs' (in-memory). Could not validate code http://cs#code1");
assertThat(oo.getIssue().get(0).getDiagnostics()).contains("HAPI-0702: Unable to expand ValueSet because CodeSystem could not be found: http://cs");
assertThat(oo.getIssue()).hasSize(2);
OperationOutcome.OperationOutcomeIssueComponent unableToExpandError = oo.getIssue().get(0);
assertThat(unableToExpandError.getDiagnostics()).contains("Unable to expand ValueSet because CodeSystem could not be found: http://cs");
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());
assertEquals("Terminology_TX_NoValid_12", ((StringType) oo.getIssue().get(0).getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/operationoutcome-message-id").getValue()).getValue());
assertEquals(OperationOutcome.IssueType.PROCESSING, oo.getIssue().get(0).getCode());
assertEquals(OperationOutcome.IssueSeverity.ERROR, oo.getIssue().get(0).getSeverity());
assertThat(oo.getIssue().get(0).getLocation()).hasSize(2);
assertEquals("Observation.value.ofType(Quantity)", oo.getIssue().get(0).getLocation().get(0).getValue());
assertEquals("Line[27] Col[4]", oo.getIssue().get(0).getLocation().get(1).getValue());
OperationOutcome.OperationOutcomeIssueComponent notInValueSetError = oo.getIssue().get(1);
assertThat(notInValueSetError.getDiagnostics()).contains("provided (http://cs#code1) was not found in the value set");
assertThat(notInValueSetError.getDiagnostics()).contains("Failed to expand ValueSet 'http://vs' (in-memory). Could not validate code http://cs#code1");
assertThat(notInValueSetError.getDiagnostics()).contains("HAPI-0702: Unable to expand ValueSet because CodeSystem could not be found: http://cs");
assertEquals(OperationOutcome.IssueSeverity.ERROR, oo.getIssueFirstRep().getSeverity());
assertEquals(27, ((IntegerType) notInValueSetError.getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-line").getValue()).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);
String outcomeStr = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome);
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
runInTransaction(() -> {
@ -535,7 +540,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
assertHasErrors(outcome);
outcomeStr = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome);
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.getCode().getCodingFirstRep().setSystem("http://loinc.org").setCode("non-existing-code").setDisplay("Display 3");
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
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
@ -639,7 +644,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
// Code that exists but isn't in the valueset
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);
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.getCategoryFirstRep().addCoding().setSystem("http://terminology.hl7.org/CodeSystem/observation-category").setCode("FOO");
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
myCaptureQueriesListener.clear();
@ -931,7 +936,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
OperationOutcome oo = validateAndReturnOutcome(vs);
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
@ -986,7 +991,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
obs.getCode().getCodingFirstRep().setDisplay("Some Code");
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));
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());
// Correct codesystem, Code in codesystem
@ -1077,7 +1082,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://loinc.org").setCode("non-existing-code").setDisplay("Display 3");
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
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
@ -1089,20 +1094,20 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://foo").setCode("CODE3").setDisplay("Display 3");
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
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);
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
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
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");
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);
ourLog.debug(myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo));
assertEquals("Error MY ERROR validating Coding: java.lang.NullPointerException: MY ERROR", oo.getIssueFirstRep().getDiagnostics());
assertEquals(OperationOutcome.IssueSeverity.ERROR, oo.getIssueFirstRep().getSeverity());
assertEquals("Error MY ERROR validating CodeableConcept", oo.getIssueFirstRep().getDiagnostics());
assertEquals(OperationOutcome.IssueSeverity.WARNING, oo.getIssueFirstRep().getSeverity());
}
@Test
@ -1366,7 +1371,9 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
TermCodeSystemVersion csv = new TermCodeSystemVersion();
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
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
assertEquals(2, OperationOutcomeUtil.getIssueCount(myFhirContext, oo));
assertThat(OperationOutcomeUtil.getFirstIssueDetails(myFhirContext, oo)).contains("None of the codings provided are in the value set 'IdentifierType'");
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)");
assertEquals(OperationOutcome.IssueSeverity.WARNING, oo.getIssue().get(1).getSeverity());
assertEquals("Concept Display \"not bar code\" does not match expected \"Bar Code\" for 'http://foo#bar'", oo.getIssue().get(1).getDiagnostics());
OperationOutcome.OperationOutcomeIssueComponent notInValueSetIssue = oo.getIssue().get(1);
assertThat(notInValueSetIssue.getDiagnostics()).contains("None of the codings provided are in the value set 'IdentifierType'");
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(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 {
@ -1465,7 +1473,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
assertHasErrors(oo);
String outputString = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo);
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
@ -1498,7 +1506,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
assertHasErrors(oo);
String outputString = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo);
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
@ -1572,10 +1580,14 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
@Test
void testValidateCommonCodes_Ucum_ErrorMessageIsPreserved() {
String loincCode = "1234";
addLoincCodeToCodeSystemDao(loincCode);
Observation input = new Observation();
input.getText().setDiv(new XhtmlNode().setValue("<div>AA</div>")).setStatus(Narrative.NarrativeStatus.GENERATED);
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(
null,
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(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("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.IssueSeverity.ERROR, oo.getIssue().get(0).getSeverity());
assertThat(oo.getIssue().get(0).getLocation()).hasSize(2);
@ -1602,10 +1614,14 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
@Test
void testValidateCommonCodes_Currency_ErrorMessageIsPreserved() {
String loincCode = "1234";
addLoincCodeToCodeSystemDao(loincCode);
Observation input = new Observation();
input.getText().setDiv(new XhtmlNode().setValue("<div>AA</div>")).setStatus(Narrative.NarrativeStatus.GENERATED);
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(
null,
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(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("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.IssueSeverity.ERROR, oo.getIssue().get(0).getSeverity());
assertThat(oo.getIssue().get(0).getLocation()).hasSize(2);
@ -2064,6 +2080,8 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
codeElement.addType().setCode("CodeableConcept");
codeElement.getBinding().setStrength(Enumerations.BindingStrength.REQUIRED);
codeElement.getBinding().setValueSet("http://vs");
String encodedStructureDefinition = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(sd);
myStructureDefinitionDao.create(sd, new SystemRequestDetails());
CodeSystem cs = new CodeSystem();
@ -2073,12 +2091,17 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
cs.addConcept()
.setCode("8302-2")
.setDisplay("Body Height");
String encodedCodeSystem = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(cs);
myCodeSystemDao.create(cs, new SystemRequestDetails());
ValueSet vs = new ValueSet();
vs.setUrl("http://vs");
vs.setStatus(Enumerations.PublicationStatus.ACTIVE);
vs.getCompose().addInclude().setSystem("http://cs");
String encodedValueSet = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(vs);
myValueSetDao.create(vs, new SystemRequestDetails());
if (thePreCalculateExpansion) {
@ -2099,8 +2122,8 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
obs.setSubject(new Reference("Patient/123"));
obs.setValue(new Quantity(null, 123, "http://unitsofmeasure.org", "[in_i]", "in"));
String encoded = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs);
MethodOutcome outcome = myObservationDao.validate(obs, null, encoded, EncodingEnum.JSON, ValidationModeEnum.CREATE, null, new SystemRequestDetails());
String encodedResource = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs);
MethodOutcome outcome = myObservationDao.validate(obs, null, encodedResource, EncodingEnum.JSON, ValidationModeEnum.CREATE, null, new SystemRequestDetails());
OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome();
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);
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("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
public void testKnownCodeSystemUnknownValueSetUri() {
CodeSystem cs = new CodeSystem();
cs.setUrl(ITermLoaderSvc.LOINC_URI);
cs.setContent(CodeSystem.CodeSystemContentMode.COMPLETE);
cs.addConcept().setCode("10013-1");
cs.setId(LOINC_LOW);
myCodeSystemDao.update(cs);
String loincCode = "10013-1";
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());
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);
assertTrue(result.isOk());
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

View File

@ -49,6 +49,7 @@ public class RepositoryValidatingInterceptorHttpR4Test extends BaseJpaR4Test {
@Test
public void testValidationIsSkippedOnAutoCreatedPlaceholderReferencesIfConfiguredToDoSo() {
createLocalCsAndVs();
List<IRepositoryValidatingRule> rules = newRuleBuilder()
.forResourcesOfType("Observation")
.requireValidationToDeclaredProfiles()
@ -56,7 +57,7 @@ public class RepositoryValidatingInterceptorHttpR4Test extends BaseJpaR4Test {
myValInterceptor.setRules(rules);
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);
MethodOutcome outcome = myRestfulServerExtension
@ -68,11 +69,12 @@ public class RepositoryValidatingInterceptorHttpR4Test extends BaseJpaR4Test {
String operationOutcomeEncoded = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome.getOperationOutcome());
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
public void testValidationOutcomeAddedToRequestResponse() {
createLocalCsAndVs();
List<IRepositoryValidatingRule> rules = newRuleBuilder()
.forResourcesOfType("Observation")
.requireValidationToDeclaredProfiles()
@ -81,7 +83,7 @@ public class RepositoryValidatingInterceptorHttpR4Test extends BaseJpaR4Test {
myValInterceptor.setRules(rules);
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);
MethodOutcome outcome = myRestfulServerExtension
@ -93,7 +95,7 @@ public class RepositoryValidatingInterceptorHttpR4Test extends BaseJpaR4Test {
String operationOutcomeEncoded = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome.getOperationOutcome());
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);
String encode = encode(oo);
ourLog.info(encode);
assertThat(encode).contains("All observations should have a performer");
assertThat(encode).contains("In general, all observations should have a performer");
}
@Test
@ -92,13 +92,16 @@ public class ValidationMessageSuppressingInterceptorTest extends BaseResourcePro
} catch (UnprocessableEntityException e) {
String encode = encode(e.getOperationOutcome());
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
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);
{
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("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\"><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\"><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/></table></div>", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 0, "operation", "value"));
assertEquals("insert", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 1, "operation", "type"));
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("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\"><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\"><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/></table></div>", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 2, "operation", "value"));
assertEquals("insert", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 3, "operation", "type"));
assertEquals("Patient.name", FhirPatchApplyR4Test.extractPartValuePrimitive(diff, 3, "operation", "path"));

View File

@ -573,7 +573,7 @@ public class ResourceProviderR4CodeSystemTest extends BaseResourceProviderR4Test
ourLog.info(resp);
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

View File

@ -1,11 +1,5 @@
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.i18n.HapiLocalizer;
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 org.apache.commons.lang3.StringUtils.isNotBlank;
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.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;
@SuppressWarnings("Duplicates")
@ -2108,7 +2110,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
String respString = IOUtils.toString(resp.getEntity().getContent(), Charsets.UTF_8);
ourLog.debug(respString);
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());
assertEquals("28571000087109", outcome.getCode());
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("0.17", outcome.getCodeSystemVersion());
@ -1689,7 +1689,7 @@ public class ValueSetExpansionR4Test extends BaseTermR4Test implements IValueSet
assertEquals("28571000087109", outcome.getCode());
assertEquals("MODERNA COVID-19 mRNA-1273", outcome.getDisplay());
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
codeSystemUrl = "http://snomed.info/sct";

View File

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

View File

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

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version>
<version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</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);
assertTrue(result.isOk());
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

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version>
<version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</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.r5.elementmodel.Element;
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.IValidationPolicyAdvisor;
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.ContainedReferenceValidationPolicy;
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.BeforeEach;
import org.junit.jupiter.api.Order;
@ -211,6 +213,7 @@ import org.springframework.transaction.PlatformTransactionManager;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@ -1022,12 +1025,44 @@ public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuil
}
@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) {
return CodedContentValidationPolicy.CODE;
public EnumSet<ResourceValidationAction> policyForResource(IResourceValidator validator, Object appContext,
org.hl7.fhir.r5.model.StructureDefinition type, String path) {
return EnumSet.allOf(ResourceValidationAction.class);
}
@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;
}
}

View File

@ -30,6 +30,10 @@ public final class 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) {
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) {
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>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>7.3.4-SNAPSHOT</version>
<version>7.3.5-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

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

View File

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

View File

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

View File

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

View File

@ -53,11 +53,13 @@ import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
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.IBaseConformance;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.utilities.xhtml.NodeType;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
import java.io.IOException;
@ -858,7 +860,7 @@ public class ResponseHighlighterInterceptor {
// Try to extract the narrative from the resource. First, just see if there
// 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 (xhtmlNode == null && "Bundle".equals(ctx.getResourceType(theResource))) {
@ -866,7 +868,7 @@ public class ResponseHighlighterInterceptor {
IBaseResource firstResource =
ctx.newTerser().getSingleValueOrNull(theResource, "entry.resource", IBaseResource.class);
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;
}
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 {
double kb = ((double) theLength) / FileUtils.ONE_KB;
if (kb <= 1000) {
@ -1014,11 +1044,15 @@ public class ResponseHighlighterInterceptor {
myShowNarrative = theShowNarrative;
}
/**
* Extracts the narrative from an element (typically a FHIR resource) that holds
* a "text" element
*/
@Nullable
private static XhtmlNode extractNarrativeFromDomainResource(@Nonnull IBaseResource theResource, FhirContext ctx) {
if (ctx.getResourceDefinition(theResource).getChildByName("text") != null) {
private static XhtmlNode extractNarrativeFromElement(@Nonnull IBase theElement, FhirContext ctx) {
if (ctx.getElementDefinition(theElement.getClass()).getChildByName("text") != null) {
return ctx.newTerser()
.getSingleValue(theResource, "text.div", XhtmlNode.class)
.getSingleValue(theElement, "text.div", XhtmlNode.class)
.orElse(null);
}
return null;

View File

@ -206,6 +206,9 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
terser.addElement(retVal, "id", UUID.randomUUID().toString());
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, "date", conformanceDate(configuration));
terser.addElement(
@ -704,6 +707,10 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
myContext.getResourceDefinition("OperationDefinition").newInstance();
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, "kind", "query");
terser.addElement(op, "affectsState", "false");
@ -765,6 +772,10 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
myContext.getResourceDefinition("OperationDefinition").newInstance();
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, "kind", "operation");

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>hapi-deployable-pom</artifactId>
<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>
</parent>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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.StructureDefinition;
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.IValidationPolicyAdvisor;
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.ReferenceValidationPolicy;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
public class ValidatorPolicyAdvisor implements IValidationPolicyAdvisor {
@ -58,22 +61,41 @@ public class ValidatorPolicyAdvisor implements IValidationPolicyAdvisor {
}
@Override
public CodedContentValidationPolicy policyForCodedContent(
IResourceValidator iResourceValidator,
Object o,
String s,
ElementDefinition elementDefinition,
StructureDefinition structureDefinition,
BindingKind bindingKind,
public EnumSet<ResourceValidationAction> policyForResource(
IResourceValidator validator, Object appContext, StructureDefinition type, String path) {
return EnumSet.allOf(ResourceValidationAction.class);
}
@Override
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,
List<String> list) {
return CodedContentValidationPolicy.CODE;
List<String> systems) {
return EnumSet.allOf(CodedContentValidationAction.class);
}
@Override
public ContainedReferenceValidationPolicy policyForContained(
IResourceValidator validator,
Object appContext,
StructureDefinition structure,
ElementDefinition element,
String containerType,
String containerId,
Element.SpecialElement containingResourceType,
@ -81,4 +103,18 @@ public class ValidatorPolicyAdvisor implements IValidationPolicyAdvisor {
String url) {
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.LoggerFactory;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Set;
public class ValidatorResourceFetcher implements IValidatorResourceFetcher {
@ -131,7 +134,8 @@ public class ValidatorResourceFetcher implements IValidatorResourceFetcher {
}
@Override
public CanonicalResource fetchCanonicalResource(IResourceValidator iResourceValidator, String s) {
public CanonicalResource fetchCanonicalResource(IResourceValidator validator, Object appContext, String url)
throws URISyntaxException {
return null;
}
@ -139,4 +143,9 @@ public class ValidatorResourceFetcher implements IValidatorResourceFetcher {
public boolean fetchesCanonicalResource(IResourceValidator iResourceValidator, String s) {
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.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.AuditEvent;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
import java.nio.charset.StandardCharsets;
import java.util.Date;
@ -306,6 +307,10 @@ public class BalpAuditCaptureInterceptor {
AuditEvent auditEvent = new AuditEvent();
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
.getType()
.setSystem(BalpConstants.CS_AUDIT_EVENT_TYPE)

View File

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

View File

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

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>7.3.4-SNAPSHOT</version>
<version>7.3.5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</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.validation.IResourceValidator;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.utilities.FhirPublication;
import org.hl7.fhir.utilities.i18n.I18nBase;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
import org.hl7.fhir.utilities.validation.ValidationOptions;
@ -313,7 +314,8 @@ public final class HapiWorkerContext extends I18nBase implements IWorkerContext
@Override
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(
new ValidationSupportContext(myValidationSupport),
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) {
IValidationSupport.CodeValidationResult outcome;
ValidationOptions options = new ValidationOptions();
ValidationOptions options = new ValidationOptions(FhirPublication.fromCode(
myValidationSupport.getFhirContext().getVersion().toString()));
if (isNotBlank(theVs.getUrl())) {
outcome = myValidationSupport.validateCode(
new ValidationSupportContext(myValidationSupport),

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