Merge pull request #1427 from hapifhir/do-20230905-fix-system-cache-directory

Fix system cache directory
This commit is contained in:
Grahame Grieve 2023-09-10 09:29:57 +10:00 committed by GitHub
commit eef084f4b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 106 additions and 59 deletions

View File

@ -1,33 +1,33 @@
package org.hl7.fhir.dstu3.utils; package org.hl7.fhir.dstu3.utils;
/* /*
Copyright (c) 2011+, HL7, Inc. Copyright (c) 2011+, HL7, Inc.
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met: are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this * Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer. list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, * Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution. and/or other materials provided with the distribution.
* Neither the name of HL7 nor the names of its contributors may be used to * Neither the name of HL7 nor the names of its contributors may be used to
endorse or promote products derived from this software without specific endorse or promote products derived from this software without specific
prior written permission. prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. POSSIBILITY OF SUCH DAMAGE.
*/ */
@ -160,7 +160,7 @@ public class StructureMapUtilities {
public List<Base> performSearch(Object appContext, String url); public List<Base> performSearch(Object appContext, String url);
} }
private class FFHIRPathHostServices implements IEvaluationContext{ private class FHIRPathHostServices implements IEvaluationContext{
public Base resolveConstant(Object appContext, String name) throws PathEngineException { public Base resolveConstant(Object appContext, String name) throws PathEngineException {
Variables vars = (Variables) appContext; Variables vars = (Variables) appContext;
@ -223,7 +223,7 @@ public class StructureMapUtilities {
this.services = services; this.services = services;
this.pkp = pkp; this.pkp = pkp;
fpe = new FHIRPathEngine(worker); fpe = new FHIRPathEngine(worker);
fpe.setHostServices(new FFHIRPathHostServices()); fpe.setHostServices(new FHIRPathHostServices());
} }
public StructureMapUtilities(IWorkerContext worker, Map<String, StructureMap> library, ITransformerServices services) { public StructureMapUtilities(IWorkerContext worker, Map<String, StructureMap> library, ITransformerServices services) {
@ -232,7 +232,7 @@ public class StructureMapUtilities {
this.library = library; this.library = library;
this.services = services; this.services = services;
fpe = new FHIRPathEngine(worker); fpe = new FHIRPathEngine(worker);
fpe.setHostServices(new FFHIRPathHostServices()); fpe.setHostServices(new FHIRPathHostServices());
} }
public StructureMapUtilities(IWorkerContext worker, Map<String, StructureMap> library) { public StructureMapUtilities(IWorkerContext worker, Map<String, StructureMap> library) {
@ -240,14 +240,14 @@ public class StructureMapUtilities {
this.worker = worker; this.worker = worker;
this.library = library; this.library = library;
fpe = new FHIRPathEngine(worker); fpe = new FHIRPathEngine(worker);
fpe.setHostServices(new FFHIRPathHostServices()); fpe.setHostServices(new FHIRPathHostServices());
} }
public StructureMapUtilities(IWorkerContext worker) { public StructureMapUtilities(IWorkerContext worker) {
super(); super();
this.worker = worker; this.worker = worker;
fpe = new FHIRPathEngine(worker); fpe = new FHIRPathEngine(worker);
fpe.setHostServices(new FFHIRPathHostServices()); fpe.setHostServices(new FHIRPathHostServices());
} }
public StructureMapUtilities(IWorkerContext worker, ITransformerServices services) { public StructureMapUtilities(IWorkerContext worker, ITransformerServices services) {
@ -260,7 +260,7 @@ public class StructureMapUtilities {
} }
this.services = services; this.services = services;
fpe = new FHIRPathEngine(worker); fpe = new FHIRPathEngine(worker);
fpe.setHostServices(new FFHIRPathHostServices()); fpe.setHostServices(new FHIRPathHostServices());
} }
public static String render(StructureMap map) { public static String render(StructureMap map) {

View File

@ -175,7 +175,7 @@ public class StructureMapUtilities {
public List<Base> performSearch(Object appContext, String url) throws FHIRException; public List<Base> performSearch(Object appContext, String url) throws FHIRException;
} }
private class FFHIRPathHostServices implements IEvaluationContext { private class FHIRPathHostServices implements IEvaluationContext {
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext)
throws PathEngineException { throws PathEngineException {
@ -241,7 +241,7 @@ public class StructureMapUtilities {
ok = ok && v.getLevel().isError(); ok = ok && v.getLevel().isError();
return ok; return ok;
} }
throw new NotImplementedException("Not done yet (FFHIRPathHostServices.conformsToProfile), when item is element"); throw new NotImplementedException("Not done yet (FHIRPathHostServices.conformsToProfile), when item is element");
} }
@Override @Override
@ -264,7 +264,7 @@ public class StructureMapUtilities {
this.services = services; this.services = services;
this.pkp = pkp; this.pkp = pkp;
fpe = new FHIRPathEngine(worker); fpe = new FHIRPathEngine(worker);
fpe.setHostServices(new FFHIRPathHostServices()); fpe.setHostServices(new FHIRPathHostServices());
} }
public StructureMapUtilities(IWorkerContext worker, ITransformerServices services) { public StructureMapUtilities(IWorkerContext worker, ITransformerServices services) {
@ -272,7 +272,7 @@ public class StructureMapUtilities {
this.worker = worker; this.worker = worker;
this.services = services; this.services = services;
fpe = new FHIRPathEngine(worker); fpe = new FHIRPathEngine(worker);
fpe.setHostServices(new FFHIRPathHostServices()); fpe.setHostServices(new FHIRPathHostServices());
} }
public StructureMapUtilities(IWorkerContext worker) { public StructureMapUtilities(IWorkerContext worker) {
@ -280,7 +280,7 @@ public class StructureMapUtilities {
this.worker = worker; this.worker = worker;
if (worker != null) { if (worker != null) {
fpe = new FHIRPathEngine(worker); fpe = new FHIRPathEngine(worker);
fpe.setHostServices(new FFHIRPathHostServices()); fpe.setHostServices(new FHIRPathHostServices());
} }
} }

View File

@ -16,11 +16,11 @@ import org.hl7.fhir.utilities.validation.ValidationMessage;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class FFHIRPathHostServices implements FHIRPathEngine.IEvaluationContext { public class FHIRPathHostServices implements FHIRPathEngine.IEvaluationContext {
private final StructureMapUtilities structureMapUtilities; private final StructureMapUtilities structureMapUtilities;
public FFHIRPathHostServices(StructureMapUtilities structureMapUtilities) { public FHIRPathHostServices(StructureMapUtilities structureMapUtilities) {
this.structureMapUtilities = structureMapUtilities; this.structureMapUtilities = structureMapUtilities;
} }
@ -96,7 +96,7 @@ public class FFHIRPathHostServices implements FHIRPathEngine.IEvaluationContext
return noErrorValidationMessages(valerrors); return noErrorValidationMessages(valerrors);
} }
throw new NotImplementedException( throw new NotImplementedException(
"Not done yet (FFHIRPathHostServices.conformsToProfile), when item is not element or not resource"); "Not done yet (FHIRPathHostServices.conformsToProfile), when item is not element or not resource");
} }
@Override @Override

View File

@ -109,7 +109,7 @@ public class StructureMapUtilities {
private static final boolean RENDER_MULTIPLE_TARGETS_ONELINE = true; private static final boolean RENDER_MULTIPLE_TARGETS_ONELINE = true;
private static final String AUTO_VAR_NAME = "vvv"; private static final String AUTO_VAR_NAME = "vvv";
private class FFHIRPathHostServices implements IEvaluationContext { private class FHIRPathHostServices implements IEvaluationContext {
public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext) public List<Base> resolveConstant(Object appContext, String name, boolean beforeContext)
throws PathEngineException { throws PathEngineException {
@ -177,7 +177,7 @@ public class StructureMapUtilities {
ok = ok && v.getLevel().isError(); ok = ok && v.getLevel().isError();
return ok; return ok;
} }
throw new NotImplementedException("Not done yet (FFHIRPathHostServices.conformsToProfile), when item is element"); throw new NotImplementedException("Not done yet (FHIRPathHostServices.conformsToProfile), when item is element");
} }
@Override @Override
@ -201,7 +201,7 @@ public class StructureMapUtilities {
this.services = services; this.services = services;
this.pkp = pkp; this.pkp = pkp;
fpe = new FHIRPathEngine(worker); fpe = new FHIRPathEngine(worker);
fpe.setHostServices(new FFHIRPathHostServices()); fpe.setHostServices(new FHIRPathHostServices());
profileUtilities = new ProfileUtilities(worker, null, null); profileUtilities = new ProfileUtilities(worker, null, null);
} }
@ -210,7 +210,7 @@ public class StructureMapUtilities {
this.worker = worker; this.worker = worker;
this.services = services; this.services = services;
fpe = new FHIRPathEngine(worker); fpe = new FHIRPathEngine(worker);
fpe.setHostServices(new FFHIRPathHostServices()); fpe.setHostServices(new FHIRPathHostServices());
profileUtilities = new ProfileUtilities(worker, null, null); profileUtilities = new ProfileUtilities(worker, null, null);
} }
@ -218,7 +218,7 @@ public class StructureMapUtilities {
super(); super();
this.worker = worker; this.worker = worker;
fpe = new FHIRPathEngine(worker); fpe = new FHIRPathEngine(worker);
fpe.setHostServices(new FFHIRPathHostServices()); fpe.setHostServices(new FHIRPathHostServices());
profileUtilities = new ProfileUtilities(worker, null, null); profileUtilities = new ProfileUtilities(worker, null, null);
} }

View File

@ -16,11 +16,11 @@ import org.hl7.fhir.utilities.validation.ValidationMessage;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class FFHIRPathHostServices implements FHIRPathEngine.IEvaluationContext { public class FHIRPathHostServices implements FHIRPathEngine.IEvaluationContext {
private final StructureMapUtilities structureMapUtilities; private final StructureMapUtilities structureMapUtilities;
public FFHIRPathHostServices(StructureMapUtilities structureMapUtilities) { public FHIRPathHostServices(StructureMapUtilities structureMapUtilities) {
this.structureMapUtilities = structureMapUtilities; this.structureMapUtilities = structureMapUtilities;
} }
@ -92,7 +92,7 @@ public class FFHIRPathHostServices implements FHIRPathEngine.IEvaluationContext
val.validate(appContext, valerrors, null, (Element) item, url); val.validate(appContext, valerrors, null, (Element) item, url);
return noErrorValidationMessages(valerrors); return noErrorValidationMessages(valerrors);
} }
throw new NotImplementedException("Not done yet (FFHIRPathHostServices.conformsToProfile), when item is not element or not resource"); throw new NotImplementedException("Not done yet (FHIRPathHostServices.conformsToProfile), when item is not element or not resource");
} }
@Override @Override

View File

@ -116,7 +116,7 @@ public class StructureMapUtilities {
this.services = services; this.services = services;
this.pkp = pkp; this.pkp = pkp;
fpe = new FHIRPathEngine(worker); fpe = new FHIRPathEngine(worker);
fpe.setHostServices(new FFHIRPathHostServices(this)); fpe.setHostServices(new FHIRPathHostServices(this));
profileUtilities = new ProfileUtilities(worker, null, null); profileUtilities = new ProfileUtilities(worker, null, null);
} }
@ -125,7 +125,7 @@ public class StructureMapUtilities {
this.worker = worker; this.worker = worker;
this.services = services; this.services = services;
fpe = new FHIRPathEngine(worker); fpe = new FHIRPathEngine(worker);
fpe.setHostServices(new FFHIRPathHostServices(this)); fpe.setHostServices(new FHIRPathHostServices(this));
profileUtilities = new ProfileUtilities(worker, null, null); profileUtilities = new ProfileUtilities(worker, null, null);
} }
@ -133,7 +133,7 @@ public class StructureMapUtilities {
super(); super();
this.worker = worker; this.worker = worker;
fpe = new FHIRPathEngine(worker); fpe = new FHIRPathEngine(worker);
fpe.setHostServices(new FFHIRPathHostServices(this)); fpe.setHostServices(new FHIRPathHostServices(this));
profileUtilities = new ProfileUtilities(worker, null, null); profileUtilities = new ProfileUtilities(worker, null, null);
} }

View File

@ -11,19 +11,19 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
class FFHIRPathHostServicesTest { class FHIRPathHostServicesTest {
static private SimpleWorkerContext context; static private SimpleWorkerContext context;
@BeforeAll @BeforeAll
static public void setUp() throws Exception { static public void setUp() throws Exception {
FilesystemPackageCacheManager pcm = new org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager(false); FilesystemPackageCacheManager pcm = new org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager(true);
context = TestingUtilities.getWorkerContext(pcm.loadPackage("hl7.fhir.r4.core", "4.0.1")); context = TestingUtilities.getWorkerContext(pcm.loadPackage("hl7.fhir.r4.core", "4.0.1"));
} }
@Test @Test
public void testrResolveValueSet() throws IOException, FHIRException { public void testrResolveValueSet() throws IOException, FHIRException {
StructureMapUtilities scu = new StructureMapUtilities(context); StructureMapUtilities scu = new StructureMapUtilities(context);
FFHIRPathHostServices fphs = new FFHIRPathHostServices(scu); FHIRPathHostServices fphs = new FHIRPathHostServices(scu);
ValueSet v = fphs.resolveValueSet(null, "http://hl7.org/fhir/ValueSet/FHIR-version"); ValueSet v = fphs.resolveValueSet(null, "http://hl7.org/fhir/ValueSet/FHIR-version");
Assertions.assertNotNull(v); Assertions.assertNotNull(v);
Assertions.assertEquals("http://hl7.org/fhir/ValueSet/FHIR-version", v.getUrl()); Assertions.assertEquals("http://hl7.org/fhir/ValueSet/FHIR-version", v.getUrl());

View File

@ -146,7 +146,11 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
switch (mode) { switch (mode) {
case SYSTEM: case SYSTEM:
cacheFolder = new File(Utilities.path("var", "lib", ".fhir", "packages")); if (Utilities.isWindows()) {
cacheFolder = new File(Utilities.path(System.getenv("ProgramData"), ".fhir", "packages"));
} else {
cacheFolder = new File(Utilities.path("/var", "lib", ".fhir", "packages"));
}
break; break;
case USER: case USER:
cacheFolder = new File(Utilities.path(System.getProperty("user.home"), ".fhir", "packages")); cacheFolder = new File(Utilities.path(System.getProperty("user.home"), ".fhir", "packages"));
@ -162,10 +166,17 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
break; break;
} }
initCacheFolder();
}
protected void initCacheFolder() throws IOException {
if (!(cacheFolder.exists())) if (!(cacheFolder.exists()))
Utilities.createDirectory(cacheFolder.getAbsolutePath()); Utilities.createDirectory(cacheFolder.getAbsolutePath());
if (!(new File(Utilities.path(cacheFolder, "packages.ini")).exists())) String packagesIniPath = Utilities.path(cacheFolder, "packages.ini");
TextFile.stringToFile("[cache]\r\nversion=" + CACHE_VERSION + "\r\n\r\n[urls]\r\n\r\n[local]\r\n\r\n", Utilities.path(cacheFolder, "packages.ini"), false); File packagesIniFile = new File(packagesIniPath);
if (!(packagesIniFile.exists()))
packagesIniFile.createNewFile();
TextFile.stringToFile("[cache]\r\nversion=" + CACHE_VERSION + "\r\n\r\n[urls]\r\n\r\n[local]\r\n\r\n", packagesIniPath, false);
createIniFile(); createIniFile();
for (File f : cacheFolder.listFiles()) { for (File f : cacheFolder.listFiles()) {
if (f.isDirectory() && Utilities.isValidUUID(f.getName())) { if (f.isDirectory() && Utilities.isValidUUID(f.getName())) {

View File

@ -2,12 +2,16 @@ package org.hl7.fhir.utilities.npm;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
public class FilesystemPackageManagerTests { public class FilesystemPackageManagerTests {
@ -64,4 +68,36 @@ public class FilesystemPackageManagerTests {
} }
}; };
} }
@Test
public void testUserCacheDirectory() throws IOException {
FilesystemPackageCacheManager filesystemPackageCacheManager = new FilesystemPackageCacheManager(true) {
protected void initCacheFolder() throws IOException {
}
};
assertEquals(System.getProperty("user.home") + File.separator + ".fhir" + File.separator + "packages", filesystemPackageCacheManager.getFolder());
}
/*
Targeted folder will only be valid on -nix style systems.
*/
@Test
@DisabledOnOs(OS.WINDOWS)
public void testSystemCacheDirectory() throws IOException {
FilesystemPackageCacheManager filesystemPackageCacheManager = new FilesystemPackageCacheManager(false) {
protected void initCacheFolder() throws IOException {
}
};
assertEquals( "/var/lib/.fhir/packages", filesystemPackageCacheManager.getFolder());
}
@Test
@EnabledOnOs(OS.WINDOWS)
public void testSystemCacheDirectoryWin() throws IOException {
FilesystemPackageCacheManager filesystemPackageCacheManager = new FilesystemPackageCacheManager(false) {
protected void initCacheFolder() throws IOException {
}
};
assertEquals( System.getenv("ProgramData") + "\\.fhir\\packages", filesystemPackageCacheManager.getFolder());
}
} }