Merge branch 'stable-3.12'
* stable-3.12:
Update base OS to AlmaLinux 9.3 and Java 17
Get global-refdb.jar from Gerrit-CI
Bump Gerrit to 3.9
Add missing syslog-sidecar in docker-compose.yaml
Removing obsolete version attribute in docker-compose.yaml
Active/active setup using zookeeper-refdb plugin and zookeeper service
Change-Id: Ibe9e2dcf387705b3252c90916ab4285e0131dff6
diff --git a/BUILD b/BUILD
index 3735cb3..4beff6e 100644
--- a/BUILD
+++ b/BUILD
@@ -21,7 +21,6 @@
resources = glob(["src/main/resources/**/*"]),
deps = [
":global-refdb-neverlink",
- "@auto-value//jar",
"@failsafe//jar",
"@jgroups-kubernetes//jar",
"@jgroups//jar",
diff --git a/README.md b/README.md
index fcf0566..11a33b2 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# Gerrit high-availability plugin
-This plugin allows deploying a cluster of multiple Gerrit primaries
-on the same data-center sharing the same Git repositories.
+This plugin allows deploying a cluster of multiple Gerrit primary servers
+in the same data-center sharing the same Git repositories.
Requirements for the Gerrit primaries are:
@@ -17,6 +17,18 @@
Refer to the [build instructions in the plugin documentation](src/main/resources/Documentation/build.md).
+## Installation
+
+Install
+
+- the `high-availability` plugin in the Gerrit site's `plugins` folder.
+
+> **NOTE** the `global-refdb` lib module in the Gerrit site's `lib` folder, even if it is not used or referenced as libModule in the `gerrit.config`, because of a bug in the high-availability plugin initialisation sequence.
+
+In active-active deployments with multiple Gerrit primaries, installation of a global-refdb
+implementation is needed to maintain consistent ref updates across all
+Gerrit primary sites.
+
## Sample configuration for two Gerrit primaries in high-availability
Assuming that the Gerrit primaries in the clusters are `gerrit-01.mycompany.com` and
@@ -76,7 +88,11 @@
It is the simplest and safest configuration, where only one Gerrit primary at a
time serves the incoming requests.
+<<<<<<< HEAD
+In case of failure of the active primary, the traffic is forwarded to the backup.
+=======
In case of failure of the primary, the traffic is forwarded to the backup.
+>>>>>>> stable-3.12
Assuming a load-balancing implemented using [HAProxy](http://www.haproxy.org/)
associated with the domain name `gerrit.mycompany.com`, exposing Gerrit cluster nodes
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/ValidationModule.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/ValidationModule.java
index 9229d01..c770092 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/ValidationModule.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/ValidationModule.java
@@ -26,9 +26,6 @@
import com.gerritforge.gerrit.globalrefdb.validation.SharedRefDbRefUpdate;
import com.gerritforge.gerrit.globalrefdb.validation.SharedRefDbRepository;
import com.gerritforge.gerrit.globalrefdb.validation.SharedRefLogger;
-import com.gerritforge.gerrit.globalrefdb.validation.dfsrefdb.CustomSharedRefEnforcementByProject;
-import com.gerritforge.gerrit.globalrefdb.validation.dfsrefdb.DefaultSharedRefEnforcement;
-import com.gerritforge.gerrit.globalrefdb.validation.dfsrefdb.SharedRefEnforcement;
import com.google.gerrit.extensions.config.FactoryModule;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.server.ExceptionHook;
@@ -60,14 +57,6 @@
bind(GitRepositoryManager.class).to(SharedRefDbGitRepositoryManager.class);
- if (configuration.sharedRefDb().getSharedRefDb().getEnforcementRules().isEmpty()) {
- bind(SharedRefEnforcement.class).to(DefaultSharedRefEnforcement.class).in(Scopes.SINGLETON);
- } else {
- bind(SharedRefEnforcement.class)
- .to(CustomSharedRefEnforcementByProject.class)
- .in(Scopes.SINGLETON);
- }
-
DynamicSet.bind(binder(), ExceptionHook.class).to(SharedRefDbExceptionHook.class);
}
}
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/peers/jgroups/JGroupsPeerInfoProvider.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/peers/jgroups/JGroupsPeerInfoProvider.java
index 63f65d6..6079804 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/peers/jgroups/JGroupsPeerInfoProvider.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/peers/jgroups/JGroupsPeerInfoProvider.java
@@ -14,10 +14,10 @@
package com.ericsson.gerrit.plugins.highavailability.peers.jgroups;
-import autovalue.shaded.com.google.common.collect.ImmutableMap;
import com.ericsson.gerrit.plugins.highavailability.Configuration;
import com.ericsson.gerrit.plugins.highavailability.peers.PeerInfo;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.extensions.events.LifecycleListener;
diff --git a/src/main/resources/Documentation/about.md b/src/main/resources/Documentation/about.md
index 6fcd2e2..f62c035 100644
--- a/src/main/resources/Documentation/about.md
+++ b/src/main/resources/Documentation/about.md
@@ -27,15 +27,18 @@
sharing or synchronizing them.
#### Caches
+
Every time a cache eviction occurs in one of the instances, the eviction will be
forwarded the other nodes so their caches do not contain stale entries.
#### Secondary indexes
+
Every time the secondary index is modified in one of the instances, e.g., a change
is added, updated or removed from the index, the others instances index are updated
accordingly. This way, both indexes are kept synchronized.
#### Stream events
+
Every time a stream event occurs in one of the instances
(see [more events info](https://gerrit-review.googlesource.com/Documentation/cmd-stream-events.html#events)),
the event is forwarded to the other instances which re-plays it. This way, the output
@@ -43,6 +46,7 @@
connected to.
#### Web session
+
The built-in Gerrit H2 based web session cache is replaced with a file based
implementation that is shared amongst the instances.
@@ -55,8 +59,8 @@
For the instances:
-* Configure gerrit.basePath in gerrit.config to the shared repositories location
-* Configure gerrit.serverId in gerrit.config based on [config](config.md)'s introduction
+* Configure `gerrit.basePath` in `gerrit.config` to the shared repositories location
+* Configure `gerrit.serverId` in `gerrit.config` based on [config](config.md)'s introduction
* Install and configure this @PLUGIN@ plugin [further](config.md) or based on below.
Here is an example of the minimal @PLUGIN@.config:
@@ -110,25 +114,34 @@
* Git repositories must be located on a shared file system
* A directory on a shared file system must be available for @PLUGIN@ to use
-* An implementation of global-refdb (e.g. Zookeeper) must be accessible from all the active
-instances
+* An implementation of `global-refdb` (e.g. Zookeeper) must be accessible from all the active
+ instances to maintain consistent ref updates across all Gerrit primary sites
+
+The following `global-refdb` implementations are available:
+
+* [zookeeper-refdb plugin](https://gerrit.googlesource.com/plugins/zookeeper-refdb/+/refs/heads/master)
+ using Apache Zookeeper
+* [aws-dynamodb-refdb plugin](https://gerrit.googlesource.com/plugins/aws-dynamodb-refdb/+/refs/heads/master)
+ using AWS DynamoDB
+* [spanner-refdb plugin](https://gerrit.googlesource.com/plugins/spanner-refdb/+/refs/heads/master)
+ using Google Cloud Spanner
For the instances:
-* Configure gerrit.basePath in gerrit.config to the shared repositories location
-* Configure gerrit.serverId in gerrit.config based on [config](config.md)'s introduction
+* Configure `gerrit.basePath` in `gerrit.config` to the shared repositories location
+* Configure `gerrit.serverId` in `gerrit.config` based on [config](config.md)'s introduction
* Install and configure this @PLUGIN@ plugin [further](config.md) or based on example
configuration
-* Install @PLUGIN@ plugin as a database module in $GERRIT_SITE/lib(please note that
-@PLUGIN plugin must be installed as a plugin and as a database module) and add
-`installDbModule = com.ericsson.gerrit.plugins.highavailability.ValidationModule`
-to the gerrit section in gerrit.config
-* Install [global-refdb library](https://mvnrepository.com/artifact/com.gerritforge/global-refdb) as a library module in $GERRIT_SITE/lib and add
-`installModule = com.gerritforge.gerrit.globalrefdb.validation.LibModule` to the gerrit
-section in gerrit.config
+* Install @PLUGIN@ plugin as a database module in `$GERRIT_SITE/lib` (please note that
+@PLUGIN plugin must be installed as a plugin and as a database module) and add <br/>
+`installDbModule = com.ericsson.gerrit.plugins.highavailability.ValidationModule` <br/>
+to the gerrit section in `gerrit.config`
+* Install [global-refdb library](https://mvnrepository.com/artifact/com.gerritforge/global-refdb) as a library module in $GERRIT_SITE/lib and add <br/>
+`installModule = com.gerritforge.gerrit.globalrefdb.validation.LibModule` <br/>
+to the `gerrit` section in `gerrit.config`
* Install and configure [zookeeper-refdb plugin](https://gerrit-ci.gerritforge.com/view/Plugins-master/job/plugin-zookeeper-refdb-bazel-master) based on [config.md](https://gerrit.googlesource.com/plugins/zookeeper-refdb/+/refs/heads/master/src/main/resources/Documentation/config.md)
-* Configure ref-database.enabled = true in @PLUGIN@.config to enable validation with
-global-refdb.
+* Configure `ref-database.enabled = true` in @PLUGIN@.config to enable validation with
+`global-refdb`.
Here is an example of the minimal @PLUGIN@.config:
@@ -166,12 +179,13 @@
enabled = true
```
-Minimal zookeeper-refdb.config for both active instances:
+Minimal `zookeeper-refdb.config` for both active instances:
```
[ref-database "zookeeper"]
connectString = zookeeperhost:2181
```
+
### Last index update timestamp storage
The plugin keeps track of the timestamp when it lastly updated an index.
@@ -180,6 +194,7 @@
sync with the primary, for example, after a node being offline for a long time.
The HA plugin keeps the last update timestamp for each index in the following files:
+
* `<gerrit_home>/data/high-availability/account`
* `<gerrit_home>/data/high-availability/change`
diff --git a/src/test/README.md b/src/test/README.md
index 80fe2e4..b0aa3c4 100644
--- a/src/test/README.md
+++ b/src/test/README.md
@@ -1,8 +1,8 @@
# Gerrit high-availability docker setup example
The Docker Compose project in the docker directory contains a simple test
-environment of two Gerrit primaries in HA configuration, with their git repos
-hosted on NFS filesystem.
+environment of two Gerrit primary servers in HA configuration, with their
+git repos hosted on NFS filesystem.
## How to build
diff --git a/src/test/java/com/ericsson/gerrit/plugins/highavailability/ConfigurationTest.java b/src/test/java/com/ericsson/gerrit/plugins/highavailability/ConfigurationTest.java
index b51e1a0..0fb7dad 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/highavailability/ConfigurationTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/highavailability/ConfigurationTest.java
@@ -217,9 +217,6 @@
globalPluginConfig.setInt(HTTP_SECTION, null, CONNECTION_TIMEOUT_KEY, TIMEOUT);
assertThat(getConfiguration().http().connectionTimeout().toMillis()).isEqualTo(TIMEOUT);
-
- globalPluginConfig.setString(HTTP_SECTION, null, CONNECTION_TIMEOUT_KEY, INVALID_INT);
- assertThat(getConfiguration().http().connectionTimeout()).isEqualTo(DEFAULT_TIMEOUT);
}
@Test
@@ -228,9 +225,6 @@
globalPluginConfig.setInt(HTTP_SECTION, null, SOCKET_TIMEOUT_KEY, TIMEOUT);
assertThat(getConfiguration().http().socketTimeout().toMillis()).isEqualTo(TIMEOUT);
-
- globalPluginConfig.setString(HTTP_SECTION, null, SOCKET_TIMEOUT_KEY, INVALID_INT);
- assertThat(getConfiguration().http().socketTimeout()).isEqualTo(DEFAULT_TIMEOUT);
}
@Test
@@ -256,9 +250,6 @@
globalPluginConfig.setInt(HTTP_SECTION, null, RETRY_INTERVAL_KEY, RETRY_INTERVAL);
assertThat(getConfiguration().http().retryInterval().toMillis()).isEqualTo(RETRY_INTERVAL);
-
- globalPluginConfig.setString(HTTP_SECTION, null, RETRY_INTERVAL_KEY, INVALID_INT);
- assertThat(getConfiguration().http().retryInterval()).isEqualTo(DEFAULT_RETRY_INTERVAL);
}
@Test