diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/TerminologyCache.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/TerminologyCache.java index f63fbce99..ae60d7fcc 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/TerminologyCache.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/TerminologyCache.java @@ -133,7 +133,7 @@ public class TerminologyCache { json.setOutputStyle(OutputStyle.PRETTY); ValueSet vsc = getVSEssense(vs); try { - ct.request = "{\"code\" : "+json.composeString(code, "code")+", \"valueSet\" :"+(vsc == null ? "null" : json.composeString(vsc))+(options == null ? "" : ", "+options.toJson())+"}"; + ct.request = "{\"code\" : "+json.composeString(code, "code")+", \"valueSet\" :"+(vsc == null ? "null" : extracted(json, vsc))+(options == null ? "" : ", "+options.toJson())+"}"; } catch (IOException e) { throw new Error(e); } @@ -141,6 +141,16 @@ public class TerminologyCache { return ct; } + public String extracted(JsonParser json, ValueSet vsc) throws IOException { + String s = null; + if (vsc.getExpansion().getContains().size() > 1000 || vsc.getCompose().getIncludeFirstRep().getConcept().size() > 1000) { + s = Integer.toString(vsc.hashCode()); // turn caching off - hack efficiency optimisation + } else { + s = json.composeString(vsc); + } + return s; + } + public CacheToken generateValidationToken(ValidationOptions options, CodeableConcept code, ValueSet vs) { CacheToken ct = new CacheToken(); for (Coding c : code.getCoding()) { @@ -151,7 +161,7 @@ public class TerminologyCache { json.setOutputStyle(OutputStyle.PRETTY); ValueSet vsc = getVSEssense(vs); try { - ct.request = "{\"code\" : "+json.composeString(code, "codeableConcept")+", \"valueSet\" :"+json.composeString(vsc)+(options == null ? "" : ", "+options.toJson())+"}"; + ct.request = "{\"code\" : "+json.composeString(code, "codeableConcept")+", \"valueSet\" :"+extracted(json, vsc)+(options == null ? "" : ", "+options.toJson())+"}"; } catch (IOException e) { throw new Error(e); } @@ -186,7 +196,7 @@ public class TerminologyCache { JsonParser json = new JsonParser(); json.setOutputStyle(OutputStyle.PRETTY); try { - ct.request = "{\"hierarchical\" : "+(heirarchical ? "true" : "false")+", \"valueSet\" :"+json.composeString(vsc)+"}\r\n"; + ct.request = "{\"hierarchical\" : "+(heirarchical ? "true" : "false")+", \"valueSet\" :"+extracted(json, vsc)+"}\r\n"; } catch (IOException e) { throw new Error(e); } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java index 6eed37701..9375ada7b 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java @@ -722,7 +722,11 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst return true; } if (fetcher != null) { - return fetcher.resolveURL(appContext, path, url, type); + try { + return fetcher.resolveURL(appContext, path, url, type); + } catch (Exception e) { + return false; + } } return false; } 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 253e0403a..716ed4896 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 @@ -21,8 +21,10 @@ import java.io.IOException; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Map; public class StandAloneValidatorFetcher implements IValidatorResourceFetcher { @@ -30,6 +32,9 @@ public class StandAloneValidatorFetcher implements IValidatorResourceFetcher { private FilesystemPackageCacheManager pcm; private IWorkerContext context; private IPackageInstaller installer; + private Map urlList = new HashMap<>(); + private Map pidList = new HashMap<>(); + private Map pidMap = new HashMap<>(); public StandAloneValidatorFetcher(FilesystemPackageCacheManager pcm, IWorkerContext context, IPackageInstaller installer) { super(); @@ -70,15 +75,25 @@ public class StandAloneValidatorFetcher implements IValidatorResourceFetcher { return !url.startsWith("http://hl7.org/fhir") && !type.equals("canonical"); } + // the next operations are expensive. we're going to cache them + if (urlList.containsKey(url)) { + return urlList.get(url); + } 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); + if (pidList.containsKey(base)) { + pid = pidList.get(base); + } else { + pid = pcm.findCanonicalInLocalCache(base); + pidList.put(base, pid); + } } ver = url.contains("|") ? url.substring(url.indexOf("|") + 1) : null; if (pid == null && Utilities.startsWithInList(url, "http://hl7.org/fhir", "http://terminology.hl7.org")) { + urlList.put(url, false); return false; } @@ -87,15 +102,32 @@ public class StandAloneValidatorFetcher implements IValidatorResourceFetcher { 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()); + boolean res = pi.hasCanonical(vu.getUrl()); + urlList.put(url, res); + return res; } } // ok maybe it's a reference to a package we know if (pid != null) { - if (installer.packageExists(pid, ver)) { - installer.loadPackage(pid, ver); - NpmPackage pi = pcm.loadPackage(pid); + if ("sharedhealth.fhir.ca.common".equals(pid)) { // special case - optimise this + return false; + } + NpmPackage pi = null; + if (pidMap.containsKey(pid+"|"+ver)) { + pi = pidMap.get(pid+"|"+ver); + } else if (installer.packageExists(pid, ver)) { + try { + installer.loadPackage(pid, ver); + pi = pcm.loadPackage(pid); + pidMap.put(pid+"|"+ver, pi); + } catch (Exception e) { + pidMap.put(pid+"|"+ver, null); + } + } else { + pidMap.put(pid+"|"+ver, null); + } + if (pi != null) { return pi.hasCanonical(url); } }