Skip to content

Commit

Permalink
Neha | bdshr-989 | increasing/decreasing the error level for all entr…
Browse files Browse the repository at this point in the history
…ies in bundle. Decreasing error level for MedicationOrderAction extension.
  • Loading branch information
Nehashri committed Oct 29, 2015
1 parent ed0ebfa commit c26489e
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component
public class FhirResourceValidator {
Expand All @@ -27,8 +29,8 @@ public class FhirResourceValidator {
private TRConceptValidator trConceptValidator;
private volatile FhirValidator fhirValidator;
private ShrProfileValidationSupport shrProfileValidationSupport;
private List<String> resourceFieldErrors = new ArrayList<>();
private Map<String, String> extensionFieldErrors = new HashMap<>();
private List<Pattern> resourceFieldErrors = new ArrayList<>();
private Map<Pattern, String> extensionFieldErrors = new HashMap<>();

@Autowired
public FhirResourceValidator(FhirFeedUtil fhirUtil, TRConceptValidator trConceptValidator, ShrProfileValidationSupport shrProfileValidationSupport) {
Expand All @@ -39,12 +41,13 @@ public FhirResourceValidator(FhirFeedUtil fhirUtil, TRConceptValidator trConcept
}

private void initFieldErrorChecks() {
this.resourceFieldErrors.add("/f:Bundle/f:entry/f:resource/f:Condition/f:category");
this.resourceFieldErrors.add("/f:Bundle/f:entry/f:resource/f:Condition/f:code/f:coding");
this.resourceFieldErrors.add("/f:Bundle/f:entry/f:resource/f:Condition/f:clinicalStatus");
this.resourceFieldErrors.add(Pattern.compile("/f:Bundle/f:entry(\\[\\d+\\])*/f:resource/f:Condition/f:category"));
this.resourceFieldErrors.add(Pattern.compile("/f:Bundle/f:entry(\\[\\d+\\])*/f:resource/f:Condition/f:code/f:coding"));
this.resourceFieldErrors.add(Pattern.compile("/f:Bundle/f:entry(\\[\\d+\\])*/f:resource/f:Condition/f:clinicalStatus"));

this.extensionFieldErrors.put("/f:Bundle/f:entry/f:resource/f:MedicationOrder/f:dosageInstruction/f:timing/f:extension", "https://sharedhealth.atlassian.net/wiki/display/docs/fhir-extensions#TimingScheduledDate");
this.extensionFieldErrors.put("/f:Bundle/f:entry/f:resource/f:MedicationOrder/f:dosageInstruction/f:extension", "https://sharedhealth.atlassian.net/wiki/display/docs/fhir-extensions#DosageInstructionCustomDosage");
this.extensionFieldErrors.put(Pattern.compile("/f:Bundle/f:entry(\\[\\d+\\])*/f:resource/f:MedicationOrder/f:dosageInstruction(\\[\\d+\\])*/f:timing/f:extension(\\[\\d+\\])*"), "https://sharedhealth.atlassian.net/wiki/display/docs/fhir-extensions#TimingScheduledDate");
this.extensionFieldErrors.put(Pattern.compile("/f:Bundle/f:entry(\\[\\d+\\])*/f:resource/f:MedicationOrder/f:dosageInstruction(\\[\\d+\\])*/f:extension(\\[\\d+\\])*"), "https://sharedhealth.atlassian.net/wiki/display/docs/fhir-extensions#DosageInstructionCustomDosage");
this.extensionFieldErrors.put(Pattern.compile("/f:Bundle/f:entry(\\[\\d+\\])*/f:resource/f:MedicationOrder/f:extension(\\[\\d+\\])*"), "https://sharedhealth.atlassian.net/wiki/display/docs/fhir-extensions#MedicationOrderAction");
}

public FhirValidationResult validate(Bundle bundle) {
Expand All @@ -62,8 +65,8 @@ private void checkValidationResult(FhirValidationResult validationResult) {

private void checkForExtensionErrors(FhirValidationResult validationResult) {
for (SingleValidationMessage validationMessage : validationResult.getMessages()) {
if (extensionFieldErrors.containsKey(validationMessage.getLocationString())
&& validationMessage.getMessage().contains(extensionFieldErrors.get(validationMessage.getLocationString()))) {
String extensionUrlForLocation = getExtensionForLocationError(validationMessage.getLocationString());
if (extensionUrlForLocation != null && validationMessage.getMessage().contains(extensionUrlForLocation)) {
if (validationMessage.getSeverity().ordinal() >= ResultSeverityEnum.ERROR.ordinal()) {
validationMessage.setSeverity(ResultSeverityEnum.WARNING);
}
Expand All @@ -73,14 +76,30 @@ private void checkForExtensionErrors(FhirValidationResult validationResult) {

private void checkForConditionErrors(FhirValidationResult validationResult) {
for (SingleValidationMessage validationMessage : validationResult.getMessages()) {
if (resourceFieldErrors.contains(validationMessage.getLocationString())) {
if (isPossibleResourceFieldError(validationMessage.getLocationString())) {
if (validationMessage.getSeverity().ordinal() <= ResultSeverityEnum.WARNING.ordinal()) {
validationMessage.setSeverity(ResultSeverityEnum.ERROR);
}
}
}
}

private String getExtensionForLocationError(String locationString) {
for (Pattern extensionFieldErrorLocationPattern : extensionFieldErrors.keySet()) {
Matcher matcher = extensionFieldErrorLocationPattern.matcher(locationString);
if (matcher.matches()) return extensionFieldErrors.get(extensionFieldErrorLocationPattern);
}
return null;
}

private boolean isPossibleResourceFieldError(String locationString) {
for (Pattern resourceFieldErrorPattern : resourceFieldErrors) {
Matcher matcher = resourceFieldErrorPattern.matcher(locationString);
if (matcher.matches()) return true;
}
return false;
}

/**
* This is required since the InstanceValidator does not raise a severity.error on concept validation failure.
* InstanceValidator.checkCodeableConcept() line number 225
Expand All @@ -98,9 +117,10 @@ private void checkForConceptValidationError(FhirValidationResult validationResul
}

private static String getTerminologySystem(String message) {
if (message.contains("Unable to validate code")) {
String substring = message.substring(message.indexOf("in code system"));
return StringUtils.remove(StringUtils.removeStart(substring, "in code system"), "\"");
Pattern pattern = Pattern.compile("Unable to validate code \"(.*)\" in code system \"(?<TRSERVERURL>.*)\"");
Matcher matcher = pattern.matcher(message);
if(matcher.matches()) {
return matcher.group("TRSERVERURL");
}
return "";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,13 +273,19 @@ public void shouldRejectEncounterWithInvalidDiagnosisCategoryAndStatusAndSystem(
FileUtil.asString("xmls/encounters/dstu2/p98001046534_encounter_with_localRefs_invalidCondition.xml"));
validationContext = new EncounterValidationContext(encounterBundle, new FhirFeedUtil());
EncounterValidationResponse response = validator.validate(validationContext);
assertEquals(6, response.getErrors().size());
assertFailureInResponse("/f:Bundle/f:entry/f:resource/f:Condition/f:code/f:coding/f:system",
"@value cannot be empty", false, response);
assertFailureInResponse("/f:Bundle/f:entry[3]/f:resource/f:Condition/f:code/f:coding/f:system",
"@value cannot be empty", false, response);
assertFailureInResponse("/f:Bundle/f:entry/f:resource/f:Condition/f:category",
"None of the codes are in the example value set http://hl7.org/fhir/ValueSet/condition-category", true, response);
assertFailureInResponse("/f:Bundle/f:entry[3]/f:resource/f:Condition/f:category",
"None of the codes are in the example value set http://hl7.org/fhir/ValueSet/condition-category", true, response);
assertFailureInResponse("/f:Bundle/f:entry/f:resource/f:Condition/f:clinicalStatus",
"Coded value wrong is not in value set http://hl7.org/fhir/ValueSet/condition-clinical", true, response);
assertEquals(3, response.getErrors().size());
assertFailureInResponse("/f:Bundle/f:entry[3]/f:resource/f:Condition/f:clinicalStatus",
"Coded value wrong is not in value set http://hl7.org/fhir/ValueSet/condition-clinical", true, response);
}

@Test
Expand Down Expand Up @@ -325,7 +331,7 @@ public void shouldRejectInvalidRelationshipTypeInFamilyMemberHistory() throws Ex
assertFalse(response.isSuccessful());
assertEquals(1, response.getErrors().size());
assertFailureInResponse("/f:Bundle/f:entry/f:resource/f:FamilyMemberHistory/f:relationship",
"Unable to validate code \"FT\" in code system \"http://localhost:9997/openmrs/ws/rest/v1/tr/vs/Relationship-Type\"", true, response);
"Unable to validate code \"INVALID\" in code system \"http://localhost:9997/openmrs/ws/rest/v1/tr/vs/Relationship-Type\"", true, response);
}

@Test
Expand All @@ -343,7 +349,6 @@ public void shouldValidateMedicationOrderWithCustomDosageExtension() throws Exce
FileUtil.asString("xmls/encounters/dstu2/p98001046534_encounter_with_medication_order_custom_dosage.xml"));
validationContext = new EncounterValidationContext(encounterBundle, new FhirFeedUtil());
EncounterValidationResponse response = validator.validate(validationContext);
debugEncounterValidationResponse(response);
assertTrue(response.isSuccessful());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
<relationship>
<coding>
<system value="http://localhost:9997/openmrs/ws/rest/v1/tr/vs/Relationship-Type"/>
<code value="FT"/>
<code value="INVALID"/>
<display value="father"/>
</coding>
</relationship>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@
<display value="Encounter"/>
</entry>
</section>
<section>
<entry>
<reference value="urn:uuid:04e9f319-980c-4ff1-9942-bcb5e2b5243b"/>
<display value="Diagnosis"/>
</entry>
</section>
<section>
<entry>
<reference value="urn:uuid:04e9f317-680c-4ff1-9942-bcb5e2b5243b"/>
Expand Down Expand Up @@ -76,6 +82,44 @@
</Encounter>
</resource>
</entry>
<entry>
<fullUrl value="urn:uuid:04e9f319-980c-4ff1-9942-bcb5e2b5243b"/>
<resource>
<Condition xmlns="http://hl7.org/fhir">
<id value="04e9f319-980c-4ff1-9942-bcb5e2b5243b"/>
<identifier>
<value value="urn:uuid:04e9f319-980c-4ff1-9942-bcb5e2b5243b"/>
</identifier>
<patient>
<reference value="http://localhost:9997/api/default/patients/98001046534"/>
<display value="98001046534"/>
</patient>
<encounter>
<reference value="urn:uuid:dd4d51ac-d4b6-42e4-8b50-fa88af41a3e3"/>
</encounter>
<asserter>
<reference value="http://localhost:9997/providers/19.json"/>
</asserter>
<dateRecorded value="2015-09-04"/>
<code>
<coding>
<system value=""/>
<code value="A90"/>
<display value="Dengue Fever"/>
</coding>
</code>
<category>
<coding>
<system value="http://hl7.org/fhir/condition-category"/>
<code value="invalid"/>
<display value="invalid-category"/>
</coding>
</category>
<clinicalStatus value="wrong"/>
<verificationStatus value="provisional"/>
</Condition>
</resource>
</entry>
<entry>
<fullUrl value="urn:uuid:04e9f317-680c-4ff1-9942-bcb5e2b5243b"/>
<resource>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@
<resource>
<MedicationOrder xmlns="http://hl7.org/fhir">
<id value="e461943b-7ad6-4b41-9730-70b8fc452f45"/>
<extension
url="https://sharedhealth.atlassian.net/wiki/display/docs/fhir-extensions#MedicationOrderAction">
<valueString value="NEW"/>
</extension>
<identifier>
<value value="urn:uuid:e461943b-7ad6-4b41-9730-70b8fc452f45"/>
</identifier>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@
<resource>
<MedicationOrder xmlns="http://hl7.org/fhir">
<id value="e461943b-7ad6-4b41-9730-70b8fc452f45"/>
<extension
url="https://sharedhealth.atlassian.net/wiki/display/docs/fhir-extensions#MedicationOrderAction">
<valueString value="NEW"/>
</extension>
<identifier>
<value value="urn:uuid:e461943b-7ad6-4b41-9730-70b8fc452f45"/>
</identifier>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@
<display value="Encounter"/>
</entry>
</section>
<section>
<entry>
<reference value="urn:uuid:3461943b-7ad6-4b41-9730-70b83c332f43"/>
<display value="Medication Order"/>
</entry>
</section>
<section>
<entry>
<reference value="urn:uuid:e461943b-7ad6-4b41-9730-70b8fc452f45"/>
Expand Down Expand Up @@ -76,11 +82,70 @@
</Encounter>
</resource>
</entry>
<entry>
<fullUrl value="urn:uuid:3461943b-7ad6-4b41-9730-70b83c332f43"/>
<resource>
<MedicationOrder xmlns="http://hl7.org/fhir">
<id value="3461943b-7ad6-4b41-9730-70b83c332f43"/>
<identifier>
<value value="urn:uuid:3461943b-7ad6-4b41-9730-70b83c332f43"/>
</identifier>
<dateWritten value="2015-09-22T17:09:54.000+05:30"/>
<status value="active"/>
<patient>
<reference value="http://localhost:9997/api/default/patients/98001046534"/>
<display value="98001046534"/>
</patient>
<prescriber>
<reference value="http://localhost:9997/providers/19.json"/>
</prescriber>
<encounter>
<reference value="urn:uuid:34ba3e1c-55c0-434d-b74b-b1bfe6472d4c"/>
</encounter>
<medicationCodeableConcept>
<coding>
<system value="http://localhost:9997/openmrs/ws/rest/v1/tr/drugs/23d7e743-75bd-4a25-8f34-bd849bd50394"/>
<code value="23d7e743-75bd-4a25-8f34-bd849bd50394"/>
<display value="Paracetamol"/>
</coding>
</medicationCodeableConcept>
<dosageInstruction>
<timing>
<repeat>
<boundsQuantity>
<value value="3"/>
<system value="http://unitsofmeasure.org"/>
<code value="d"/>
</boundsQuantity>
<frequency value="2"/>
<period value="7"/>
<periodUnits value="h"/>
</repeat>
</timing>
<asNeededBoolean value="false"/>
<doseQuantity>
<value value="1"/>
<unit value="mg"/>
</doseQuantity>
</dosageInstruction>
<dispenseRequest>
<quantity>
<value value="192.0"/>
<unit value="mg"/>
</quantity>
</dispenseRequest>
</MedicationOrder>
</resource>
</entry>
<entry>
<fullUrl value="urn:uuid:e461943b-7ad6-4b41-9730-70b8fc452f45"/>
<resource>
<MedicationOrder xmlns="http://hl7.org/fhir">
<id value="e461943b-7ad6-4b41-9730-70b8fc452f45"/>
<extension
url="https://sharedhealth.atlassian.net/wiki/display/docs/fhir-extensions#MedicationOrderAction">
<valueString value="NEW"/>
</extension>
<identifier>
<value value="urn:uuid:e461943b-7ad6-4b41-9730-70b8fc452f45"/>
</identifier>
Expand Down Expand Up @@ -121,7 +186,7 @@
</timing>
<asNeededBoolean value="false"/>
<doseQuantity>
<value value="10"/>
<value value="1"/>
<unit value="Pill"/>
</doseQuantity>
</dosageInstruction>
Expand Down

0 comments on commit c26489e

Please sign in to comment.