Merge pull request #304 from hapifhir/gg-fix-validator-leak

fix validator leak
This commit is contained in:
Grahame Grieve 2020-08-12 06:00:09 +10:00 committed by GitHub
commit 98dcfd8f14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 109 additions and 4 deletions

View File

@ -227,6 +227,11 @@ public class CanonicalResourceManager<T extends CanonicalResource> {
drop(n.getId());
}
}
CachedCanonicalResource<T> existing = cr.hasVersion() ? map.get(cr.getUrl()+"|"+cr.getVersion()) : map.get(cr.getUrl()+"|#0");
if (existing != null) {
list.remove(existing);
}
list.add(cr);
map.put(cr.getId(), cr); // we do this so we can drop by id
@ -234,6 +239,8 @@ public class CanonicalResourceManager<T extends CanonicalResource> {
// first, this is the correct reosurce for this version (if it has a version)
if (cr.hasVersion()) {
map.put(cr.getUrl()+"|"+cr.getVersion(), cr);
} else {
map.put(cr.getUrl()+"|#0", cr);
}
updateList(cr.getUrl(), cr.getVersion());
}

View File

@ -90,6 +90,7 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
// private static final String SECONDARY_SERVER = "http://local.fhir.org:960/packages";
public static final String PACKAGE_REGEX = "^[a-z][a-z0-9\\_\\-]*(\\.[a-z0-9\\_\\-]+)+$";
public static final String PACKAGE_VERSION_REGEX = "^[a-z][a-z0-9\\_\\-]*(\\.[a-z0-9\\_\\-]+)+\\#[a-z0-9\\-\\_]+(\\.[a-z0-9\\-\\_]+)*$";
public static final String PACKAGE_VERSION_REGEX_OPT = "^[a-z][a-z0-9\\_\\-]*(\\.[a-z0-9\\_\\-]+)+(\\#[a-z0-9\\-\\_]+(\\.[a-z0-9\\-\\_]+)*)$";
private static final Logger ourLog = LoggerFactory.getLogger(FilesystemPackageCacheManager.class);
private static final String CACHE_VERSION = "3"; // second version - see wiki page
private String cacheFolder;

View File

@ -946,7 +946,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst
}
public void loadIg(String src, boolean recursive) throws IOException, FHIRException {
NpmPackage npm = src.matches(FilesystemPackageCacheManager.PACKAGE_REGEX) ? pcm.loadPackage(src, null) : null;
NpmPackage npm = src.matches(FilesystemPackageCacheManager.PACKAGE_VERSION_REGEX_OPT) ? pcm.loadPackage(src, null) : null;
if (npm != null) {
for (String s : npm.dependencies()) {
if (!context.getLoadedPackages().contains(s)) {
@ -960,11 +960,12 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst
String canonical = null;
Map<String, byte[]> source = loadIgSource(src, recursive, true);
String version = Constants.VERSION;
if (this.version != null)
if (this.version != null) {
version = this.version;
if (source.containsKey("version.info"))
}
if (source.containsKey("version.info")) {
version = readInfoVersion(source.get("version.info"));
}
for (Entry<String, byte[]> t : source.entrySet()) {
String fn = t.getKey();
if (!exemptFile(fn)) {

View File

@ -0,0 +1,96 @@
package org.hl7.fhir.validation.tests;
import java.text.NumberFormat;
import org.hl7.fhir.r5.test.utils.TestingUtilities;
import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.VersionUtilities;
import org.hl7.fhir.validation.ValidationEngine;
import org.junit.Test;
import net.sf.saxon.expr.instruct.Message;
public class TestLoadIg {
@Test
public void testPackage() {
String id = "hl7.fhir.r4.core";
String version = "4.0.1";
int DO_TIMES = 3;
try {
final String fhirSpecVersion = "4.0";
final String definitions = VersionUtilities.packageForVersion(fhirSpecVersion) + "#" + VersionUtilities.getCurrentVersion(fhirSpecVersion);
ValidationEngine hl7Validator = new ValidationEngine(definitions);
hl7Validator.setNative(false);
hl7Validator.setAnyExtensionsAllowed(true);
hl7Validator.prepare();
for (int i = 0; i < DO_TIMES; i++) {
System.gc();
System.out.print("loading: allocated memory " + getUsedMemoryAsMbs() + " MB, ");
System.out.print("free memory " + getFreeMemoryAsMbs() + " MB, ");
System.out.println("max memory " + getTotalMemoryAsMbs() + " MB");
// The method under test:
hl7Validator.loadIg(id + (version != null ? "#" + version : ""), true);
}
} catch (Exception e) {
e.printStackTrace();
}
// loadResourceByVersion
}
@Test
public void testLoad() {
String id = "hl7.fhir.r4.core";
String version = "4.0.1";
int DO_TIMES = 10;
try {
final String fhirSpecVersion = "4.0";
final String definitions = VersionUtilities.packageForVersion(fhirSpecVersion) + "#" + VersionUtilities.getCurrentVersion(fhirSpecVersion);
ValidationEngine hl7Validator = new ValidationEngine(definitions);
hl7Validator.setNative(false);
hl7Validator.setAnyExtensionsAllowed(true);
hl7Validator.prepare();
byte[] b = TextFile.streamToBytes(TestingUtilities.loadTestResourceStream("r5", "snapshot-generation", "t34-expected.xml")); // yes the choice of R5 is deliberate here - it's the same content as R4.
for (int i = 0; i < DO_TIMES; i++) {
System.gc();
for (int j = 0; j < 100; j++) {
hl7Validator.loadResourceByVersion("4.0.1", b, "resource.xml");
}
System.out.print("loading: allocated memory " + getUsedMemoryAsMbs() + " MB, ");
System.out.print("free memory " + getFreeMemoryAsMbs() + " MB, ");
System.out.println("max memory " + getTotalMemoryAsMbs() + " MB");
// The method under test:
hl7Validator.loadIg(id + (version != null ? "#" + version : ""), true);
}
} catch (Exception e) {
e.printStackTrace();
}
// loadResourceByVersion
}
public static String getFreeMemoryAsMbs() {
long MemoryFreeSize = Runtime.getRuntime().freeMemory();
double MemoryFreeSizeInMb = (MemoryFreeSize / 1024.0 / 1024.0);
return NumberFormat.getIntegerInstance().format(MemoryFreeSizeInMb);
}
public static String getUsedMemoryAsMbs() {
long MemoryUsedSize = Runtime.getRuntime().totalMemory();
double MemoryUsedSizeInMb = (MemoryUsedSize / 1024.0 / 1024.0);
return NumberFormat.getIntegerInstance().format(MemoryUsedSizeInMb);
}
public static String getTotalMemoryAsMbs() {
long MemoryTotalSize = Runtime.getRuntime().maxMemory();
double MemoryTotalSizeInMb = (MemoryTotalSize / 1024.0 / 1024.0);
return NumberFormat.getIntegerInstance().format(MemoryTotalSizeInMb);
}
}