Separate H2 command operations from SSH

In preparation for moving the SSH migration command over to HTTP,
decouple H2 commands from the SSH specific domain, so that the migration
command can be moved to HTTP and still leverage the common
functionality.

Bug: Issue 14086
Change-Id: I2d6537abc5d00da4baa146367531ba638b39ea08
diff --git a/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/AnalyzeH2Caches.java b/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/AnalyzeH2Caches.java
index bf86e78..6f501a9 100644
--- a/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/AnalyzeH2Caches.java
+++ b/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/AnalyzeH2Caches.java
@@ -13,8 +13,16 @@
 // limitations under the License.
 package com.googlesource.gerrit.modules.cache.chroniclemap;
 
+import static com.googlesource.gerrit.modules.cache.chroniclemap.H2CacheCommand.H2_SUFFIX;
+import static com.googlesource.gerrit.modules.cache.chroniclemap.H2CacheCommand.appendToConfig;
+import static com.googlesource.gerrit.modules.cache.chroniclemap.H2CacheCommand.baseName;
+import static com.googlesource.gerrit.modules.cache.chroniclemap.H2CacheCommand.getCacheDir;
+import static com.googlesource.gerrit.modules.cache.chroniclemap.H2CacheCommand.getStats;
+import static com.googlesource.gerrit.modules.cache.chroniclemap.H2CacheCommand.logger;
+
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.config.SitePaths;
+import com.google.gerrit.sshd.SshCommand;
 import com.google.inject.Inject;
 import java.io.IOException;
 import java.nio.file.Files;
@@ -24,7 +32,10 @@
 import java.util.stream.Collectors;
 import org.eclipse.jgit.lib.Config;
 
-public class AnalyzeH2Caches extends H2CacheSshCommand {
+public class AnalyzeH2Caches extends SshCommand {
+
+  private final Config gerritConfig;
+  private final SitePaths site;
 
   @Inject
   AnalyzeH2Caches(@GerritServerConfig Config cfg, SitePaths site) {
@@ -33,7 +44,7 @@
   }
 
   @Override
-  protected void run() throws UnloggedFailure, Failure, Exception {
+  protected void run() throws Exception {
     Set<Path> h2Files = getH2CacheFiles();
     stdout.println("Extracting information from H2 caches...");
 
@@ -56,10 +67,10 @@
     stdout.println(config.toText());
   }
 
-  private Set<Path> getH2CacheFiles() throws UnloggedFailure {
+  private Set<Path> getH2CacheFiles() throws Exception {
 
     try {
-      return getCacheDir()
+      return getCacheDir(gerritConfig, site)
           .map(
               cacheDir -> {
                 try {
diff --git a/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/H2CacheSshCommand.java b/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/H2CacheCommand.java
similarity index 86%
rename from src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/H2CacheSshCommand.java
rename to src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/H2CacheCommand.java
index ab964ce..b956a7b 100644
--- a/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/H2CacheSshCommand.java
+++ b/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/H2CacheCommand.java
@@ -15,7 +15,6 @@
 
 import com.google.common.flogger.FluentLogger;
 import com.google.gerrit.server.config.SitePaths;
-import com.google.gerrit.sshd.SshCommand;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -28,18 +27,15 @@
 import org.eclipse.jgit.lib.Config;
 import org.h2.Driver;
 
-public abstract class H2CacheSshCommand extends SshCommand {
+public class H2CacheCommand {
   protected static final FluentLogger logger = FluentLogger.forEnclosingClass();
-  protected static final String H2_SUFFIX = "h2.db";
+  public static final String H2_SUFFIX = "h2.db";
 
-  protected Config gerritConfig;
-  protected SitePaths site;
-
-  protected static String baseName(Path h2File) {
+  public static String baseName(Path h2File) {
     return FilenameUtils.removeExtension(FilenameUtils.getBaseName(h2File.toString()));
   }
 
-  protected static H2AggregateData getStats(Path h2File) throws UnloggedFailure {
+  protected static H2AggregateData getStats(Path h2File) throws Exception {
     String url = jdbcUrl(h2File);
     String baseName = baseName(h2File);
     try {
@@ -62,7 +58,7 @@
         return H2AggregateData.empty(baseName);
       }
     } catch (SQLException e) {
-      throw new UnloggedFailure(1, "fatal: " + e.getMessage(), e);
+      throw new Exception("fatal: " + e.getMessage(), e);
     }
   }
 
@@ -72,7 +68,8 @@
     return "jdbc:h2:" + normalized + ";AUTO_SERVER=TRUE";
   }
 
-  protected Optional<Path> getCacheDir() throws IOException {
+  protected static Optional<Path> getCacheDir(Config gerritConfig, SitePaths site)
+      throws IOException {
     String name = gerritConfig.getString("cache", null, "directory");
     if (name == null) {
       return Optional.empty();
@@ -89,7 +86,7 @@
     return Optional.of(loc);
   }
 
-  protected void appendToConfig(Config config, H2AggregateData stats) {
+  protected static void appendToConfig(Config config, H2AggregateData stats) {
     config.setLong("cache", stats.cacheName(), "maxEntries", stats.size());
     config.setLong("cache", stats.cacheName(), "avgKeySize", stats.avgKeySize());
     config.setLong("cache", stats.cacheName(), "avgValueSize", stats.avgValueSize());
diff --git a/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/MigrateH2Caches.java b/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/MigrateH2Caches.java
index d61fb85..f3827e1 100644
--- a/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/MigrateH2Caches.java
+++ b/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/MigrateH2Caches.java
@@ -13,6 +13,13 @@
 // limitations under the License.
 package com.googlesource.gerrit.modules.cache.chroniclemap;
 
+import static com.googlesource.gerrit.modules.cache.chroniclemap.H2CacheCommand.H2_SUFFIX;
+import static com.googlesource.gerrit.modules.cache.chroniclemap.H2CacheCommand.appendToConfig;
+import static com.googlesource.gerrit.modules.cache.chroniclemap.H2CacheCommand.getCacheDir;
+import static com.googlesource.gerrit.modules.cache.chroniclemap.H2CacheCommand.getStats;
+import static com.googlesource.gerrit.modules.cache.chroniclemap.H2CacheCommand.jdbcUrl;
+
+import com.google.common.flogger.FluentLogger;
 import com.google.gerrit.common.data.GlobalCapability;
 import com.google.gerrit.extensions.annotations.RequiresCapability;
 import com.google.gerrit.metrics.DisabledMetricMaker;
@@ -22,6 +29,7 @@
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.config.SitePaths;
 import com.google.gerrit.sshd.CommandMetaData;
+import com.google.gerrit.sshd.SshCommand;
 import com.google.inject.Binding;
 import com.google.inject.Inject;
 import com.google.inject.Injector;
@@ -44,13 +52,15 @@
 
 @RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER)
 @CommandMetaData(name = "migrate-h2-caches", description = "Migrate H2 caches to Chronicle-Map")
-public class MigrateH2Caches extends H2CacheSshCommand {
-
+public class MigrateH2Caches extends SshCommand {
+  protected static final FluentLogger logger = FluentLogger.forEnclosingClass();
   private final Injector injector;
   private final ChronicleMapCacheConfig.Factory configFactory;
 
   protected static int DEFAULT_SIZE_MULTIPLIER = 3;
   protected static int DEFAULT_MAX_BLOAT_FACTOR = 3;
+  private final SitePaths site;
+  private final Config gerritConfig;
 
   @Option(
       name = "--size-multiplier",
@@ -80,7 +90,7 @@
 
   @Override
   protected void run() throws Exception {
-    Optional<Path> cacheDir = getCacheDir();
+    Optional<Path> cacheDir = getCacheDir(gerritConfig, site);
 
     if (!cacheDir.isPresent()) {
       throw die("Cannot run migration, cache directory is not configured");
diff --git a/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/MigrateH2CachesIT.java b/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/MigrateH2CachesIT.java
index 89fe5f6..0359a45 100644
--- a/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/MigrateH2CachesIT.java
+++ b/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/MigrateH2CachesIT.java
@@ -15,7 +15,7 @@
 package com.googlesource.gerrit.modules.cache.chroniclemap;
 
 import static com.google.common.truth.Truth.assertThat;
-import static com.googlesource.gerrit.modules.cache.chroniclemap.H2CacheSshCommand.H2_SUFFIX;
+import static com.googlesource.gerrit.modules.cache.chroniclemap.H2CacheCommand.H2_SUFFIX;
 import static com.googlesource.gerrit.modules.cache.chroniclemap.MigrateH2Caches.DEFAULT_MAX_BLOAT_FACTOR;
 import static com.googlesource.gerrit.modules.cache.chroniclemap.MigrateH2Caches.DEFAULT_SIZE_MULTIPLIER;
 
@@ -39,7 +39,6 @@
 import com.google.gerrit.server.cache.serialize.ObjectIdConverter;
 import com.google.gerrit.server.config.SitePaths;
 import com.google.gerrit.server.git.GitRepositoryManager;
-import com.google.gerrit.sshd.BaseCommand;
 import com.google.inject.Binding;
 import com.google.inject.Inject;
 import com.google.inject.Key;
@@ -201,8 +200,7 @@
         && annotation.toString().endsWith(String.format("Named(value=\"%s\")", named));
   }
 
-  private <K, V> ChronicleMapCacheImpl<K, V> chronicleCacheFor(String cacheName)
-      throws BaseCommand.UnloggedFailure, IOException {
+  private <K, V> ChronicleMapCacheImpl<K, V> chronicleCacheFor(String cacheName) throws Exception {
     Path cacheDirectory = sitePaths.resolve(cfg.getString("cache", null, "directory"));
 
     PersistentCacheDef<K, V> persistentDef = getPersistentCacheDef(cacheName);
@@ -211,7 +209,7 @@
             chronicleMapCacheConfigFactory,
             cacheDirectory,
             persistentDef,
-            H2CacheSshCommand.getStats(
+            H2CacheCommand.getStats(
                 cacheDirectory.resolve(String.format("%s.%s", cacheName, H2_SUFFIX))),
             DEFAULT_SIZE_MULTIPLIER,
             DEFAULT_MAX_BLOAT_FACTOR);