use of org.hl7.fhir.r5.utils.validation.BundleValidationRule in project org.hl7.fhir.core by hapifhir.
the class Params method loadCliContext.
/**
* TODO Don't do this all in one for loop. Use the above methods.
*/
public static CliContext loadCliContext(String[] args) throws Exception {
CliContext cliContext = new CliContext();
// load the parameters - so order doesn't matter
for (int i = 0; i < args.length; i++) {
if (args[i].equals(VERSION)) {
cliContext.setSv(VersionUtilities.getCurrentPackageVersion(args[++i]));
} else if (args[i].equals(OUTPUT)) {
if (i + 1 == args.length)
throw new Error("Specified -output without indicating output file");
else
cliContext.setOutput(args[++i]);
} else if (args[i].equals(HTML_OUTPUT)) {
if (i + 1 == args.length)
throw new Error("Specified -html-output without indicating output file");
else
cliContext.setHtmlOutput(args[++i]);
} else if (args[i].equals(PROXY)) {
// ignore next parameter
i++;
} else if (args[i].equals(PROXY_AUTH)) {
i++;
} else if (args[i].equals(PROFILE)) {
String p = null;
if (i + 1 == args.length) {
throw new Error("Specified -profile without indicating profile source");
} else {
p = args[++i];
cliContext.addProfile(p);
}
} else if (args[i].equals(BUNDLE)) {
String p = null;
String r = null;
if (i + 1 == args.length) {
throw new Error("Specified -profile without indicating bundle rule ");
} else {
r = args[++i];
}
if (i + 1 == args.length) {
throw new Error("Specified -profile without indicating profile source");
} else {
p = args[++i];
}
cliContext.getBundleValidationRules().add(new BundleValidationRule(r, p));
} else if (args[i].equals(QUESTIONNAIRE)) {
if (i + 1 == args.length)
throw new Error("Specified -questionnaire without indicating questionnaire mode");
else {
String q = args[++i];
cliContext.setQuestionnaireMode(QuestionnaireMode.fromCode(q));
}
} else if (args[i].equals(LEVEL)) {
if (i + 1 == args.length)
throw new Error("Specified -level without indicating level mode");
else {
String q = args[++i];
cliContext.setLevel(ValidationLevel.fromCode(q));
}
} else if (args[i].equals(NATIVE)) {
cliContext.setDoNative(true);
} else if (args[i].equals(ASSUME_VALID_REST_REF)) {
cliContext.setAssumeValidRestReferences(true);
} else if (args[i].equals(DEBUG)) {
cliContext.setDoDebug(true);
} else if (args[i].equals(SCT)) {
cliContext.setSnomedCT(args[++i]);
} else if (args[i].equals(RECURSE)) {
cliContext.setRecursive(true);
} else if (args[i].equals(SHOW_MESSAGES_FROM_REFERENCES)) {
cliContext.setShowMessagesFromReferences(true);
} else if (args[i].equals(LOCALE)) {
if (i + 1 == args.length) {
throw new Error("Specified -locale without indicating locale");
} else {
cliContext.setLocale(new Locale(args[++i]));
}
} else if (args[i].equals(EXTENSIONS)) {
cliContext.getExtensions().add(args[++i]);
} else if (args[i].equals(NO_INTERNAL_CACHING)) {
cliContext.setNoInternalCaching(true);
} else if (args[i].equals(NO_EXTENSIBLE_BINDING_WARNINGS)) {
cliContext.setNoExtensibleBindingMessages(true);
} else if (args[i].equals(NO_UNICODE_BIDI_CONTROL_CHARS)) {
cliContext.setNoUnicodeBiDiControlChars(true);
} else if (args[i].equals(NO_INVARIANTS)) {
cliContext.setNoInvariants(true);
} else if (args[i].equals(WANT_INVARIANTS_IN_MESSAGES)) {
cliContext.setWantInvariantsInMessages(true);
} else if (args[i].equals(HINT_ABOUT_NON_MUST_SUPPORT)) {
cliContext.setHintAboutNonMustSupport(true);
} else if (args[i].equals(TO_VERSION)) {
cliContext.setTargetVer(args[++i]);
cliContext.setMode(EngineMode.VERSION);
} else if (args[i].equals(DO_NATIVE)) {
cliContext.setCanDoNative(true);
} else if (args[i].equals(NO_NATIVE)) {
cliContext.setCanDoNative(false);
} else if (args[i].equals(TRANSFORM)) {
cliContext.setMap(args[++i]);
cliContext.setMode(EngineMode.TRANSFORM);
} else if (args[i].equals(COMPILE)) {
cliContext.setMap(args[++i]);
cliContext.setMode(EngineMode.COMPILE);
} else if (args[i].equals(NARRATIVE)) {
cliContext.setMode(EngineMode.NARRATIVE);
} else if (args[i].equals(SPREADSHEET)) {
cliContext.setMode(EngineMode.SPREADSHEET);
} else if (args[i].equals(SNAPSHOT)) {
cliContext.setMode(EngineMode.SNAPSHOT);
} else if (args[i].equals(SECURITY_CHECKS)) {
cliContext.setSecurityChecks(true);
} else if (args[i].equals(CRUMB_TRAIL)) {
cliContext.setCrumbTrails(true);
} else if (args[i].equals(VERBOSE)) {
cliContext.setCrumbTrails(true);
} else if (args[i].equals(ALLOW_EXAMPLE_URLS)) {
String bl = args[++i];
if ("true".equals(bl)) {
cliContext.setAllowExampleUrls(true);
} else if ("false".equals(bl)) {
cliContext.setAllowExampleUrls(false);
} else {
throw new Error("Value for " + ALLOW_EXAMPLE_URLS + " not understood: " + bl);
}
} else if (args[i].equals(SHOW_TIMES)) {
cliContext.setShowTimes(true);
} else if (args[i].equals(OUTPUT_STYLE)) {
cliContext.setOutputStyle(args[++i]);
} else if (args[i].equals(SCAN)) {
cliContext.setMode(EngineMode.SCAN);
} else if (args[i].equals(TERMINOLOGY)) {
if (i + 1 == args.length)
throw new Error("Specified -tx without indicating terminology server");
else
cliContext.setTxServer("n/a".equals(args[++i]) ? null : args[i]);
} else if (args[i].equals(TERMINOLOGY_LOG)) {
if (i + 1 == args.length)
throw new Error("Specified -txLog without indicating file");
else
cliContext.setTxLog(args[++i]);
} else if (args[i].equals(TERMINOLOGY_CACHE)) {
if (i + 1 == args.length)
throw new Error("Specified -txCache without indicating file");
else
cliContext.setTxCache(args[++i]);
} else if (args[i].equals(LOG)) {
if (i + 1 == args.length)
throw new Error("Specified -log without indicating file");
else
cliContext.setMapLog(args[++i]);
} else if (args[i].equals(LANGUAGE)) {
if (i + 1 == args.length)
throw new Error("Specified -language without indicating language");
else
cliContext.setLang(args[++i]);
} else if (args[i].equals(IMPLEMENTATION_GUIDE) || args[i].equals(DEFINITION)) {
if (i + 1 == args.length)
throw new Error("Specified " + args[i] + " without indicating ig file");
else {
String s = args[++i];
String version = Common.getVersionFromIGName(null, s);
if (version == null) {
cliContext.addIg(s);
} else {
cliContext.setSv(version);
}
}
} else if (args[i].equals(MAP)) {
if (cliContext.getMap() == null) {
if (i + 1 == args.length)
throw new Error("Specified -map without indicating map file");
else
cliContext.setMap(args[++i]);
} else {
throw new Exception("Can only nominate a single -map parameter");
}
} else if (args[i].startsWith(X)) {
i++;
} else if (args[i].equals(CONVERT)) {
cliContext.setMode(EngineMode.CONVERT);
} else if (args[i].equals(FHIRPATH)) {
cliContext.setMode(EngineMode.FHIRPATH);
if (cliContext.getFhirpath() == null)
if (i + 1 == args.length)
throw new Error("Specified -fhirpath without indicating a FHIRPath expression");
else
cliContext.setFhirpath(args[++i]);
else
throw new Exception("Can only nominate a single -fhirpath parameter");
} else {
cliContext.addSource(args[i]);
}
}
return cliContext;
}
use of org.hl7.fhir.r5.utils.validation.BundleValidationRule in project org.hl7.fhir.core by hapifhir.
the class ValidationTests method test.
@SuppressWarnings("deprecation")
@Test
public void test() throws Exception {
CacheVerificationLogger logger = new CacheVerificationLogger();
long setup = System.nanoTime();
this.name = name;
System.out.println("---- " + name + " ----------------------------------------------------------------");
System.out.println("** Core: ");
String txLog = null;
if (content.has("txLog")) {
txLog = content.get("txLog").getAsString();
}
version = "5.0";
List<ValidationMessage> messages = new ArrayList<ValidationMessage>();
if (content.has("version")) {
version = content.get("version").getAsString();
}
version = VersionUtilities.getMajMin(version);
if (!ve.containsKey(version)) {
if (version.startsWith("5.0"))
ve.put(version, TestUtilities.getValidationEngine("hl7.fhir.r5.core#4.5.0", ValidationEngineTests.DEF_TX, txLog, FhirPublication.R5, true, "4.5.0"));
else if (version.startsWith("4.3"))
ve.put(version, TestUtilities.getValidationEngine("hl7.fhir.r4b.core#4.3.0", ValidationEngineTests.DEF_TX, txLog, FhirPublication.R4B, true, "4.3.0"));
else if (version.startsWith("4.0"))
ve.put(version, TestUtilities.getValidationEngine("hl7.fhir.r4.core#4.0.1", ValidationEngineTests.DEF_TX, txLog, FhirPublication.R4, true, "4.0.1"));
else if (version.startsWith("3.0"))
ve.put(version, TestUtilities.getValidationEngine("hl7.fhir.r3.core#3.0.2", ValidationEngineTests.DEF_TX, txLog, FhirPublication.STU3, true, "3.0.2"));
else if (version.startsWith("1.4"))
ve.put(version, TestUtilities.getValidationEngine("hl7.fhir.r2b.core#1.4.0", ValidationEngineTests.DEF_TX, txLog, FhirPublication.DSTU2016May, true, "1.4.0"));
else if (version.startsWith("1.0"))
ve.put(version, TestUtilities.getValidationEngine("hl7.fhir.r2.core#1.0.2", ValidationEngineTests.DEF_TX, txLog, FhirPublication.DSTU2, true, "1.0.2"));
else
throw new Exception("unknown version " + version);
}
vCurr = ve.get(version);
vCurr.getContext().getTxClient().setLogger(logger);
igLoader = new IgLoader(vCurr.getPcm(), vCurr.getContext(), vCurr.getVersion(), true);
if (TestingUtilities.fcontexts == null) {
TestingUtilities.fcontexts = new HashMap<>();
}
TestingUtilities.fcontexts.put(version, vCurr.getContext());
if (content.has("use-test") && !content.get("use-test").getAsBoolean())
return;
byte[] testCaseContent = TestingUtilities.loadTestResource("validator", JSONUtil.str(content, "file")).getBytes(StandardCharsets.UTF_8);
// load and process content
FhirFormat fmt = determineFormat(content, testCaseContent);
InstanceValidator val = vCurr.getValidator(fmt);
val.setWantCheckSnapshotUnchanged(true);
val.getContext().setClientRetryCount(4);
val.setDebug(false);
if (content.has("fetcher") && "standalone".equals(JSONUtil.str(content, "fetcher"))) {
val.setFetcher(vCurr);
vCurr.setFetcher(new StandAloneValidatorFetcher(vCurr.getPcm(), vCurr.getContext(), vCurr));
} else {
val.setFetcher(this);
}
val.setPolicyAdvisor(this);
if (content.has("allowed-extension-domain"))
val.getExtensionDomains().add(content.get("allowed-extension-domain").getAsString());
if (content.has("allowed-extension-domains"))
for (JsonElement a : content.getAsJsonArray("allowed-extension-domains")) val.getExtensionDomains().add(a.getAsString());
if (content.has("language"))
val.setValidationLanguage(content.get("language").getAsString());
else
val.setValidationLanguage(null);
if (content.has("default-version")) {
val.setBaseOptions(val.getBaseOptions().setVersionFlexible(content.get("default-version").getAsBoolean()));
} else {
val.setBaseOptions(val.getBaseOptions().setVersionFlexible(false));
}
if (content.has("packages")) {
for (JsonElement e : content.getAsJsonArray("packages")) {
String n = e.getAsString();
InputStream cnt = n.endsWith(".tgz") ? TestingUtilities.loadTestResourceStream("validator", n) : null;
if (cnt != null) {
igLoader.loadPackage(NpmPackage.fromPackage(cnt));
} else {
igLoader.loadIg(vCurr.getIgs(), vCurr.getBinaries(), n, true);
}
}
}
if (content.has("crumb-trail")) {
val.setCrumbTrails(content.get("crumb-trail").getAsBoolean());
}
if (content.has("supporting")) {
for (JsonElement e : content.getAsJsonArray("supporting")) {
String filename = e.getAsString();
String contents = TestingUtilities.loadTestResource("validator", filename);
CanonicalResource mr = (CanonicalResource) loadResource(filename, contents);
val.getContext().cacheResource(mr);
if (mr instanceof ImplementationGuide) {
val.getImplementationGuides().add((ImplementationGuide) mr);
}
}
}
val.getBundleValidationRules().clear();
if (content.has("bundle-param")) {
val.getBundleValidationRules().add(new BundleValidationRule(content.getAsJsonObject("bundle-param").get("rule").getAsString(), content.getAsJsonObject("bundle-param").get("profile").getAsString()));
}
if (content.has("profiles")) {
for (JsonElement je : content.getAsJsonArray("profiles")) {
String filename = je.getAsString();
String contents = TestingUtilities.loadTestResource("validator", filename);
StructureDefinition sd = loadProfile(filename, contents, messages, val.isDebug());
val.getContext().cacheResource(sd);
}
}
List<ValidationMessage> errors = new ArrayList<ValidationMessage>();
if (content.getAsJsonObject("java").has("debug")) {
val.setDebug(content.getAsJsonObject("java").get("debug").getAsBoolean());
} else {
val.setDebug(false);
}
if (content.has("best-practice")) {
val.setBestPracticeWarningLevel(BestPracticeWarningLevel.valueOf(content.get("best-practice").getAsString()));
}
if (content.has("examples")) {
val.setAllowExamples(content.get("examples").getAsBoolean());
} else {
val.setAllowExamples(true);
}
if (content.has("security-checks")) {
val.setSecurityChecks(content.get("security-checks").getAsBoolean());
}
if (content.has("logical") == false) {
val.setAssumeValidRestReferences(content.has("assumeValidRestReferences") ? content.get("assumeValidRestReferences").getAsBoolean() : false);
System.out.println(String.format("Start Validating (%d to set up)", (System.nanoTime() - setup) / 1000000));
val.validate(null, errors, new ByteArrayInputStream(testCaseContent), fmt);
System.out.println(val.reportTimes());
checkOutcomes(errors, content, null, name);
}
if (content.has("profile")) {
System.out.print("** Profile: ");
JsonObject profile = content.getAsJsonObject("profile");
if (profile.has("packages")) {
for (JsonElement e : profile.getAsJsonArray("packages")) {
igLoader.loadIg(vCurr.getIgs(), vCurr.getBinaries(), e.getAsString(), true);
}
}
if (profile.getAsJsonObject("java").has("debug")) {
val.setDebug(profile.getAsJsonObject("java").get("debug").getAsBoolean());
}
if (profile.has("supporting")) {
for (JsonElement e : profile.getAsJsonArray("supporting")) {
String filename = e.getAsString();
String contents = TestingUtilities.loadTestResource("validator", filename);
CanonicalResource mr = (CanonicalResource) loadResource(filename, contents);
val.getContext().cacheResource(mr);
if (mr instanceof ImplementationGuide) {
val.getImplementationGuides().add((ImplementationGuide) mr);
}
}
}
StructureDefinition sd = null;
String filename = profile.get("source").getAsString();
if (Utilities.isAbsoluteUrl(filename)) {
sd = val.getContext().fetchResource(StructureDefinition.class, filename);
} else {
String contents = TestingUtilities.loadTestResource("validator", filename);
System.out.println("Name: " + name + " - profile : " + profile.get("source").getAsString());
version = content.has("version") ? content.get("version").getAsString() : Constants.VERSION;
sd = loadProfile(filename, contents, messages, val.isDebug());
val.getContext().cacheResource(sd);
}
val.setAssumeValidRestReferences(profile.has("assumeValidRestReferences") ? profile.get("assumeValidRestReferences").getAsBoolean() : false);
List<ValidationMessage> errorsProfile = new ArrayList<ValidationMessage>();
val.validate(null, errorsProfile, new ByteArrayInputStream(testCaseContent), fmt, asSdList(sd));
System.out.println(val.reportTimes());
checkOutcomes(errorsProfile, profile, filename, name);
}
if (content.has("logical")) {
System.out.print("** Logical: ");
JsonObject logical = content.getAsJsonObject("logical");
if (logical.has("supporting")) {
for (JsonElement e : logical.getAsJsonArray("supporting")) {
String filename = e.getAsString();
String contents = TestingUtilities.loadTestResource("validator", filename);
CanonicalResource mr = (CanonicalResource) loadResource(filename, contents);
if (mr instanceof StructureDefinition) {
val.getContext().generateSnapshot((StructureDefinition) mr, true);
}
val.getContext().cacheResource(mr);
}
}
if (logical.has("packages")) {
for (JsonElement e : logical.getAsJsonArray("packages")) {
igLoader.loadIg(vCurr.getIgs(), vCurr.getBinaries(), e.getAsString(), true);
}
}
List<ValidationMessage> errorsLogical = new ArrayList<ValidationMessage>();
Element le = val.validate(null, errorsLogical, new ByteArrayInputStream(testCaseContent), fmt);
if (logical.has("expressions")) {
FHIRPathEngine fp = new FHIRPathEngine(val.getContext());
for (JsonElement e : logical.getAsJsonArray("expressions")) {
String exp = e.getAsString();
Assert.assertTrue(fp.evaluateToBoolean(null, le, le, le, fp.parse(exp)));
}
}
checkOutcomes(errorsLogical, logical, "logical", name);
}
logger.verifyHasNoRequests();
}
use of org.hl7.fhir.r5.utils.validation.BundleValidationRule in project org.hl7.fhir.core by hapifhir.
the class BundleValidator method validateBundle.
public void validateBundle(List<ValidationMessage> errors, Element bundle, NodeStack stack, boolean checkSpecials, ValidatorHostContext hostContext) {
List<Element> entries = new ArrayList<Element>();
bundle.getNamedChildren(ENTRY, entries);
String type = bundle.getNamedChildValue(TYPE);
type = StringUtils.defaultString(type);
if (entries.size() == 0) {
rule(errors, IssueType.INVALID, stack.getLiteralPath(), !(type.equals(DOCUMENT) || type.equals(MESSAGE)), I18nConstants.BUNDLE_BUNDLE_ENTRY_NOFIRST);
} else {
// Get the first entry, the MessageHeader
Element firstEntry = entries.get(0);
// Get the stack of the first entry
NodeStack firstStack = stack.push(firstEntry, 1, null, null);
String fullUrl = firstEntry.getNamedChildValue(FULL_URL);
if (type.equals(DOCUMENT)) {
Element resource = firstEntry.getNamedChild(RESOURCE);
if (rule(errors, IssueType.INVALID, firstEntry.line(), firstEntry.col(), stack.addToLiteralPath(ENTRY, PATH_ARG), resource != null, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOFIRSTRESOURCE)) {
String id = resource.getNamedChildValue(ID);
validateDocument(errors, entries, resource, firstStack.push(resource, -1, null, null), fullUrl, id);
}
if (!VersionUtilities.isThisOrLater(FHIRVersion._4_0_1.getDisplay(), bundle.getProperty().getStructure().getFhirVersion().getDisplay())) {
handleSpecialCaseForLastUpdated(bundle, errors, stack);
}
checkAllInterlinked(errors, entries, stack, bundle, true);
}
if (type.equals(MESSAGE)) {
Element resource = firstEntry.getNamedChild(RESOURCE);
String id = resource.getNamedChildValue(ID);
if (rule(errors, IssueType.INVALID, firstEntry.line(), firstEntry.col(), stack.addToLiteralPath(ENTRY, PATH_ARG), resource != null, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOFIRSTRESOURCE)) {
validateMessage(errors, entries, resource, firstStack.push(resource, -1, null, null), fullUrl, id);
}
checkAllInterlinked(errors, entries, stack, bundle, VersionUtilities.isR5Ver(context.getVersion()));
}
if (type.equals(SEARCHSET)) {
checkSearchSet(errors, bundle, entries, stack);
}
// We do not yet have rules requiring that the id and fullUrl match when dealing with messaging Bundles
// validateResourceIds(errors, entries, stack);
}
int count = 0;
Map<String, Integer> counter = new HashMap<>();
boolean fullUrlOptional = Utilities.existsInList(type, "transaction", "transaction-response", "batch", "batch-response");
for (Element entry : entries) {
NodeStack estack = stack.push(entry, count, null, null);
String fullUrl = entry.getNamedChildValue(FULL_URL);
String url = getCanonicalURLForEntry(entry);
String id = getIdForEntry(entry);
if (url != null) {
if (!(!url.equals(fullUrl) || (url.matches(uriRegexForVersion()) && url.endsWith("/" + id))) && !isV3orV2Url(url))
rule(errors, IssueType.INVALID, entry.line(), entry.col(), stack.addToLiteralPath(ENTRY, PATH_ARG), false, I18nConstants.BUNDLE_BUNDLE_ENTRY_MISMATCHIDURL, url, fullUrl, id);
rule(errors, IssueType.INVALID, entry.line(), entry.col(), stack.addToLiteralPath(ENTRY, PATH_ARG), !url.equals(fullUrl) || serverBase == null || (url.equals(Utilities.pathURL(serverBase, entry.getNamedChild(RESOURCE).fhirType(), id))), I18nConstants.BUNDLE_BUNDLE_ENTRY_CANONICAL, url, fullUrl);
}
if (!VersionUtilities.isR2Ver(context.getVersion())) {
rule(errors, IssueType.INVALID, entry.line(), entry.col(), estack.getLiteralPath(), fullUrlOptional || fullUrl != null, I18nConstants.BUNDLE_BUNDLE_ENTRY_FULLURL_REQUIRED);
}
// check bundle profile requests
if (entry.hasChild(RESOURCE)) {
String rtype = entry.getNamedChild(RESOURCE).fhirType();
int rcount = counter.containsKey(rtype) ? counter.get(rtype) + 1 : 0;
counter.put(rtype, rcount);
for (BundleValidationRule bvr : validator.getBundleValidationRules()) {
if (meetsRule(bvr, rtype, rcount, count)) {
StructureDefinition defn = validator.getContext().fetchResource(StructureDefinition.class, bvr.getProfile());
if (defn == null) {
throw new Error(validator.getContext().formatMessage(I18nConstants.BUNDLE_RULE_PROFILE_UNKNOWN, bvr.getRule(), bvr.getProfile()));
} else {
Element res = entry.getNamedChild(RESOURCE);
NodeStack rstack = estack.push(res, -1, null, null);
if (validator.isCrumbTrails()) {
res.addMessage(signpost(errors, IssueType.INFORMATIONAL, res.line(), res.col(), stack.getLiteralPath(), I18nConstants.VALIDATION_VAL_PROFILE_SIGNPOST_BUNDLE_PARAM, defn.getUrl()));
}
stack.resetIds();
validator.startInner(hostContext, errors, res, res, defn, rstack, false);
}
}
}
}
// todo: check specials
count++;
}
}
Aggregations