From 8c0523f3fa59849a792a8d90995cdde45a3d619e Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Fri, 13 Nov 2020 14:36:10 +1100 Subject: [PATCH] Fix bug in unknown URL handling that could cause significant delays in validation (>1min / unknown URL) --- .../npm/FilesystemPackageCacheManager.java | 20 +++++++- .../services/StandAloneValidatorFetcher.java | 47 ++++++++++++------- .../cli/services/ValidationService.java | 1 + 3 files changed, 50 insertions(+), 18 deletions(-) diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/FilesystemPackageCacheManager.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/FilesystemPackageCacheManager.java index 87fd9b28f..fdb9338c2 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/FilesystemPackageCacheManager.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/FilesystemPackageCacheManager.java @@ -41,6 +41,7 @@ import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.json.JSONUtil; +import org.hl7.fhir.utilities.json.JsonTrackingParser; import org.hl7.fhir.utilities.npm.NpmPackage.NpmPackageFolder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -549,7 +550,9 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple @Override public String getPackageId(String canonicalUrl) throws IOException { - String retVal = super.getPackageId(canonicalUrl); + String retVal = findCanonicalInLocalCache(canonicalUrl); + + retVal = super.getPackageId(canonicalUrl); if (retVal == null) { retVal = getPackageIdFromBuildList(canonicalUrl); @@ -559,6 +562,21 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple } + public String findCanonicalInLocalCache(String canonicalUrl) { + try { + for (String pf : listPackages()) { + if (new File(Utilities.path(cacheFolder, pf, "package", "package.json")).exists()) { + JsonObject npm = JsonTrackingParser.parseJsonFile(Utilities.path(cacheFolder, pf, "package", "package.json")); + if (canonicalUrl.equals(JSONUtil.str(npm, "canonical"))) { + return JSONUtil.str(npm, "name"); + } + } + } + } catch (IOException e) { + } + return null; + } + // ========================= Package Mgmt API ======================================================================= private String getPackageIdFromBuildList(String canonical) throws IOException { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/StandAloneValidatorFetcher.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/StandAloneValidatorFetcher.java index 904ec8dca..f76fa0f8d 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/StandAloneValidatorFetcher.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/StandAloneValidatorFetcher.java @@ -25,7 +25,7 @@ public class StandAloneValidatorFetcher implements IValidatorResourceFetcher { void loadPackage(String id, String ver) throws IOException, FHIRException; } - private BasePackageCacheManager pcm; + private FilesystemPackageCacheManager pcm; private IWorkerContext context; private IPackageInstaller installer; @@ -51,19 +51,37 @@ public class StandAloneValidatorFetcher implements IValidatorResourceFetcher { if (!Utilities.isAbsoluteUrl(url)) { return false; } - // if we've got to here, it's a reference to a FHIR URL. We're going to try to resolve it on the fly - // first possibility: it's a reference to a version specific URL http://hl7.org/fhir/X.X/... - VersionURLInfo vu = VersionUtilities.parseVersionUrl(url); - if (vu != null) { - NpmPackage pi = pcm.loadPackage(VersionUtilities.packageForVersion(vu.getVersion()), VersionUtilities.getCurrentVersion(vu.getVersion())); - return pi.hasCanonical(vu.getUrl()); + // if we've got to here, it's a reference to a FHIR URL. We're going to try to resolve it on the fly + String pid = null; + String ver = null; + String base = findBaseUrl(url); + if (base == null) { + return false; + } + + if (base.equals("http://terminology.hl7.org")) { + pid = "hl7.terminology"; + } else if (url.startsWith("http://hl7.org/fhir")) { + pid = pcm.getPackageId(base); + } else { + pid = pcm.findCanonicalInLocalCache(base); + } + ver = url.contains("|") ? url.substring(url.indexOf("|")+1) : null; + if (pid == null) { + return false; + } + + if (url.startsWith("http://hl7.org/fhir")) { + // first possibility: it's a reference to a version specific URL http://hl7.org/fhir/X.X/... + VersionURLInfo vu = VersionUtilities.parseVersionUrl(url); + if (vu != null) { + NpmPackage pi = pcm.loadPackage(VersionUtilities.packageForVersion(vu.getVersion()), VersionUtilities.getCurrentVersion(vu.getVersion())); + return pi.hasCanonical(vu.getUrl()); + } } // ok maybe it's a reference to a package we know - String base = findBaseUrl(url); - String pid = pcm.getPackageId(base); - String ver = url.contains("|") ? url.substring(url.indexOf("|")+1) : null; if (pid != null) { if (installer.packageExists(pid, ver)) { installer.loadPackage(pid, ver); @@ -72,13 +90,8 @@ public class StandAloneValidatorFetcher implements IValidatorResourceFetcher { } } - if (!url.startsWith("http://hl7.org/fhir")) { - return true; // we don't bother with those in the standalone validator - we assume they are valid - } - - // we assume it's invalid at this point - return false; - + // we don't bother with urls outside fhir space in the standalone validator - we assume they are valid + return !url.startsWith("http://hl7.org/fhir"); } private String findBaseUrl(String url) { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java index 16417caa8..5f564f143 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java @@ -209,6 +209,7 @@ public class ValidationService { FhirPublication ver = FhirPublication.fromCode(cliContext.getSv()); ValidationEngine validator = new ValidationEngine(definitions, ver, cliContext.getSv(), tt); System.out.println(" - "+validator.getContext().countAllCaches()+" resources ("+tt.milestone()+")"); + validator.loadIg("hl7.terminology", false); System.out.print(" Terminology server " + cliContext.getTxServer()); String txver = validator.setTerminologyServer(cliContext.getTxServer(), cliContext.getTxLog(), ver); System.out.println(" - Version "+txver+" ("+tt.milestone()+")");