Fix for cache init on existing directories (#1743)
* Add tests+fix for cache init on existing directories * Clear the cache if it is the wrong version * Link to FHIR spec docs for .index.json
This commit is contained in:
parent
2c8122a42e
commit
bc0303535a
|
@ -210,26 +210,30 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
||||||
Utilities.createDirectory(cacheFolder.getAbsolutePath());
|
Utilities.createDirectory(cacheFolder.getAbsolutePath());
|
||||||
createIniFile();
|
createIniFile();
|
||||||
} else {
|
} else {
|
||||||
if (!isCacheFolderValid()) {
|
if (!iniFileExists()) {
|
||||||
|
createIniFile();
|
||||||
|
}
|
||||||
|
if (!isIniFileCurrentVersion()) {
|
||||||
clearCache();
|
clearCache();
|
||||||
createIniFile();
|
createIniFile();
|
||||||
} else {
|
|
||||||
deleteOldTempDirectories();
|
|
||||||
}
|
}
|
||||||
|
deleteOldTempDirectories();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isCacheFolderValid() throws IOException {
|
private boolean iniFileExists() throws IOException {
|
||||||
String iniPath = getPackagesIniPath();
|
String iniPath = getPackagesIniPath();
|
||||||
File iniFile = ManagedFileAccess.file(iniPath);
|
File iniFile = ManagedFileAccess.file(iniPath);
|
||||||
if (!(iniFile.exists())) {
|
return iniFile.exists();
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isIniFileCurrentVersion() throws IOException {
|
||||||
|
String iniPath = getPackagesIniPath();
|
||||||
IniFile ini = new IniFile(iniPath);
|
IniFile ini = new IniFile(iniPath);
|
||||||
String v = ini.getStringProperty("cache", "version");
|
String version = ini.getStringProperty("cache", "version");
|
||||||
return CACHE_VERSION.equals(v);
|
return CACHE_VERSION.equals(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteOldTempDirectories() throws IOException {
|
private void deleteOldTempDirectories() throws IOException {
|
||||||
|
|
|
@ -648,7 +648,17 @@ public class NpmPackage {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a package .index.json file for a package folder.
|
||||||
|
* <p>
|
||||||
|
* See <a href="https://hl7.org/fhir/packages.html#2.1.10.4">the FHIR specification</a> for details on .index.json
|
||||||
|
* format and usage.
|
||||||
|
*
|
||||||
|
* @param desc
|
||||||
|
* @param folder
|
||||||
|
* @throws FileNotFoundException
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
public void indexFolder(String desc, NpmPackageFolder folder) throws FileNotFoundException, IOException {
|
public void indexFolder(String desc, NpmPackageFolder folder) throws FileNotFoundException, IOException {
|
||||||
List<String> remove = new ArrayList<>();
|
List<String> remove = new ArrayList<>();
|
||||||
NpmPackageIndexBuilder indexer = new NpmPackageIndexBuilder();
|
NpmPackageIndexBuilder indexer = new NpmPackageIndexBuilder();
|
||||||
|
|
|
@ -1,22 +1,25 @@
|
||||||
package org.hl7.fhir.utilities.npm;
|
package org.hl7.fhir.utilities.npm;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
import org.hl7.fhir.utilities.IniFile;
|
||||||
import org.hl7.fhir.utilities.filesystem.ManagedFileAccess;
|
import org.hl7.fhir.utilities.filesystem.ManagedFileAccess;
|
||||||
import org.junit.jupiter.api.RepeatedTest;
|
|
||||||
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.DisabledOnOs;
|
||||||
import org.junit.jupiter.api.condition.EnabledOnOs;
|
import org.junit.jupiter.api.condition.EnabledOnOs;
|
||||||
|
@ -100,7 +103,6 @@ public class FilesystemPackageManagerTests {
|
||||||
@DisabledOnOs(OS.WINDOWS)
|
@DisabledOnOs(OS.WINDOWS)
|
||||||
public void testSystemCacheDirectory() throws IOException {
|
public void testSystemCacheDirectory() throws IOException {
|
||||||
File folder = new FilesystemPackageCacheManager.Builder().withSystemCacheFolder().getCacheFolder();
|
File folder = new FilesystemPackageCacheManager.Builder().withSystemCacheFolder().getCacheFolder();
|
||||||
|
|
||||||
assertEquals( "/var/lib/.fhir/packages", folder.getAbsolutePath());
|
assertEquals( "/var/lib/.fhir/packages", folder.getAbsolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,6 +126,118 @@ public class FilesystemPackageManagerTests {
|
||||||
return params.stream();
|
return params.stream();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createDummyTemp(File cacheDirectory, String lowerCase) throws IOException {
|
||||||
|
createDummyPackage(cacheDirectory, lowerCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createDummyPackage(File cacheDirectory, String packageName, String packageVersion) throws IOException {
|
||||||
|
String directoryName = packageName + "#" + packageVersion;
|
||||||
|
createDummyPackage(cacheDirectory, directoryName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void createDummyPackage(File cacheDirectory, String directoryName) throws IOException {
|
||||||
|
File packageDirectory = ManagedFileAccess.file(cacheDirectory.getAbsolutePath(), directoryName);
|
||||||
|
packageDirectory.mkdirs();
|
||||||
|
|
||||||
|
File dummyContentFile = ManagedFileAccess.file(packageDirectory.getAbsolutePath(), "dummy.txt");
|
||||||
|
FileWriter wr = new FileWriter(dummyContentFile);
|
||||||
|
wr.write("Ain't nobody here but us chickens");
|
||||||
|
wr.flush();
|
||||||
|
wr.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertThatDummyTempExists(File cacheDirectory, String dummyTempPackage) throws IOException {
|
||||||
|
File dummyTempDirectory = ManagedFileAccess.file(cacheDirectory.getAbsolutePath(), dummyTempPackage);
|
||||||
|
assertThat(dummyTempDirectory).exists();
|
||||||
|
|
||||||
|
File dummyContentFile = ManagedFileAccess.file(dummyTempDirectory.getAbsolutePath(), "dummy.txt");
|
||||||
|
assertThat(dummyContentFile).exists();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreatesIniIfDoesntExistAndCacheStaysIntact() throws IOException {
|
||||||
|
File cacheDirectory = ManagedFileAccess.fromPath(Files.createTempDirectory("fpcm-multithreadingTest"));
|
||||||
|
File cacheIni = ManagedFileAccess.file(cacheDirectory.getAbsolutePath(), "packages.ini");
|
||||||
|
|
||||||
|
createDummyPackage(cacheDirectory, "example.fhir.uv.myig", "1.2.3");
|
||||||
|
|
||||||
|
String dummyTempPackage = UUID.randomUUID().toString().toLowerCase();
|
||||||
|
createDummyTemp(cacheDirectory, dummyTempPackage);
|
||||||
|
assertThatDummyTempExists(cacheDirectory, dummyTempPackage);
|
||||||
|
|
||||||
|
assertThat(cacheIni).doesNotExist();
|
||||||
|
FilesystemPackageCacheManager filesystemPackageCacheManager = new FilesystemPackageCacheManager.Builder().withCacheFolder(cacheDirectory.getAbsolutePath()).build();
|
||||||
|
assertInitializedTestCacheIsValid(cacheDirectory, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClearsCacheIfVersionIsWrong() throws IOException {
|
||||||
|
File cacheDirectory = ManagedFileAccess.fromPath(Files.createTempDirectory("fpcm-multithreadingTest"));
|
||||||
|
File cacheIni = ManagedFileAccess.file(cacheDirectory.getAbsolutePath(), "packages.ini");
|
||||||
|
|
||||||
|
createDummyPackage(cacheDirectory, "example.fhir.uv.myig", "1.2.3");
|
||||||
|
String dummyTempPackage = UUID.randomUUID().toString().toLowerCase();
|
||||||
|
createDummyTemp(cacheDirectory, dummyTempPackage);
|
||||||
|
assertThatDummyTempExists(cacheDirectory, dummyTempPackage);
|
||||||
|
|
||||||
|
|
||||||
|
IniFile ini = new IniFile(cacheIni.getAbsolutePath());
|
||||||
|
ini.setStringProperty("cache", "version", "2", null);
|
||||||
|
ini.save();
|
||||||
|
|
||||||
|
assertThat(cacheIni).exists();
|
||||||
|
FilesystemPackageCacheManager filesystemPackageCacheManager = new FilesystemPackageCacheManager.Builder().withCacheFolder(cacheDirectory.getAbsolutePath()).build();
|
||||||
|
assertInitializedTestCacheIsValid(cacheDirectory, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCacheStaysIntactIfVersionIsTheSame() throws IOException {
|
||||||
|
File cacheDirectory = ManagedFileAccess.fromPath(Files.createTempDirectory("fpcm-multithreadingTest"));
|
||||||
|
File cacheIni = ManagedFileAccess.file(cacheDirectory.getAbsolutePath(), "packages.ini");
|
||||||
|
|
||||||
|
createDummyPackage(cacheDirectory, "example.fhir.uv.myig", "1.2.3");
|
||||||
|
String dummyTempPackage = UUID.randomUUID().toString().toLowerCase();
|
||||||
|
createDummyTemp(cacheDirectory, dummyTempPackage);
|
||||||
|
assertThatDummyTempExists(cacheDirectory, dummyTempPackage);
|
||||||
|
|
||||||
|
|
||||||
|
IniFile ini = new IniFile(cacheIni.getAbsolutePath());
|
||||||
|
ini.setStringProperty("cache", "version", "3", null);
|
||||||
|
ini.save();
|
||||||
|
|
||||||
|
assertThat(cacheIni).exists();
|
||||||
|
FilesystemPackageCacheManager filesystemPackageCacheManager = new FilesystemPackageCacheManager.Builder().withCacheFolder(cacheDirectory.getAbsolutePath()).build();
|
||||||
|
assertInitializedTestCacheIsValid(cacheDirectory, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertInitializedTestCacheIsValid(File cacheDirectory, boolean dummyPackageShouldExist) throws IOException {
|
||||||
|
assertThat(cacheDirectory).exists();
|
||||||
|
File iniFile = ManagedFileAccess.file(cacheDirectory.getAbsolutePath(), "packages.ini");
|
||||||
|
assertThat(ManagedFileAccess.file(cacheDirectory.getAbsolutePath(), "packages.ini")).exists();
|
||||||
|
IniFile ini = new IniFile(iniFile.getAbsolutePath());
|
||||||
|
String version = ini.getStringProperty("cache", "version");
|
||||||
|
assertThat(version).isEqualTo("3");
|
||||||
|
|
||||||
|
File[] files = cacheDirectory.listFiles();
|
||||||
|
if (dummyPackageShouldExist) {
|
||||||
|
// Check that only packages.ini and our dummy package are in the cache. Our previous temp should be deleted.
|
||||||
|
assertThat(files).hasSize(2); // packages.ini and example.fhir.uv.myig#1.2.3 (directory)
|
||||||
|
|
||||||
|
File dummyPackage = ManagedFileAccess.file(cacheDirectory.getAbsolutePath(), "example.fhir.uv.myig#1.2.3");
|
||||||
|
assertThat(dummyPackage).exists();
|
||||||
|
|
||||||
|
File dummyContentFile = ManagedFileAccess.file(dummyPackage.getAbsolutePath(), "dummy.txt");
|
||||||
|
assertThat(dummyContentFile).exists();
|
||||||
|
} else {
|
||||||
|
// Check that only packages.ini is in the cache.
|
||||||
|
assertThat(files).hasSize(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@MethodSource("packageCacheMultiThreadTestParams")
|
@MethodSource("packageCacheMultiThreadTestParams")
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
public void packageCacheMultiThreadTest(final int threadTotal, final int packageCacheManagerTotal) throws IOException {
|
public void packageCacheMultiThreadTest(final int threadTotal, final int packageCacheManagerTotal) throws IOException {
|
||||||
|
|
Loading…
Reference in New Issue