better logging on discriminator misses

This commit is contained in:
Grahame Grieve 2022-06-24 11:44:29 +02:00
parent 8769846d5d
commit ced9a748ad
2 changed files with 34 additions and 6 deletions

View File

@ -4,6 +4,9 @@ import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.context.SimpleWorkerContext; import org.hl7.fhir.r5.context.SimpleWorkerContext;
import org.hl7.fhir.r5.context.SystemOutLoggingService; import org.hl7.fhir.r5.context.SystemOutLoggingService;
import org.hl7.fhir.r5.context.TerminologyCache; import org.hl7.fhir.r5.context.TerminologyCache;
import org.hl7.fhir.r5.conformance.ProfileUtilities;
import org.hl7.fhir.r5.context.IWorkerContext.PackageVersion;
import org.hl7.fhir.r5.context.SimpleWorkerContext.PackageResourceLoader;
import org.hl7.fhir.r5.elementmodel.Manager; import org.hl7.fhir.r5.elementmodel.Manager;
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat; import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
import org.hl7.fhir.r5.formats.IParser; import org.hl7.fhir.r5.formats.IParser;
@ -12,6 +15,7 @@ import org.hl7.fhir.r5.formats.XmlParser;
import org.hl7.fhir.r5.model.*; import org.hl7.fhir.r5.model.*;
import org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity; import org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity;
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind; import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
import org.hl7.fhir.r5.renderers.spreadsheets.CodeSystemSpreadsheetGenerator; import org.hl7.fhir.r5.renderers.spreadsheets.CodeSystemSpreadsheetGenerator;
import org.hl7.fhir.r5.renderers.spreadsheets.ConceptMapSpreadsheetGenerator; import org.hl7.fhir.r5.renderers.spreadsheets.ConceptMapSpreadsheetGenerator;
import org.hl7.fhir.r5.renderers.spreadsheets.StructureDefinitionSpreadsheetGenerator; import org.hl7.fhir.r5.renderers.spreadsheets.StructureDefinitionSpreadsheetGenerator;
@ -24,8 +28,11 @@ import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.TimeTracker; import org.hl7.fhir.utilities.TimeTracker;
import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.VersionUtilities;
import org.hl7.fhir.utilities.i18n.I18nConstants;
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager; import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
import org.hl7.fhir.utilities.npm.NpmPackage;
import org.hl7.fhir.utilities.npm.ToolsVersion; import org.hl7.fhir.utilities.npm.ToolsVersion;
import org.hl7.fhir.utilities.npm.NpmPackage.PackageResourceInformation;
import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.hl7.fhir.validation.IgLoader; import org.hl7.fhir.validation.IgLoader;
import org.hl7.fhir.validation.ValidationEngine; import org.hl7.fhir.validation.ValidationEngine;
@ -39,6 +46,8 @@ import org.hl7.fhir.validation.cli.renderers.ValidationOutputRenderer;
import org.hl7.fhir.validation.cli.utils.EngineMode; import org.hl7.fhir.validation.cli.utils.EngineMode;
import org.hl7.fhir.validation.cli.utils.VersionSourceInformation; import org.hl7.fhir.validation.cli.utils.VersionSourceInformation;
import lombok.val;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
@ -46,7 +55,9 @@ import java.io.PrintStream;
import java.lang.management.ManagementFactory; import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean; import java.lang.management.MemoryMXBean;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
public class ValidationService { public class ValidationService {
@ -329,6 +340,8 @@ public class ValidationService {
IgLoader igLoader = new IgLoader(validator.getPcm(), validator.getContext(), validator.getVersion(), validator.isDebug()); IgLoader igLoader = new IgLoader(validator.getPcm(), validator.getContext(), validator.getVersion(), validator.isDebug());
System.out.println(" - " + validator.getContext().countAllCaches() + " resources (" + tt.milestone() + ")"); System.out.println(" - " + validator.getContext().countAllCaches() + " resources (" + tt.milestone() + ")");
igLoader.loadIg(validator.getIgs(), validator.getBinaries(), "hl7.terminology", false); igLoader.loadIg(validator.getIgs(), validator.getBinaries(), "hl7.terminology", false);
System.out.print(" Load R5 Extensions");
System.out.println(" - " + ProfileUtilities.loadR5Extensions(validator.getPcm(), validator.getContext()) + " resources (" + tt.milestone() + ")");
System.out.print(" Terminology server " + cliContext.getTxServer()); System.out.print(" Terminology server " + cliContext.getTxServer());
String txver = validator.setTerminologyServer(cliContext.getTxServer(), cliContext.getTxLog(), ver); String txver = validator.setTerminologyServer(cliContext.getTxServer(), cliContext.getTxLog(), ver);
System.out.println(" - Version " + txver + " (" + tt.milestone() + ")"); System.out.println(" - Version " + txver + " (" + tt.milestone() + ")");
@ -378,6 +391,8 @@ public class ValidationService {
} }
public String determineVersion(CliContext cliContext) throws Exception { public String determineVersion(CliContext cliContext) throws Exception {
return determineVersion(cliContext, null); return determineVersion(cliContext, null);
} }

View File

@ -4012,10 +4012,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
throw new DefinitionException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_MULTIPLE_TYPES_, discriminator, ed.getId(), profile.getUrl(), criteriaElement.typeSummary())); throw new DefinitionException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_MULTIPLE_TYPES_, discriminator, ed.getId(), profile.getUrl(), criteriaElement.typeSummary()));
} else } else
throw new DefinitionException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_NO_TYPES, discriminator, ed.getId(), profile.getUrl())); throw new DefinitionException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_NO_TYPES, discriminator, ed.getId(), profile.getUrl()));
if (discriminator.isEmpty()) if (discriminator.isEmpty()) {
expression.append(" and $this is " + type); expression.append(" and $this is " + type);
else } else {
expression.append(" and " + discriminator + " is " + type); expression.append(" and " + discriminator + " is " + type);
}
} else if (s.getType() == DiscriminatorType.PROFILE) { } else if (s.getType() == DiscriminatorType.PROFILE) {
if (criteriaElement.getType().size() == 0) { if (criteriaElement.getType().size() == 0) {
throw new DefinitionException(context.formatMessage(I18nConstants.PROFILE_BASED_DISCRIMINATORS_MUST_HAVE_A_TYPE__IN_PROFILE_, criteriaElement.getId(), profile.getUrl())); throw new DefinitionException(context.formatMessage(I18nConstants.PROFILE_BASED_DISCRIMINATORS_MUST_HAVE_A_TYPE__IN_PROFILE_, criteriaElement.getId(), profile.getUrl()));
@ -4036,12 +4037,13 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
expression.append(" and " + discriminator + ".conformsTo('" + list.get(0).getValue() + "')"); expression.append(" and " + discriminator + ".conformsTo('" + list.get(0).getValue() + "')");
} }
} else if (s.getType() == DiscriminatorType.EXISTS) { } else if (s.getType() == DiscriminatorType.EXISTS) {
if (criteriaElement.hasMin() && criteriaElement.getMin() >= 1) if (criteriaElement.hasMin() && criteriaElement.getMin() >= 1) {
expression.append(" and (" + discriminator + ".exists())"); expression.append(" and (" + discriminator + ".exists())");
else if (criteriaElement.hasMax() && criteriaElement.getMax().equals("0")) } else if (criteriaElement.hasMax() && criteriaElement.getMax().equals("0")) {
expression.append(" and (" + discriminator + ".exists().not())"); expression.append(" and (" + discriminator + ".exists().not())");
else } else {
throw new FHIRException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_ELEMENT_EXISTENCE_BUT_SLICE__NEITHER_SETS_MIN1_OR_MAX0, discriminator, ed.getId())); throw new FHIRException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_ELEMENT_EXISTENCE_BUT_SLICE__NEITHER_SETS_MIN1_OR_MAX0, discriminator, ed.getId()));
}
} else if (criteriaElement.hasFixed()) { } else if (criteriaElement.hasFixed()) {
buildFixedExpression(ed, expression, discriminator, criteriaElement); buildFixedExpression(ed, expression, discriminator, criteriaElement);
} else if (criteriaElement.hasPattern()) { } else if (criteriaElement.hasPattern()) {
@ -4072,12 +4074,13 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
} }
timeTracker.fpe(t); timeTracker.fpe(t);
ed.setUserData("slice.expression.cache", n); ed.setUserData("slice.expression.cache", n);
} else {
} }
ValidatorHostContext shc = hostContext.forSlicing(); ValidatorHostContext shc = hostContext.forSlicing();
boolean pass = evaluateSlicingExpression(shc, element, path, profile, n); boolean pass = evaluateSlicingExpression(shc, element, path, profile, n);
if (!pass) { if (!pass) {
slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, isProfile(slicer), (context.formatMessage(I18nConstants.DOES_NOT_MATCH_SLICE_, ed.getSliceName())), "discriminator = " + Utilities.escapeXml(n.toString()), null); slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, isProfile(slicer), (context.formatMessage(I18nConstants.DOES_NOT_MATCH_SLICE_, ed.getSliceName(), n.toString().substring(8).trim())), "discriminator = " + Utilities.escapeXml(n.toString()), null);
for (String url : shc.getSliceRecords().keySet()) { for (String url : shc.getSliceRecords().keySet()) {
slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, isProfile(slicer), slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, isProfile(slicer),
context.formatMessage(I18nConstants.DETAILS_FOR__MATCHING_AGAINST_PROFILE_, stack.getLiteralPath(), url), context.formatMessage(I18nConstants.DETAILS_FOR__MATCHING_AGAINST_PROFILE_, stack.getLiteralPath(), url),
@ -4089,6 +4092,16 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
return pass; return pass;
} }
private boolean isBaseDefinition(String url) {
boolean b = url.startsWith("http://hl7.org/fhir/") && !url.substring(40).contains("/");
return b;
}
private String descSD(String url) {
StructureDefinition sd = context.fetchResource(StructureDefinition.class, url);
return sd == null ? url : sd.present();
}
private boolean isProfile(ElementDefinition slicer) { private boolean isProfile(ElementDefinition slicer) {
if (slicer == null || !slicer.hasSlicing()) { if (slicer == null || !slicer.hasSlicing()) {
return false; return false;