use of ca.uhn.fhir.validation.SingleValidationMessage in project synthea by synthetichealth.
the class FHIRR4ExporterTest method testFHIRR4Export.
@Test
public void testFHIRR4Export() throws Exception {
TestHelper.loadTestProperties();
Generator.DEFAULT_STATE = Config.get("test_state.default", "Massachusetts");
Config.set("exporter.baseDirectory", tempFolder.newFolder().toString());
FhirContext ctx = FhirR4.getContext();
IParser parser = ctx.newJsonParser().setPrettyPrint(true);
ValidationResources validator = new ValidationResources();
List<String> errors = ParallelTestingService.runInParallel((person) -> {
List<String> validationErrors = new ArrayList<String>();
TestHelper.exportOff();
FhirR4.TRANSACTION_BUNDLE = person.randBoolean();
FhirR4.USE_US_CORE_IG = person.randBoolean();
FhirR4.USE_SHR_EXTENSIONS = false;
String fhirJson = FhirR4.convertToFHIRJson(person, System.currentTimeMillis());
// (these should have been converted into URIs)
if (fhirJson.contains("SNOMED-CT")) {
validationErrors.add("JSON contains unconverted references to 'SNOMED-CT' (should be URIs)");
}
// Let's crack open the Bundle and validate
// each individual entry.resource to get context-sensitive error
// messages...
// IMPORTANT: this approach significantly reduces memory usage when compared to
// validating the entire bundle at a time, but means that validating references
// is impossible.
// As of 2021-01-05, validating the bundle didn't validate references anyway,
// but at some point we may want to do that.
Bundle bundle = parser.parseResource(Bundle.class, fhirJson);
for (Bundle.BundleEntryComponent entry : bundle.getEntry()) {
ValidationResult eresult = validator.validateR4(entry.getResource());
if (!eresult.isSuccessful()) {
for (SingleValidationMessage emessage : eresult.getMessages()) {
boolean valid = false;
if (emessage.getSeverity() == ResultSeverityEnum.INFORMATION || emessage.getSeverity() == ResultSeverityEnum.WARNING) {
/*
* Ignore warnings.
*/
valid = true;
} else if (emessage.getMessage().contains("us-core-documentreference-type")) {
/*
* The instance validator does not expand intentional value sets like this one.
*/
valid = true;
} else if (emessage.getMessage().contains("@ AllergyIntolerance ait-2")) {
/*
* The ait-2 invariant:
* Description:
* AllergyIntolerance.clinicalStatus SHALL NOT be present
* if verification Status is entered-in-error
* Expression:
* verificationStatus!='entered-in-error' or clinicalStatus.empty()
*/
valid = true;
} else if (emessage.getMessage().contains("@ ExplanationOfBenefit dom-3")) {
/*
* For some reason, it doesn't like the contained ServiceRequest and contained
* Coverage resources in the ExplanationOfBenefit, both of which are
* properly referenced. Running $validate on test servers finds this valid...
*/
valid = true;
} else if (emessage.getMessage().contains("per-1: If present, start SHALL have a lower value than end")) {
/*
* The per-1 invariant does not account for daylight savings time... so, if the
* daylight savings switch happens between the start and end, the validation
* fails, even if it is valid.
*/
// ignore this error
valid = true;
} else if (emessage.getMessage().contains("Unknown extension http://hl7.org/fhir/us/core") || emessage.getMessage().contains("Unknown extension http://synthetichealth") || emessage.getMessage().contains("not be resolved, so has not been checked")) {
/*
* Despite setting instanceValidator.setAnyExtensionsAllowed(true) and
* instanceValidator.setErrorForUnknownProfiles(false), the FHIR validator still
* reports these as errors
*/
// ignore this error
valid = true;
}
if (!valid) {
System.out.println(parser.encodeResourceToString(entry.getResource()));
System.out.println("ERROR: " + emessage.getMessage());
validationErrors.add(emessage.getMessage());
}
}
}
}
if (!validationErrors.isEmpty()) {
Exporter.export(person, System.currentTimeMillis());
}
return validationErrors;
});
assertTrue("Validation of exported FHIR bundle failed: " + String.join("|", errors), errors.size() == 0);
}
use of ca.uhn.fhir.validation.SingleValidationMessage in project synthea by synthetichealth.
the class HospitalExporterTestStu3 method testFHIRExport.
@Test
public void testFHIRExport() throws Exception {
FhirContext ctx = FhirStu3.getContext();
FhirValidator validator = ctx.newValidator();
validator.setValidateAgainstStandardSchema(true);
validator.setValidateAgainstStandardSchematron(true);
File tempOutputFolder = tempFolder.newFolder();
Config.set("exporter.baseDirectory", tempOutputFolder.toString());
Config.set("exporter.hospital.fhir_stu3.export", "true");
Config.set("exporter.fhir.transaction_bundle", "true");
// set this manually, in case it has already been loaded.
FhirStu3.TRANSACTION_BUNDLE = true;
TestHelper.loadTestProperties();
Generator.DEFAULT_STATE = Config.get("test_state.default", "Massachusetts");
Location location = new Location(Generator.DEFAULT_STATE, null);
Provider.clear();
Provider.loadProviders(location, 1L);
assertNotNull(Provider.getProviderList());
assertFalse(Provider.getProviderList().isEmpty());
Provider.getProviderList().get(0).incrementEncounters(EncounterType.WELLNESS, 0);
HospitalExporterStu3.export(0L);
File expectedExportFolder = tempOutputFolder.toPath().resolve("fhir_stu3").toFile();
assertTrue(expectedExportFolder.exists() && expectedExportFolder.isDirectory());
File expectedExportFile = expectedExportFolder.toPath().resolve("hospitalInformation0.json").toFile();
assertTrue(expectedExportFile.exists() && expectedExportFile.isFile());
FileReader fileReader = new FileReader(expectedExportFile.getPath());
BufferedReader bufferedReader = new BufferedReader(fileReader);
StringBuilder fhirJson = new StringBuilder();
String line = null;
while ((line = bufferedReader.readLine()) != null) {
fhirJson.append(line);
}
bufferedReader.close();
IBaseResource resource = ctx.newJsonParser().parseResource(fhirJson.toString());
ValidationResult result = validator.validateWithResult(resource);
if (result.isSuccessful() == false) {
for (SingleValidationMessage message : result.getMessages()) {
System.out.println(message.getSeverity().toString() + ": " + message.getMessage());
}
}
assertTrue(result.isSuccessful());
}
use of ca.uhn.fhir.validation.SingleValidationMessage in project synthea by synthetichealth.
the class FHIRDSTU2ExporterTest method testFHIRDSTU2Export.
@Test
public void testFHIRDSTU2Export() throws Exception {
TestHelper.loadTestProperties();
Generator.DEFAULT_STATE = Config.get("test_state.default", "Massachusetts");
Config.set("exporter.baseDirectory", tempFolder.newFolder().toString());
FhirContext ctx = FhirDstu2.getContext();
IParser parser = ctx.newJsonParser().setPrettyPrint(true);
FhirValidator validator = ctx.newValidator();
validator.setValidateAgainstStandardSchema(true);
validator.setValidateAgainstStandardSchematron(true);
List<String> errors = ParallelTestingService.runInParallel((person) -> {
List<String> validationErrors = new ArrayList<String>();
Config.set("exporter.fhir_dstu2.export", "true");
FhirDstu2.TRANSACTION_BUNDLE = person.randBoolean();
String fhirJson = FhirDstu2.convertToFHIRJson(person, System.currentTimeMillis());
// (these should have been converted into URIs)
if (fhirJson.contains("SNOMED-CT")) {
validationErrors.add("JSON contains unconverted references to 'SNOMED-CT' (should be URIs)");
}
// let's crack open the Bundle and validate
// each individual entry.resource to get context-sensitive error
// messages...
Bundle bundle = parser.parseResource(Bundle.class, fhirJson);
for (Entry entry : bundle.getEntry()) {
ValidationResult eresult = validator.validateWithResult(entry.getResource());
if (!eresult.isSuccessful()) {
for (SingleValidationMessage emessage : eresult.getMessages()) {
if (emessage.getMessage().contains("start SHALL have a lower value than end")) {
continue;
}
System.out.println(parser.encodeResourceToString(entry.getResource()));
System.out.println("ERROR: " + emessage.getMessage());
validationErrors.add(emessage.getMessage());
}
}
if (entry.getResource() instanceof DiagnosticReport) {
DiagnosticReport report = (DiagnosticReport) entry.getResource();
if (report.getPerformer().isEmpty()) {
validationErrors.add("Performer is a required field on DiagnosticReport!");
}
}
}
if (!validationErrors.isEmpty()) {
Exporter.export(person, System.currentTimeMillis());
}
return validationErrors;
});
assertTrue("Validation of exported FHIR bundle failed: " + String.join("|", errors), errors.size() == 0);
}
use of ca.uhn.fhir.validation.SingleValidationMessage in project synthea by synthetichealth.
the class FHIRSTU3ExporterTest method testFHIRSTU3Export.
@Test
public void testFHIRSTU3Export() throws Exception {
TestHelper.loadTestProperties();
Generator.DEFAULT_STATE = Config.get("test_state.default", "Massachusetts");
Config.set("exporter.baseDirectory", tempFolder.newFolder().toString());
FhirContext ctx = FhirStu3.getContext();
IParser parser = ctx.newJsonParser().setPrettyPrint(true);
FhirValidator validator = ctx.newValidator();
validator.setValidateAgainstStandardSchema(true);
validator.setValidateAgainstStandardSchematron(true);
ValidationResources validationResources = new ValidationResources();
List<String> errors = ParallelTestingService.runInParallel((person) -> {
List<String> validationErrors = new ArrayList<String>();
TestHelper.exportOff();
Config.set("exporter.fhir_stu3.export", "true");
Config.set("exporter.fhir.use_shr_extensions", "true");
FhirStu3.TRANSACTION_BUNDLE = person.randBoolean();
String fhirJson = FhirStu3.convertToFHIRJson(person, System.currentTimeMillis());
// (these should have been converted into URIs)
if (fhirJson.contains("SNOMED-CT")) {
validationErrors.add("JSON contains unconverted references to 'SNOMED-CT' (should be URIs)");
}
// let's crack open the Bundle and validate
// each individual entry.resource to get context-sensitive error
// messages...
Bundle bundle = parser.parseResource(Bundle.class, fhirJson);
for (BundleEntryComponent entry : bundle.getEntry()) {
ValidationResult eresult = validator.validateWithResult(entry.getResource());
if (!eresult.isSuccessful()) {
for (SingleValidationMessage emessage : eresult.getMessages()) {
boolean valid = false;
if (emessage.getMessage().contains("@ Observation obs-7")) {
/*
* The obs-7 invariant basically says that Observations should have values, unless
* they are made of components. This test replaces an invalid XPath expression
* that was causing correct instances to fail validation.
*/
valid = validateObs7((Observation) entry.getResource());
} else if (emessage.getMessage().contains("@ Condition con-4")) {
/*
* The con-4 invariant says "If condition is abated, then clinicalStatus must be
* either inactive, resolved, or remission" which is very clear and sensical.
* However, the XPath expression does not evaluate correctly for valid instances,
* so we must manually validate.
*/
valid = validateCon4((Condition) entry.getResource());
} else if (emessage.getMessage().contains("@ MedicationRequest mps-1")) {
/*
* The mps-1 invariant says MedicationRequest.requester.onBehalfOf can only be
* specified if MedicationRequest.requester.agent is practitioner or device.
* But the invariant is poorly written and does not correctly handle references
* starting with "urn:uuid"
*/
// ignore this error
valid = true;
} else if (emessage.getMessage().contains("per-1: If present, start SHALL have a lower value than end")) {
/*
* The per-1 invariant does not account for daylight savings time... so, if the
* daylight savings switch happens between the start and end, the validation
* fails, even if it is valid.
*/
// ignore this error
valid = true;
}
if (!valid) {
System.out.println(parser.encodeResourceToString(entry.getResource()));
System.out.println("ERROR: " + emessage.getMessage());
validationErrors.add(emessage.getMessage());
}
}
}
// Check ExplanationOfBenefit Resources against BlueButton
if (entry.getResource().fhirType().equals("ExplanationOfBenefit")) {
ValidationResult bbResult = validationResources.validateSTU3(entry.getResource());
for (SingleValidationMessage message : bbResult.getMessages()) {
if (message.getMessage().contains("extension https://bluebutton.cms.gov/assets")) {
/*
* The instance validator complains about the BlueButton extensions, ignore
*/
continue;
} else if (message.getSeverity() == ResultSeverityEnum.ERROR) {
if (!(message.getMessage().contains("Element 'ExplanationOfBenefit.id': minimum required = 1, but only found 0") || message.getMessage().contains("Could not verify slice for profile"))) {
// For some reason the validator is not detecting the IDs on the resources,
// even though they appear to be present while debugging and during normal
// operations.
System.out.println(message.getSeverity() + ": " + message.getMessage());
Assert.fail(message.getSeverity() + ": " + message.getMessage());
}
}
}
}
}
if (!validationErrors.isEmpty()) {
Exporter.export(person, System.currentTimeMillis());
}
return validationErrors;
});
assertTrue("Validation of exported FHIR bundle failed: " + String.join("|", errors), errors.size() == 0);
}
use of ca.uhn.fhir.validation.SingleValidationMessage in project synthea by synthetichealth.
the class HospitalExporterTestR4 method testFHIRExport.
@Test
public void testFHIRExport() throws Exception {
FhirContext ctx = FhirR4.getContext();
FhirValidator validator = ctx.newValidator();
validator.setValidateAgainstStandardSchema(true);
validator.setValidateAgainstStandardSchematron(true);
File tempOutputFolder = tempFolder.newFolder();
Config.set("exporter.baseDirectory", tempOutputFolder.toString());
Config.set("exporter.hospital.fhir.export", "true");
Config.set("exporter.fhir.transaction_bundle", "true");
// set this manually, in case it has already been loaded.
FhirR4.TRANSACTION_BUNDLE = true;
TestHelper.loadTestProperties();
Generator.DEFAULT_STATE = Config.get("test_state.default", "Massachusetts");
Location location = new Location(Generator.DEFAULT_STATE, null);
Provider.clear();
Provider.loadProviders(location, 1L);
assertNotNull(Provider.getProviderList());
assertFalse(Provider.getProviderList().isEmpty());
Provider.getProviderList().get(0).incrementEncounters(EncounterType.WELLNESS, 0);
HospitalExporterR4.export(new Generator(), 0L);
File expectedExportFolder = tempOutputFolder.toPath().resolve("fhir").toFile();
assertTrue(expectedExportFolder.exists() && expectedExportFolder.isDirectory());
File expectedExportFile = expectedExportFolder.toPath().resolve("hospitalInformation0.json").toFile();
assertTrue(expectedExportFile.exists() && expectedExportFile.isFile());
FileReader fileReader = new FileReader(expectedExportFile.getPath());
BufferedReader bufferedReader = new BufferedReader(fileReader);
StringBuilder fhirJson = new StringBuilder();
String line = null;
while ((line = bufferedReader.readLine()) != null) {
fhirJson.append(line);
}
bufferedReader.close();
IBaseResource resource = ctx.newJsonParser().parseResource(fhirJson.toString());
ValidationResult result = validator.validateWithResult(resource);
if (result.isSuccessful() == false) {
for (SingleValidationMessage message : result.getMessages()) {
System.out.println(message.getSeverity().toString() + ": " + message.getMessage());
}
}
assertTrue(result.isSuccessful());
}
Aggregations