better validation of derived valuesets + better handling of validation failures on UCUM when no terminology server
This commit is contained in:
parent
29e9f28add
commit
7166d55153
|
@ -51,6 +51,7 @@ import org.hl7.fhir.r5.conformance.ElementRedirection;
|
|||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities.AllowUnknownProfile;
|
||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities.ElementDefinitionCounter;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult;
|
||||
import org.hl7.fhir.r5.elementmodel.ObjectConverter;
|
||||
import org.hl7.fhir.r5.elementmodel.Property;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
|
@ -2599,9 +2600,23 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+base.getPath(), "Binding "+base.getBinding().getValueSet()+" could not be expanded", ValidationMessage.IssueSeverity.WARNING));
|
||||
else if (expDerived.getValueset() == null)
|
||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+derived.getPath(), "Binding "+derived.getBinding().getValueSet()+" could not be expanded", ValidationMessage.IssueSeverity.WARNING));
|
||||
else if (ToolingExtensions.hasExtension(expBase.getValueset().getExpansion(), ToolingExtensions.EXT_EXP_TOOCOSTLY))
|
||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+derived.getPath(), "Unable to check if "+derived.getBinding().getValueSet()+" is a proper subset of " +base.getBinding().getValueSet()+" - base value set is too large to check", ValidationMessage.IssueSeverity.WARNING));
|
||||
else if (!isSubset(expBase.getValueset(), expDerived.getValueset()))
|
||||
else if (ToolingExtensions.hasExtension(expBase.getValueset().getExpansion(), ToolingExtensions.EXT_EXP_TOOCOSTLY)) {
|
||||
if (ToolingExtensions.hasExtension(expDerived.getValueset().getExpansion(), ToolingExtensions.EXT_EXP_TOOCOSTLY) || expDerived.getValueset().getExpansion().getContains().size() > 100) {
|
||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+derived.getPath(), "Unable to check if "+derived.getBinding().getValueSet()+" is a proper subset of " +base.getBinding().getValueSet()+" - base value set is too large to check", ValidationMessage.IssueSeverity.WARNING));
|
||||
} else {
|
||||
boolean ok = true;
|
||||
for (ValueSetExpansionContainsComponent cc : expDerived.getValueset().getExpansion().getContains()) {
|
||||
ValidationResult vr = context.validateCode(null, cc.getSystem(), cc.getVersion(), cc.getCode(), null, baseVs);
|
||||
if (!vr.isOk()) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+derived.getPath(), "Binding "+derived.getBinding().getValueSet()+" is not a subset of binding "+base.getBinding().getValueSet(), ValidationMessage.IssueSeverity.ERROR));
|
||||
}
|
||||
}
|
||||
} else if (!isSubset(expBase.getValueset(), expDerived.getValueset()))
|
||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+derived.getPath(), "Binding "+derived.getBinding().getValueSet()+" is not a subset of binding "+base.getBinding().getValueSet(), ValidationMessage.IssueSeverity.ERROR));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1066,6 +1066,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
Set<String> unknownSystems = new HashSet<>();
|
||||
|
||||
String localError = null;
|
||||
String localWarning = null;
|
||||
if (options.isUseClient()) {
|
||||
// ok, first we try to validate locally
|
||||
try {
|
||||
|
@ -1080,7 +1081,11 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
return res;
|
||||
}
|
||||
} catch (VSCheckerException e) {
|
||||
localError = e.getMessage();
|
||||
if (e.isWarning()) {
|
||||
localWarning = e.getMessage();
|
||||
} else {
|
||||
localError = e.getMessage();
|
||||
}
|
||||
if (e.getIssues() != null) {
|
||||
issues.addAll(e.getIssues());
|
||||
}
|
||||
|
@ -1097,8 +1102,15 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
return new ValidationResult(IssueSeverity.ERROR, localError, TerminologyServiceErrorClass.UNKNOWN, issues);
|
||||
}
|
||||
}
|
||||
if (localWarning != null && tcc.getClient() == null) {
|
||||
return new ValidationResult(IssueSeverity.WARNING,formatMessage(I18nConstants.UNABLE_TO_VALIDATE_CODE_WITHOUT_USING_SERVER, localWarning), TerminologyServiceErrorClass.BLOCKED_BY_OPTIONS, issues);
|
||||
}
|
||||
if (!options.isUseServer()) {
|
||||
return new ValidationResult(IssueSeverity.WARNING,formatMessage(I18nConstants.UNABLE_TO_VALIDATE_CODE_WITHOUT_USING_SERVER, localError), TerminologyServiceErrorClass.BLOCKED_BY_OPTIONS, issues);
|
||||
if (localWarning != null) {
|
||||
return new ValidationResult(IssueSeverity.WARNING,formatMessage(I18nConstants.UNABLE_TO_VALIDATE_CODE_WITHOUT_USING_SERVER, localWarning), TerminologyServiceErrorClass.BLOCKED_BY_OPTIONS, issues);
|
||||
} else {
|
||||
return new ValidationResult(IssueSeverity.WARNING,formatMessage(I18nConstants.UNABLE_TO_VALIDATE_CODE_WITHOUT_USING_SERVER, localError), TerminologyServiceErrorClass.BLOCKED_BY_OPTIONS, issues);
|
||||
}
|
||||
}
|
||||
String codeKey = getCodeKey(code);
|
||||
if (unsupportedCodeSystems.contains(codeKey)) {
|
||||
|
|
|
@ -8,16 +8,27 @@ import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent;
|
|||
public class VSCheckerException extends FHIRException {
|
||||
|
||||
private List<OperationOutcomeIssueComponent> issues;
|
||||
private boolean warning;
|
||||
|
||||
public VSCheckerException(String message, List<OperationOutcomeIssueComponent> issues) {
|
||||
super(message);
|
||||
this.issues = issues;
|
||||
}
|
||||
|
||||
public VSCheckerException(String message, List<OperationOutcomeIssueComponent> issues, boolean warning) {
|
||||
super(message);
|
||||
this.issues = issues;
|
||||
this.warning = warning;
|
||||
}
|
||||
|
||||
public List<OperationOutcomeIssueComponent> getIssues() {
|
||||
return issues;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = -5889505119633054187L;
|
||||
|
||||
public boolean isWarning() {
|
||||
return warning;
|
||||
}
|
||||
|
||||
}
|
|
@ -435,7 +435,7 @@ public class ValueSetValidator {
|
|||
if (cs!=null && cs.getContent() != CodeSystemContentMode.COMPLETE) {
|
||||
warningMessage = "Resolved system "+system+(cs.hasVersion() ? " (v"+cs.getVersion()+")" : "")+", but the definition is not complete";
|
||||
if (!inExpansion && cs.getContent() != CodeSystemContentMode.FRAGMENT) { // we're going to give it a go if it's a fragment
|
||||
throw new VSCheckerException(warningMessage, null);
|
||||
throw new VSCheckerException(warningMessage, null, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue