borgbutler-core/src/main/java/de/micromata/borgbutler/cache/AbstractCache.java
@@ -5,6 +5,7 @@ import de.micromata.borgbutler.json.JsonUtils; import lombok.Getter; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -16,6 +17,8 @@ public abstract class AbstractCache<T> { private static Logger log = LoggerFactory.getLogger(AbstractCache.class); private static final String CACHE_FILE_PREFIX = "cache-"; private static final String CACHE_FILE_EXTENSION = "json"; @JsonIgnore protected File cacheFile; @@ -41,6 +44,13 @@ public abstract void updateFrom(T dest, T source); /** * Removes all entries (doesn't effect the cache files!). */ public void clear() { elements.clear(); } public void upsert(T element) { T existingElement = get(getIdentifier(element)); if (existingElement == null) { @@ -52,6 +62,11 @@ public void read() { try { if (!cacheFile.exists()) { // Cache file doesn't exist. Nothing to read. return; } log.info("Parsing cache file '" + cacheFile.getAbsolutePath() + "'."); String json = FileUtils.readFileToString(cacheFile, Charset.forName("UTF-8")); AbstractCache readCache = JsonUtils.fromJson(this.getClass(), json); if (readCache != null) { @@ -83,6 +98,12 @@ } AbstractCache(File cacheDir, String cacheFilename) { cacheFile = new File(cacheDir, cacheFilename); cacheFile = new File(cacheDir, CACHE_FILE_PREFIX + cacheFilename + "." + CACHE_FILE_EXTENSION); } public static boolean isCacheFile(File file) { String filename = file.getName(); String extension = FilenameUtils.getExtension(filename); return filename.startsWith(CACHE_FILE_PREFIX) && extension.equals(CACHE_FILE_EXTENSION); } } borgbutler-core/src/main/java/de/micromata/borgbutler/cache/ButlerCache.java
@@ -5,13 +5,17 @@ import org.slf4j.LoggerFactory; import java.io.File; import java.util.ArrayList; import java.util.List; public class ButlerCache { private static Logger log = LoggerFactory.getLogger(ButlerCache.class); public static final String CACHE_DIR_NAME = ".borgbutler"; private static ButlerCache instance = new ButlerCache(); private RepoInfoCache reposCache; private RepoInfoCache repoInfoCache; private RepoListCache repoListCache; private List<AbstractCache> caches; @JsonIgnore private File cacheDir; @@ -20,12 +24,40 @@ return instance; } public static RepoInfoCache getReposCache() { return instance.reposCache; public static RepoInfoCache getRepoInfoCache() { return instance.repoInfoCache; } public static RepoListCache getRepoListCache() { return instance.repoListCache; } public void read() { for (AbstractCache cache : caches) { cache.read(); } } public void save() { reposCache.save(); for (AbstractCache cache : caches) { cache.save(); } } /** * Removes all cache files and clears all caches. */ public void removeAllCacheFiles() { File[] files = cacheDir.listFiles(); for (File file : files) { if (AbstractCache.isCacheFile(file)) { log.info("Deleting cache file: " + file.getAbsolutePath()); file.delete(); } } for (AbstractCache cache : caches) { cache.clear(); } } private ButlerCache() { @@ -35,6 +67,10 @@ log.info("Creating cache dir: " + cacheDir.getAbsolutePath()); cacheDir.mkdir(); } reposCache = new RepoInfoCache(cacheDir); repoInfoCache = new RepoInfoCache(cacheDir); repoListCache = new RepoListCache(cacheDir); caches = new ArrayList<>(); caches.add(repoInfoCache); caches.add(repoListCache); } } borgbutler-core/src/main/java/de/micromata/borgbutler/cache/RepoInfoCache.java
@@ -9,7 +9,7 @@ public class RepoInfoCache extends AbstractCache<RepoInfo> { private static Logger log = LoggerFactory.getLogger(RepoInfoCache.class); public static final String CACHE_REPOS_FILENAME = "cache-repos.json"; public static final String CACHE_REPOS_BASENAME = "repos"; public boolean matches(RepoInfo element, String identifier) { Repository repository = element.getRepository(); @@ -35,6 +35,6 @@ } RepoInfoCache(File cacheDir) { super(cacheDir, CACHE_REPOS_FILENAME); super(cacheDir, CACHE_REPOS_BASENAME); } } borgbutler-core/src/main/java/de/micromata/borgbutler/cache/RepoListCache.java
New file @@ -0,0 +1,40 @@ package de.micromata.borgbutler.cache; import de.micromata.borgbutler.json.borg.RepoList; import de.micromata.borgbutler.json.borg.Repository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; public class RepoListCache extends AbstractCache<RepoList> { private static Logger log = LoggerFactory.getLogger(RepoListCache.class); public static final String CACHE_REPO_LISTS_BASENAME = "repo-lists"; public boolean matches(RepoList element, String identifier) { Repository repository = element.getRepository(); if (repository == null) { return false; } return identifier.equals(repository.getId()) || identifier.equals(repository.getName()) || identifier.equals(repository.getLocation()); } public String getIdentifier(RepoList element) { return element.getRepository().getId(); } public void updateFrom(RepoList dest, RepoList source) { dest.updateFrom(source); } /** * Needed by jackson for deserialization. */ RepoListCache() { } RepoListCache(File cacheDir) { super(cacheDir, CACHE_REPO_LISTS_BASENAME); } } borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/RepoInfo.java
@@ -33,5 +33,4 @@ this.repository = repoInfo.getRepository(); this.originalJson = repoInfo.originalJson; } } borgbutler-core/src/main/java/de/micromata/borgbutler/json/borg/RepoList.java
@@ -22,4 +22,11 @@ public String toString() { return JsonUtils.toJson(this, true); } public void updateFrom(RepoList repoList) { this.archives = repoList.archives; this.encryption = repoList.encryption; this.repository = repoList.getRepository(); this.originalJson = repoList.originalJson; } } borgbutler-core/src/test/java/de/micromata/borgbutler/cache/CacheTest.java
@@ -18,7 +18,7 @@ private static Logger log = LoggerFactory.getLogger(CacheTest.class); @Test void reposCacheTest() { void repoCacheTest() { ConfigurationHandler configHandler = ConfigurationHandler.getInstance(); configHandler.read(); Configuration config = ConfigurationHandler.getConfiguration(); @@ -26,31 +26,43 @@ log.info("No repos configured. Please configure repos first in: " + configHandler.getConfigFile().getAbsolutePath()); return; } RepoInfoCache cache = ButlerCache.getReposCache(); cache.read(); if (cache.getElements().size() != config.getRepos().size()) { refreshReposCache(config, cache); ButlerCache butlerCache = ButlerCache.getInstance(); //butlerCache.removeAllCacheFiles(); butlerCache.read(); { RepoInfoCache repoInfoCache = ButlerCache.getRepoInfoCache(); if (repoInfoCache.getElements().size() != config.getRepos().size()) { refreshRepoInfoCache(config, repoInfoCache); } assertEquals(config.getRepos().size(), repoInfoCache.getElements().size()); } refreshRepoListsCache(config); assertEquals(config.getRepos().size(), cache.getElements().size()); { RepoListCache repoListCache = ButlerCache.getRepoListCache(); if (repoListCache.getElements().size() != config.getRepos().size()) { refreshRepoListCache(config, repoListCache); } assertEquals(config.getRepos().size(), repoListCache.getElements().size()); } butlerCache.save(); } private void refreshReposCache(Configuration config, RepoInfoCache cache) { private void refreshRepoInfoCache(Configuration config, RepoInfoCache repoInfoCache) { for (BorgRepoConfig repo : config.getRepos()) { log.info("Processing repo '" + repo + "'"); log.info("Processing repo info '" + repo + "'"); RepoInfo repoInfo = BorgCommands.info(repo); cache.upsert(repoInfo); repoInfo = cache.get(repoInfo.getRepository().getId()); repoInfoCache.upsert(repoInfo); repoInfo = repoInfoCache.get(repoInfo.getRepository().getId()); assertNotNull(repoInfo); } cache.save(); } private void refreshRepoListsCache(Configuration config) { private void refreshRepoListCache(Configuration config, RepoListCache repoListCache) { for (BorgRepoConfig repo : config.getRepos()) { log.info("Processing repo '" + repo + "'"); log.info("Processing repo list '" + repo + "'"); RepoList repoList = BorgCommands.list(repo); log.info("repoList: " + repoList); repoListCache.upsert(repoList); repoList = repoListCache.get(repoList.getRepository().getId()); assertNotNull(repoList); } } }