summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDariusz Luksza <dariusz.luksza@gmail.com>2023-12-07 10:59:20 +0000
committerDariusz Luksza <dariusz.luksza@gmail.com>2024-01-05 11:46:48 +0000
commitcf1908ab78dfc00fdf11bdd9a680832569c67055 (patch)
tree2eec6fc0353f51d339aacccd2db081699028ec32
parent5c4fd7bf6e644f42073acb60ab804170e6eab9e5 (diff)
Add `ConfigResource` interface
This is a first step for providing replication configuration from an external source. The `ConfigResource` bundles together JGit `Config` instance with its version. The future implementations can read the configuration from a Gerrit project or external systems like ZooKeeper. The idea here is to separate the configuration resource from configuration options. This way it is easier to manage the configruation externally and also provide layers of configuration like "git config" command does. On top of the `ConfigResource` we sill use the `ReplicationConfig` and `ReplicationFileBasedConfig` to access plugin configuraiton options. The auto-reloading mechanism is also reused. Change-Id: I77d205dce223e508bf4a06c5ff9da91444a87032
-rw-r--r--src/main/java/com/googlesource/gerrit/plugins/replication/ConfigResource.java46
-rw-r--r--src/main/java/com/googlesource/gerrit/plugins/replication/FanoutReplicationConfig.java13
-rw-r--r--src/main/java/com/googlesource/gerrit/plugins/replication/FileConfigResource.java54
-rw-r--r--src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationConfigModule.java4
-rw-r--r--src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationFileBasedConfig.java37
5 files changed, 129 insertions, 25 deletions
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ConfigResource.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ConfigResource.java
new file mode 100644
index 0000000..7b41fe6
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ConfigResource.java
@@ -0,0 +1,46 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.replication;
+
+import org.eclipse.jgit.lib.Config;
+
+/**
+ * Separates configuration resource from the configuration schema.
+ *
+ * <p>The {@code ConfigResource} splits configuration source from configuration options. The
+ * resource is just an {@code Config} object with its version. The configuration options can be
+ * loaded from different sources eg. a single file, multiple files or ZooKeeper.
+ *
+ * <p>Here we don't assume any configuration options being present in the {@link Config} object,
+ * this is the responsibility of {@link ReplicationConfig} interface. Think about {@code
+ * ConfigResource} as a "plain text file" and {@code ReplicationConfig} as a XML file.
+ */
+public interface ConfigResource {
+
+ /**
+ * Configuration for the plugin and all replication end points.
+ *
+ * @return current configuration
+ */
+ Config getConfig();
+
+ /**
+ * Current logical version string of the current configuration loaded in memory, depending on the
+ * actual implementation of the configuration on the persistent storage.
+ *
+ * @return current logical version number.
+ */
+ String getVersion();
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/FanoutReplicationConfig.java b/src/main/java/com/googlesource/gerrit/plugins/replication/FanoutReplicationConfig.java
index b915d0d..80d8b9d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/FanoutReplicationConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/FanoutReplicationConfig.java
@@ -17,6 +17,7 @@ package com.googlesource.gerrit.plugins.replication;
import static com.google.common.io.Files.getNameWithoutExtension;
import static java.nio.charset.StandardCharsets.UTF_8;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
import com.google.common.flogger.FluentLogger;
import com.google.common.hash.Hasher;
@@ -43,12 +44,20 @@ public class FanoutReplicationConfig implements ReplicationConfig {
private final Config config;
private final Path remoteConfigsDirPath;
+ @VisibleForTesting
+ public FanoutReplicationConfig(SitePaths sitePaths, @PluginData Path pluginDataDir)
+ throws IOException, ConfigInvalidException {
+ this(
+ new ReplicationFileBasedConfig(new FileConfigResource(sitePaths), sitePaths, pluginDataDir),
+ sitePaths);
+ }
+
@Inject
- public FanoutReplicationConfig(SitePaths site, @PluginData Path pluginDataDir)
+ FanoutReplicationConfig(ReplicationFileBasedConfig replicationConfig, SitePaths site)
throws IOException, ConfigInvalidException {
remoteConfigsDirPath = site.etc_dir.resolve("replication");
- replicationConfig = new ReplicationFileBasedConfig(site, pluginDataDir);
+ this.replicationConfig = replicationConfig;
config = replicationConfig.getConfig();
removeRemotes(config);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/FileConfigResource.java b/src/main/java/com/googlesource/gerrit/plugins/replication/FileConfigResource.java
new file mode 100644
index 0000000..aad4666
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/FileConfigResource.java
@@ -0,0 +1,54 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.replication;
+
+import static com.googlesource.gerrit.plugins.replication.ReplicationQueue.repLog;
+
+import com.google.gerrit.server.config.SitePaths;
+import com.google.inject.Inject;
+import java.io.IOException;
+import java.nio.file.Path;
+import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.storage.file.FileBasedConfig;
+import org.eclipse.jgit.util.FS;
+
+public class FileConfigResource implements ConfigResource {
+ public static final String CONFIG_NAME = "replication.config";
+ private final FileBasedConfig config;
+
+ @Inject
+ FileConfigResource(SitePaths site) {
+ Path cfgPath = site.etc_dir.resolve(CONFIG_NAME);
+ this.config = new FileBasedConfig(cfgPath.toFile(), FS.DETECTED);
+ try {
+ config.load();
+ } catch (ConfigInvalidException e) {
+ repLog.atSevere().withCause(e).log("Config file %s is invalid: %s", cfgPath, e.getMessage());
+ } catch (IOException e) {
+ repLog.atSevere().withCause(e).log("Cannot read %s: %s", cfgPath, e.getMessage());
+ }
+ }
+
+ @Override
+ public Config getConfig() {
+ return config;
+ }
+
+ @Override
+ public String getVersion() {
+ return Long.toString(config.getFile().lastModified());
+ }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationConfigModule.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationConfigModule.java
index a2edd0b..2cc3982 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationConfigModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationConfigModule.java
@@ -14,6 +14,8 @@
package com.googlesource.gerrit.plugins.replication;
+import static com.googlesource.gerrit.plugins.replication.FileConfigResource.CONFIG_NAME;
+
import com.google.gerrit.extensions.events.LifecycleListener;
import com.google.gerrit.server.config.SitePaths;
import com.google.inject.AbstractModule;
@@ -37,7 +39,7 @@ public class ReplicationConfigModule extends AbstractModule {
@Inject
ReplicationConfigModule(SitePaths site) {
this.site = site;
- this.cfgPath = site.etc_dir.resolve("replication.config");
+ this.cfgPath = site.etc_dir.resolve(CONFIG_NAME);
}
@Override
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationFileBasedConfig.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationFileBasedConfig.java
index eed7556..9f45702 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationFileBasedConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationFileBasedConfig.java
@@ -13,46 +13,39 @@
// limitations under the License.
package com.googlesource.gerrit.plugins.replication;
-import static com.googlesource.gerrit.plugins.replication.ReplicationQueue.repLog;
-
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.annotations.PluginData;
import com.google.gerrit.server.config.SitePaths;
import com.google.inject.Inject;
-import java.io.IOException;
import java.nio.file.Path;
-import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Config;
-import org.eclipse.jgit.storage.file.FileBasedConfig;
-import org.eclipse.jgit.util.FS;
public class ReplicationFileBasedConfig implements ReplicationConfig {
private static final int DEFAULT_SSH_CONNECTION_TIMEOUT_MS = 2 * 60 * 1000; // 2 minutes
private final SitePaths site;
- private Path cfgPath;
private boolean replicateAllOnPluginStart;
private boolean defaultForceUpdate;
private int maxRefsToLog;
private final int maxRefsToShow;
private int sshCommandTimeout;
private int sshConnectionTimeout = DEFAULT_SSH_CONNECTION_TIMEOUT_MS;
- private final FileBasedConfig config;
+ private final ConfigResource configResource;
private final Path pluginDataDir;
+ @VisibleForTesting
+ public ReplicationFileBasedConfig(SitePaths paths, @PluginData Path pluginDataDir) {
+ this(new FileConfigResource(paths), paths, pluginDataDir);
+ }
+
@Inject
- public ReplicationFileBasedConfig(SitePaths site, @PluginData Path pluginDataDir) {
+ public ReplicationFileBasedConfig(
+ FileConfigResource configResource, SitePaths site, @PluginData Path pluginDataDir) {
this.site = site;
- this.cfgPath = site.etc_dir.resolve("replication.config");
- this.config = new FileBasedConfig(cfgPath.toFile(), FS.DETECTED);
- try {
- config.load();
- } catch (ConfigInvalidException e) {
- repLog.atSevere().withCause(e).log("Config file %s is invalid: %s", cfgPath, e.getMessage());
- } catch (IOException e) {
- repLog.atSevere().withCause(e).log("Cannot read %s: %s", cfgPath, e.getMessage());
- }
+ this.configResource = configResource;
+ Config config = configResource.getConfig();
this.replicateAllOnPluginStart = config.getBoolean("gerrit", "replicateOnStartup", false);
this.defaultForceUpdate = config.getBoolean("gerrit", "defaultForceUpdate", false);
this.maxRefsToLog = config.getInt("gerrit", "maxRefsToLog", 0);
@@ -93,7 +86,7 @@ public class ReplicationFileBasedConfig implements ReplicationConfig {
@Override
public int getDistributionInterval() {
- return config.getInt("replication", "distributionInterval", 0);
+ return getConfig().getInt("replication", "distributionInterval", 0);
}
@Override
@@ -108,7 +101,7 @@ public class ReplicationFileBasedConfig implements ReplicationConfig {
@Override
public Path getEventsDirectory() {
- String eventsDirectory = config.getString("replication", null, "eventsDirectory");
+ String eventsDirectory = getConfig().getString("replication", null, "eventsDirectory");
if (!Strings.isNullOrEmpty(eventsDirectory)) {
return site.resolve(eventsDirectory);
}
@@ -117,12 +110,12 @@ public class ReplicationFileBasedConfig implements ReplicationConfig {
@Override
public Config getConfig() {
- return config;
+ return configResource.getConfig();
}
@Override
public String getVersion() {
- return Long.toString(config.getFile().lastModified());
+ return configResource.getVersion();
}
@Override