Merge branch 'stable-3.2' into stable-3.3
* stable-3.2:
Remove unmaintained attempt to Dockerize the whole multi-site setup
Change-Id: I0eec9896cddcaccbc37f630d7baad07840ae0ddc
diff --git a/README.md b/README.md
index 0bf8486..34f7709 100644
--- a/README.md
+++ b/README.md
@@ -14,12 +14,10 @@
**NOTE**: The multi-site plugin will not start if Gerrit is not yet migrated
to NoteDb.
-Currently, the only mode supported is one primary read/write master
-and multiple read-only masters but eventually the plan is to support multiple
-read/write masters. The read/write master is handling any traffic while the
-read-only masters are serving the Gerrit GUI assets, the HTTP GET REST API and
-git fetch requests (git-upload-pack). The read-only masters are kept synchronized
-with the read/write master in order to be always ready to become a read/write master.
+Supports multiple read/write masters across multiple sites across different
+geographic locations. The Gerrit nodes are kept synchronized
+between each other using the replication plugin and a global ref-database in
+order to detect and prevent split-brains.
For more details on the overall multi-site design and roadmap, please refer
to the [multi-site plugin DESIGN.md document](DESIGN.md)
diff --git a/external_plugin_deps.bzl b/external_plugin_deps.bzl
index fee8aca..223778e 100644
--- a/external_plugin_deps.bzl
+++ b/external_plugin_deps.bzl
@@ -3,12 +3,12 @@
def external_plugin_deps():
maven_jar(
name = "global-refdb",
- artifact = "com.gerritforge:global-refdb:3.1.2",
- sha1 = "6ddee3de0f3fe9254453118ae1eca481ec03e957",
+ artifact = "com.gerritforge:global-refdb:3.3.1",
+ sha1 = "5df9dddad2fc67c922406f41549186b210cd957e",
)
maven_jar(
name = "events-broker",
- artifact = "com.gerritforge:events-broker:3.2.0-rc4",
- sha1 = "53e3f862ac2c2196dba716756ac9586f4b63af47",
+ artifact = "com.gerritforge:events-broker:3.3.2",
+ sha1 = "d8bcb77047cc12dd7c623b5b4de70a25499d3d6c",
)
diff --git a/setup_local_env/README.md b/setup_local_env/README.md
index 5b99996..fca46d8 100644
--- a/setup_local_env/README.md
+++ b/setup_local_env/README.md
@@ -4,7 +4,8 @@
The environment is composed by:
- 2 gerrit instances deployed by default in /tmp
-- 1 kafka node and 1 zookeeper node
+- 1 zookeeper node
+- 1 Broker node (kafka, kinesis or gcloud-pubsub)
- 1 HA-PROXY
## Requirements
@@ -14,15 +15,36 @@
- wget
- envsubst
- haproxy
+- aws-cli (only when broker_type is "kinesis")
## Examples
-Simplest setup with all default values and cleanup previous deployment
+Simplest setup with all default values and cleanup previous deployment. This
+will deploy kafka broker
```bash
sh setup_local_env/setup.sh --release-war-file /path/to/gerrit.war --multisite-lib-file /path/to/multi-site.jar
```
+Deploy Kinesis broker
+
+```bash
+sh setup_local_env/setup.sh \
+ --release-war-file /path/to/gerrit.war \
+ --multisite-lib-file /path/to/multi-site.jar \
+ --broker-type kinesis
+```
+
+Deploy GCloud PubSub broker
+
+```bash
+sh setup_local_env/setup.sh \
+ --release-war-file /path/to/gerrit.war \
+ --multisite-lib-file /path/to/multi-site.jar \
+ --broker-type gcloud-pubsub
+```
+
+
Cleanup the previous deployments
```bash
@@ -59,6 +81,8 @@
[--just-cleanup-env] Cleans up previous deployment; default false
[--enabled-https] Enabled https; default true
+
+[--broker_type] events broker type; 'kafka', 'kinesis' or 'gcloud-pubsub'. Default 'kafka'
```
## Limitations
diff --git a/setup_local_env/configs/gerrit.config b/setup_local_env/configs/gerrit.config
index 884b5be..c4df06a 100644
--- a/setup_local_env/configs/gerrit.config
+++ b/setup_local_env/configs/gerrit.config
@@ -18,6 +18,7 @@
[container]
javaOptions = "-Dflogger.backend_factory=com.google.common.flogger.backend.log4j.Log4jBackendFactory#getInstance"
javaOptions = "-Dflogger.logging_context=com.google.gerrit.server.logging.LoggingContext#getInstance"
+ javaOptions = "-DPUBSUB_EMULATOR_HOST=localhost:$BROKER_PORT"
javaOptions = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=$REMOTE_DEBUG_PORT"
[index]
type = LUCENE
@@ -41,13 +42,25 @@
directory = $FAKE_NFS
[plugin "events-kafka"]
sendAsync = true
- bootstrapServers = localhost:$KAFKA_PORT
- groupId = $KAFKA_GROUP_ID
+ bootstrapServers = localhost:$BROKER_PORT
+ groupId = $GROUP_ID
numberOfSubscribers = 6
securityProtocol = PLAINTEXT
pollingIntervalMs = 1000
enableAutoCommit = true
autoCommitIntervalMs = 1000
autoOffsetReset = latest
+[plugin "events-aws-kinesis"]
+ numberOfSubscribers = 6
+ pollingIntervalMs = 1000
+ region = us-east-1
+ endpoint = http://localhost:$BROKER_PORT
+ applicationName = $GROUP_ID
+ initialPosition = trim_horizon
+[plugin "events-gcloud-pubsub"]
+ numberOfSubscribers = 6
+ gcloudProject="test-project"
+ subscriptionId=$GROUP_ID
+ privateKeyLocation="not used in local mode"
[plugin "metrics-reporter-prometheus"]
prometheusBearerToken = token
diff --git a/setup_local_env/docker-compose.yaml b/setup_local_env/docker-compose-core.yaml
similarity index 61%
rename from setup_local_env/docker-compose.yaml
rename to setup_local_env/docker-compose-core.yaml
index c386d46..dab168d 100644
--- a/setup_local_env/docker-compose.yaml
+++ b/setup_local_env/docker-compose-core.yaml
@@ -5,15 +5,8 @@
ports:
- "2181:2181"
container_name: zk_test_node
- kafka:
- image: wurstmeister/kafka:2.12-2.1.0
- ports:
- - "9092:9092"
- container_name: kafka_test_node
- environment:
- KAFKA_ADVERTISED_HOST_NAME: 127.0.0.1
- KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
prometheus:
+ container_name: prometheus_test_node
image: prom/prometheus:v2.16.0
user: root
volumes:
diff --git a/setup_local_env/docker-compose-gcloud-pubsub.yaml b/setup_local_env/docker-compose-gcloud-pubsub.yaml
new file mode 100644
index 0000000..983e784
--- /dev/null
+++ b/setup_local_env/docker-compose-gcloud-pubsub.yaml
@@ -0,0 +1,13 @@
+version: '3'
+services:
+ pubsub:
+ image: gcr.io/google.com/cloudsdktool/cloud-sdk:316.0.0-emulators
+ ports:
+ - "8085:8085"
+ container_name: gcloud-pubsub_test_node
+ entrypoint: gcloud beta emulators pubsub start --project test-project --host-port 0.0.0.0:8085
+ networks:
+ - setup_local_env_default
+networks:
+ setup_local_env_default:
+ external: true
diff --git a/setup_local_env/docker-compose-kafka.yaml b/setup_local_env/docker-compose-kafka.yaml
new file mode 100644
index 0000000..8a31502
--- /dev/null
+++ b/setup_local_env/docker-compose-kafka.yaml
@@ -0,0 +1,15 @@
+version: '3'
+services:
+ kafka:
+ image: wurstmeister/kafka:2.12-2.1.0
+ ports:
+ - "9092:9092"
+ container_name: kafka_test_node
+ environment:
+ KAFKA_ADVERTISED_HOST_NAME: 127.0.0.1
+ KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
+ networks:
+ - setup_local_env_default
+networks:
+ setup_local_env_default:
+ external: true
diff --git a/setup_local_env/docker-compose-kinesis.yaml b/setup_local_env/docker-compose-kinesis.yaml
new file mode 100644
index 0000000..15c609e
--- /dev/null
+++ b/setup_local_env/docker-compose-kinesis.yaml
@@ -0,0 +1,17 @@
+version: '3'
+services:
+ kinesis:
+ image: localstack/localstack:0.12.8
+ ports:
+ - "4566:4566"
+ - "4751:4751"
+ container_name: kinesis_test_node
+ environment:
+ SERVICES: dynamodb,cloudwatch,kinesis
+ AWS_REGION: us-east-1
+ USE_SSL: "true"
+ networks:
+ - setup_local_env_default
+networks:
+ setup_local_env_default:
+ external: true
\ No newline at end of file
diff --git a/setup_local_env/haproxy-config/haproxy.cfg b/setup_local_env/haproxy-config/haproxy.cfg
index 94b22d8..de4f709 100644
--- a/setup_local_env/haproxy-config/haproxy.cfg
+++ b/setup_local_env/haproxy-config/haproxy.cfg
@@ -65,4 +65,5 @@
timeout connect 10s
timeout server 5m
server ssh_node1 $HA_GERRIT_SITE1_HOSTNAME:$HA_GERRIT_SITE1_SSHD_PORT check inter 10s check port $HA_GERRIT_SITE1_HTTPD_PORT inter 10s
- server ssh_node2 $HA_GERRIT_SITE2_HOSTNAME:$HA_GERRIT_SITE2_SSHD_PORT check inter 10s check port $HA_GERRIT_SITE2_HTTPD_PORT inter 10s backup
\ No newline at end of file
+ server ssh_node2 $HA_GERRIT_SITE2_HOSTNAME:$HA_GERRIT_SITE2_SSHD_PORT check inter 10s check port $HA_GERRIT_SITE2_HTTPD_PORT inter 10s backup
+
diff --git a/setup_local_env/setup.sh b/setup_local_env/setup.sh
index f3f3ae6..4266ce2 100755
--- a/setup_local_env/setup.sh
+++ b/setup_local_env/setup.sh
@@ -16,10 +16,11 @@
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
-GERRIT_BRANCH=stable-3.2
+GERRIT_BRANCH=stable-3.3
GERRIT_CI=https://gerrit-ci.gerritforge.com/view/Plugins-$GERRIT_BRANCH/job
LAST_BUILD=lastSuccessfulBuild/artifact/bazel-bin/plugins
EVENTS_BROKER_VER=`grep 'com.gerritforge:events-broker' $(dirname $0)/../external_plugin_deps.bzl | cut -d '"' -f 2 | cut -d ':' -f 3`
+GLOBAL_REFDB_VER=`grep 'com.gerritforge:global-refdb' $(dirname $0)/../external_plugin_deps.bzl | cut -d '"' -f 2 | cut -d ':' -f 3`
function check_application_requirements {
type haproxy >/dev/null 2>&1 || { echo >&2 "Require haproxy but it's not installed. Aborting."; exit 1; }
@@ -29,6 +30,9 @@
type wget >/dev/null 2>&1 || { echo >&2 "Require wget but it's not installed. Aborting."; exit 1; }
type envsubst >/dev/null 2>&1 || { echo >&2 "Require envsubst but it's not installed. Aborting."; exit 1; }
type openssl >/dev/null 2>&1 || { echo >&2 "Require openssl but it's not installed. Aborting."; exit 1; }
+ if [ "$BROKER_TYPE" = "kinesis" ]; then
+ type aws >/dev/null 2>&1 || { echo >&2 "Require aws-cli but it's not installed. Aborting."; exit 1; }
+ fi
}
function get_replication_url {
@@ -66,7 +70,7 @@
export GERRIT_HOSTNAME=$7
export REPLICATION_HOSTNAME=$8
export REMOTE_DEBUG_PORT=$9
- export KAFKA_GROUP_ID=${10}
+ export GROUP_ID=${10}
export REPLICATION_URL=$(get_replication_url $REPLICATION_LOCATION_TEST_SITE $REPLICATION_HOSTNAME)
echo "Replacing variables for file $file and copying to $CONFIG_TEST_SITE/$file_name"
@@ -98,10 +102,17 @@
haproxy -f $HA_PROXY_CONFIG_DIR/haproxy.cfg &
}
-function deploy_config_files {
- # KAFKA configuration
- export KAFKA_PORT=9092
+function export_broker_port {
+ if [ "$BROKER_TYPE" = "kinesis" ]; then
+ export BROKER_PORT=4566
+ elif [ "$BROKER_TYPE" = "kafka" ]; then
+ export BROKER_PORT=9092
+ elif [ "$BROKER_TYPE" = "gcloud-pubsub" ]; then
+ export BROKER_PORT=8085
+ fi
+}
+function deploy_config_files {
# ZK configuration
export ZK_PORT=2181
@@ -111,21 +122,21 @@
GERRIT_SITE1_SSHD_PORT=$3
CONFIG_TEST_SITE_1=$LOCATION_TEST_SITE_1/etc
GERRIT_SITE1_REMOTE_DEBUG_PORT="5005"
- GERRIT_SITE1_KAFKA_GROUP_ID="instance-1"
+ GERRIT_SITE1_GROUP_ID="instance-1"
# SITE 2
GERRIT_SITE2_HOSTNAME=$4
GERRIT_SITE2_HTTPD_PORT=$5
GERRIT_SITE2_SSHD_PORT=$6
CONFIG_TEST_SITE_2=$LOCATION_TEST_SITE_2/etc
GERRIT_SITE2_REMOTE_DEBUG_PORT="5006"
- GERRIT_SITE2_KAFKA_GROUP_ID="instance-2"
+ GERRIT_SITE2_GROUP_ID="instance-2"
# Set config SITE1
- copy_config_files $CONFIG_TEST_SITE_1 $GERRIT_SITE1_HTTPD_PORT $LOCATION_TEST_SITE_1 $GERRIT_SITE1_SSHD_PORT $GERRIT_SITE2_HTTPD_PORT $LOCATION_TEST_SITE_2 $GERRIT_SITE1_HOSTNAME $GERRIT_SITE2_HOSTNAME $GERRIT_SITE1_REMOTE_DEBUG_PORT $GERRIT_SITE1_KAFKA_GROUP_ID
+ copy_config_files $CONFIG_TEST_SITE_1 $GERRIT_SITE1_HTTPD_PORT $LOCATION_TEST_SITE_1 $GERRIT_SITE1_SSHD_PORT $GERRIT_SITE2_HTTPD_PORT $LOCATION_TEST_SITE_2 $GERRIT_SITE1_HOSTNAME $GERRIT_SITE2_HOSTNAME $GERRIT_SITE1_REMOTE_DEBUG_PORT $GERRIT_SITE1_GROUP_ID
# Set config SITE2
- copy_config_files $CONFIG_TEST_SITE_2 $GERRIT_SITE2_HTTPD_PORT $LOCATION_TEST_SITE_2 $GERRIT_SITE2_SSHD_PORT $GERRIT_SITE1_HTTPD_PORT $LOCATION_TEST_SITE_1 $GERRIT_SITE1_HOSTNAME $GERRIT_SITE2_HOSTNAME $GERRIT_SITE2_REMOTE_DEBUG_PORT $GERRIT_SITE2_KAFKA_GROUP_ID
+ copy_config_files $CONFIG_TEST_SITE_2 $GERRIT_SITE2_HTTPD_PORT $LOCATION_TEST_SITE_2 $GERRIT_SITE2_SSHD_PORT $GERRIT_SITE1_HTTPD_PORT $LOCATION_TEST_SITE_1 $GERRIT_SITE1_HOSTNAME $GERRIT_SITE2_HOSTNAME $GERRIT_SITE2_REMOTE_DEBUG_PORT $GERRIT_SITE2_GROUP_ID
}
function is_docker_desktop {
@@ -141,13 +152,33 @@
fi
}
+function create_kinesis_streams {
+ for stream in "gerrit_batch_index" "gerrit_cache_eviction" "gerrit_index" "gerrit_list_project" "gerrit_stream" "gerrit_web_session" "gerrit"
+ do
+ create_kinesis_stream $stream
+ done
+}
+
+function create_kinesis_stream {
+ local stream=$1
+
+ export AWS_PAGER=''
+ echo "[KINESIS] Create stream $stream"
+ until aws --endpoint-url=http://localhost:$BROKER_PORT kinesis create-stream --shard-count 1 --stream-name "$stream"
+ do
+ echo "[KINESIS stream $stream] Creation failed. Retrying in 5 seconds..."
+ sleep 5s
+ done
+}
function cleanup_environment {
echo "Killing existing HA-PROXY setup"
kill $(ps -ax | grep haproxy | grep "gerrit_setup/ha-proxy-config" | awk '{print $1}') 2> /dev/null
- echo "Stopping docker containers"
- docker-compose -f $SCRIPT_DIR/docker-compose.yaml down 2> /dev/null
+ echo "Stopping $BROKER_TYPE docker container"
+ docker-compose -f "${SCRIPT_DIR}/docker-compose-${BROKER_TYPE}.yaml" down 2> /dev/null
+ echo "Stopping core docker containers"
+ docker-compose -f "${SCRIPT_DIR}/docker-compose-core.yaml" down 2> /dev/null
echo "Stopping GERRIT instances"
$1/bin/gerrit.sh stop 2> /dev/null
@@ -157,8 +188,32 @@
rm -rf $3 2> /dev/null
}
-function check_if_kafka_is_running {
- echo $(docker inspect kafka_test_node 2> /dev/null | grep '"Running": true' | wc -l)
+function check_if_container_is_running {
+ local container=$1;
+ echo $(docker inspect "$container" 2> /dev/null | grep '"Running": true' | wc -l)
+}
+
+function ensure_docker_compose_is_up_and_running {
+ local log_label=$1
+ local container_name=$2
+ local docker_compose_file=$3
+
+ local is_container_running=$(check_if_container_is_running "$container_name")
+ if [ "$is_container_running" -lt 1 ];then
+ echo "[$log_label] Starting docker containers"
+ docker-compose -f "${SCRIPT_DIR}/${docker_compose_file}" up -d
+
+ echo "[$log_label] Waiting for docker containers to start..."
+ while [[ $(check_if_container_is_running "$container_name") -lt 1 ]];do sleep 10s; done
+ else
+ echo "[$log_label] Containers already running, nothing to do"
+ fi
+}
+
+function prepare_broker_data {
+ if [ "$BROKER_TYPE" = "kinesis" ]; then
+ create_kinesis_streams
+ fi
}
while [ $# -ne 0 ]
@@ -193,6 +248,8 @@
echo
echo "[--enabled-https] Enabled https; default true"
echo
+ echo "[--broker-type] events broker type; 'kafka', 'kinesis' or 'gcloud-pubsub'. Default 'kafka'"
+ echo
exit 0
;;
"--new-deployment")
@@ -280,6 +337,15 @@
shift
shift
;;
+ "--broker-type" )
+ BROKER_TYPE=$2
+ shift
+ shift
+ if [ ! "$BROKER_TYPE" = "kafka" ] && [ ! "$BROKER_TYPE" = "kinesis" ] && [ ! "$BROKER_TYPE" = "gcloud-pubsub" ]; then
+ echo >&2 "broker type: '$BROKER_TYPE' not valid. Please supply 'kafka','kinesis' or 'gcloud-pubsub'. Aborting"
+ exit 1
+ fi
+ ;;
* )
echo "Unknown option argument: $1"
shift
@@ -308,6 +374,7 @@
export REPLICATION_DELAY_SEC=${REPLICATION_DELAY_SEC:-"5"}
export SSH_ADVERTISED_PORT=${SSH_ADVERTISED_PORT:-"29418"}
HTTPS_ENABLED=${HTTPS_ENABLED:-"false"}
+BROKER_TYPE=${BROKER_TYPE:-"kafka"}
export COMMON_LOCATION=$DEPLOYMENT_LOCATION/gerrit_setup
LOCATION_TEST_SITE_1=$COMMON_LOCATION/instance-1
@@ -356,15 +423,37 @@
-O $DEPLOYMENT_LOCATION/zookeeper-refdb.jar || { echo >&2 "Cannot download zookeeper plugin: Check internet connection. Abort\
ing"; exit 1; }
+echo "Downloading global-refdb library $GERRIT_BRANCH"
+ wget https://repo1.maven.org/maven2/com/gerritforge/global-refdb/$GLOBAL_REFDB_VER/global-refdb-$GLOBAL_REFDB_VER.jar \
+ -O $DEPLOYMENT_LOCATION/global-refdb.jar || { echo >&2 "Cannot download global-refdb library: Check internet connection. Abort\
+ing"; exit 1; }
+
echo "Downloading events-broker library $GERRIT_BRANCH"
wget https://repo1.maven.org/maven2/com/gerritforge/events-broker/$EVENTS_BROKER_VER/events-broker-$EVENTS_BROKER_VER.jar \
-O $DEPLOYMENT_LOCATION/events-broker.jar || { echo >&2 "Cannot download events-broker library: Check internet connection. Abort\
ing"; exit 1; }
+if [ "$BROKER_TYPE" = "kafka" ]; then
echo "Downloading events-kafka plugin $GERRIT_BRANCH"
wget $GERRIT_CI/plugin-events-kafka-bazel-$GERRIT_BRANCH/$LAST_BUILD/events-kafka/events-kafka.jar \
-O $DEPLOYMENT_LOCATION/events-kafka.jar || { echo >&2 "Cannot download events-kafka plugin: Check internet connection. Abort\
ing"; exit 1; }
+fi
+
+if [ "$BROKER_TYPE" = "kinesis" ]; then
+echo "Downloading events-aws-kinesis plugin $GERRIT_BRANCH"
+ wget $GERRIT_CI/plugin-events-aws-kinesis-bazel-$GERRIT_BRANCH/$LAST_BUILD/events-aws-kinesis/events-aws-kinesis.jar \
+ -O $DEPLOYMENT_LOCATION/events-aws-kinesis.jar || { echo >&2 "Cannot download events-aws-kinesis plugin: Check internet connection. Abort\
+ing"; exit 1; }
+fi
+
+
+if [ "$BROKER_TYPE" = "gcloud-pubsub" ]; then
+echo "Downloading events-gcloud-pubsub plugin $GERRIT_BRANCH"
+ wget $GERRIT_CI/plugin-events-gcloud-pubsub-bazel-$GERRIT_BRANCH/$LAST_BUILD/events-gcloud-pubsub/events-gcloud-pubsub.jar \
+ -O $DEPLOYMENT_LOCATION/events-gcloud-pubsub.jar || { echo >&2 "Cannot download events-gcloud-pubsub plugin: Check internet connection. Abort\
+ing"; exit 1; }
+fi
echo "Downloading metrics-reporter-prometheus plugin $GERRIT_BRANCH"
wget $GERRIT_CI/plugin-metrics-reporter-prometheus-bazel-master-$GERRIT_BRANCH/$LAST_BUILD/metrics-reporter-prometheus/metrics-reporter-prometheus.jar \
@@ -410,11 +499,20 @@
echo "Copy zookeeper plugin"
cp -f $DEPLOYMENT_LOCATION/zookeeper-refdb.jar $LOCATION_TEST_SITE_1/plugins/zookeeper-refdb.jar
+ echo "Copy global refdb library"
+ cp -f $DEPLOYMENT_LOCATION/global-refdb.jar $LOCATION_TEST_SITE_1/lib/global-refdb.jar
+
echo "Copy events broker library"
cp -f $DEPLOYMENT_LOCATION/events-broker.jar $LOCATION_TEST_SITE_1/lib/events-broker.jar
- echo "Copy events kafka plugin"
- cp -f $DEPLOYMENT_LOCATION/events-kafka.jar $LOCATION_TEST_SITE_1/plugins/events-kafka.jar
+ echo "Copy $BROKER_TYPE events plugin"
+ if [ $BROKER_TYPE = "kinesis" ]; then
+ cp -f $DEPLOYMENT_LOCATION/events-aws-kinesis.jar $LOCATION_TEST_SITE_1/plugins/events-aws-kinesis.jar
+ elif [ $BROKER_TYPE = "gcloud-pubsub" ]; then
+ cp -f $DEPLOYMENT_LOCATION/events-gcloud-pubsub.jar $LOCATION_TEST_SITE_1/plugins/events-gcloud-pubsub.jar
+ else
+ cp -f $DEPLOYMENT_LOCATION/events-kafka.jar $LOCATION_TEST_SITE_1/plugins/events-kafka.jar
+ fi
echo "Copy metrics-reporter-prometheus plugin"
cp -f $DEPLOYMENT_LOCATION/metrics-reporter-prometheus.jar $LOCATION_TEST_SITE_1/plugins/metrics-reporter-prometheus.jar
@@ -446,14 +544,10 @@
cat $SCRIPT_DIR/configs/prometheus.yml | envsubst > $COMMON_LOCATION/prometheus.yml
-IS_KAFKA_RUNNING=$(check_if_kafka_is_running)
-if [ $IS_KAFKA_RUNNING -lt 1 ];then
-
- echo "Starting zk and kafka"
- docker-compose -f $SCRIPT_DIR/docker-compose.yaml up -d
- echo "Waiting for kafka to start..."
- while [[ $(check_if_kafka_is_running) -lt 1 ]];do sleep 10s; done
-fi
+export_broker_port
+ensure_docker_compose_is_up_and_running "core" "prometheus_test_node" "docker-compose-core.yaml"
+ensure_docker_compose_is_up_and_running "$BROKER_TYPE" "${BROKER_TYPE}_test_node" "docker-compose-$BROKER_TYPE.yaml"
+prepare_broker_data
echo "Re-deploying configuration files"
deploy_config_files $GERRIT_1_HOSTNAME $GERRIT_1_HTTPD_PORT $GERRIT_1_SSHD_PORT $GERRIT_2_HOSTNAME $GERRIT_2_HTTPD_PORT $GERRIT_2_SSHD_PORT
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java
index f509cd4..81e1c12 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java
@@ -17,17 +17,16 @@
import static com.google.common.base.Suppliers.memoize;
import static com.google.common.base.Suppliers.ofInstance;
+import com.gerritforge.gerrit.globalrefdb.validation.SharedRefDbConfiguration;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
+import com.google.common.base.Strings;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.MultimapBuilder;
import com.google.gerrit.server.config.SitePaths;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.inject.spi.Message;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement.EnforcePolicy;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
@@ -62,7 +61,7 @@
private final Supplier<Event> event;
private final Supplier<Index> index;
private final Supplier<Projects> projects;
- private final Supplier<SharedRefDatabase> sharedRefDb;
+ private final Supplier<SharedRefDbConfiguration> sharedRefDb;
private final Supplier<Collection<Message>> replicationConfigValidation;
private final Supplier<Broker> broker;
private final Config multiSiteConfig;
@@ -81,7 +80,11 @@
event = memoize(() -> new Event(lazyMultiSiteCfg));
index = memoize(() -> new Index(lazyMultiSiteCfg));
projects = memoize(() -> new Projects(lazyMultiSiteCfg));
- sharedRefDb = memoize(() -> new SharedRefDatabase(lazyMultiSiteCfg));
+ sharedRefDb =
+ memoize(
+ () ->
+ new SharedRefDbConfiguration(
+ enableSharedRefDbByDefault(lazyMultiSiteCfg.get()), PLUGIN_NAME));
broker = memoize(() -> new Broker(lazyMultiSiteCfg));
}
@@ -89,7 +92,7 @@
return multiSiteConfig;
}
- public SharedRefDatabase getSharedRefDb() {
+ public SharedRefDbConfiguration getSharedRefDbConfiguration() {
return sharedRefDb.get();
}
@@ -121,6 +124,21 @@
return new FileBasedConfig(sitePaths.etc_dir.resolve(configFileName).toFile(), FS.DETECTED);
}
+ private Config enableSharedRefDbByDefault(Config cfg) {
+ if (Strings.isNullOrEmpty(
+ cfg.getString(
+ SharedRefDbConfiguration.SharedRefDatabase.SECTION,
+ null,
+ SharedRefDbConfiguration.SharedRefDatabase.ENABLE_KEY))) {
+ cfg.setBoolean(
+ SharedRefDbConfiguration.SharedRefDatabase.SECTION,
+ null,
+ SharedRefDbConfiguration.SharedRefDatabase.ENABLE_KEY,
+ true);
+ }
+ return cfg;
+ }
+
private Supplier<Config> lazyLoad(Config config) {
if (config instanceof FileBasedConfig) {
return memoize(
@@ -172,38 +190,6 @@
}
}
- public static class SharedRefDatabase {
- public static final String SECTION = "ref-database";
- public static final String ENABLE_KEY = "enabled";
- public static final String SUBSECTION_ENFORCEMENT_RULES = "enforcementRules";
-
- private final boolean enabled;
- private final Multimap<EnforcePolicy, String> enforcementRules;
-
- private SharedRefDatabase(Supplier<Config> cfg) {
- enabled = getBoolean(cfg, SECTION, null, ENABLE_KEY, true);
-
- enforcementRules = MultimapBuilder.hashKeys().arrayListValues().build();
- for (EnforcePolicy policy : EnforcePolicy.values()) {
- enforcementRules.putAll(
- policy, getList(cfg, SECTION, SUBSECTION_ENFORCEMENT_RULES, policy.name()));
- }
- }
-
- public boolean isEnabled() {
- return enabled;
- }
-
- public Multimap<EnforcePolicy, String> getEnforcementRules() {
- return enforcementRules;
- }
-
- private List<String> getList(
- Supplier<Config> cfg, String section, String subsection, String name) {
- return ImmutableList.copyOf(cfg.get().getStringList(section, subsection, name));
- }
- }
-
public static class Projects {
public static final String SECTION = "projects";
public static final String PATTERN_KEY = "pattern";
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/GitModule.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/GitModule.java
index 4f7205d..87e9d22 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/GitModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/GitModule.java
@@ -28,7 +28,7 @@
@Override
protected void configure() {
- if (config.getSharedRefDb().isEnabled()) {
+ if (config.getSharedRefDbConfiguration().getSharedRefDb().isEnabled()) {
install(new ValidationModule(config));
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/LockWrapper.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/LockWrapper.java
deleted file mode 100644
index 0e018d3..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/LockWrapper.java
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (C) 2019 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.multisite;
-
-import com.google.inject.Inject;
-import com.google.inject.assistedinject.Assisted;
-
-public class LockWrapper implements AutoCloseable {
- public interface Factory {
- LockWrapper create(
- @Assisted("project") String project,
- @Assisted("refName") String refName,
- @Assisted("lock") AutoCloseable lock);
- }
-
- private final String project;
- private final String refName;
- private final AutoCloseable lock;
- private final SharedRefLogger sharedRefLogger;
-
- @Inject
- public LockWrapper(
- SharedRefLogger sharedRefLogger,
- @Assisted("project") String project,
- @Assisted("refName") String refName,
- @Assisted("lock") AutoCloseable lock) {
- this.lock = lock;
- this.sharedRefLogger = sharedRefLogger;
- this.project = project;
- this.refName = refName;
- }
-
- @Override
- public void close() throws Exception {
- lock.close();
- sharedRefLogger.logLockRelease(project, refName);
- }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/Log4jSharedRefLogger.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/Log4jSharedRefLogger.java
deleted file mode 100644
index 003ce5b..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/Log4jSharedRefLogger.java
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright (C) 2019 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.multisite;
-
-import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
-import static org.eclipse.jgit.lib.Constants.OBJ_COMMIT;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.flogger.FluentLogger;
-import com.google.gerrit.entities.Project;
-import com.google.gerrit.extensions.common.GitPerson;
-import com.google.gerrit.json.OutputFormat;
-import com.google.gerrit.server.CommonConverters;
-import com.google.gerrit.server.git.GitRepositoryManager;
-import com.google.gerrit.server.util.SystemLog;
-import com.google.gson.Gson;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import java.io.IOException;
-import org.apache.log4j.PatternLayout;
-import org.eclipse.jgit.errors.IncorrectObjectTypeException;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.revwalk.RevWalk;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Singleton
-public class Log4jSharedRefLogger extends LibModuleLogFile implements SharedRefLogger {
- private static final String LOG_NAME = "sharedref_log";
- private Logger sharedRefDBLog;
- private final GitRepositoryManager gitRepositoryManager;
- private static final Gson gson = OutputFormat.JSON_COMPACT.newGson();
-
- private static final FluentLogger logger = FluentLogger.forEnclosingClass();
-
- @Inject
- public Log4jSharedRefLogger(SystemLog systemLog, GitRepositoryManager gitRepositoryManager) {
- super(systemLog, LOG_NAME, new PatternLayout("[%d{ISO8601}] [%t] %-5p : %m%n"));
- this.gitRepositoryManager = gitRepositoryManager;
- sharedRefDBLog = LoggerFactory.getLogger(LOG_NAME);
- }
-
- @Override
- public void logRefUpdate(String project, Ref currRef, ObjectId newRefValue) {
- if (!ObjectId.zeroId().equals(newRefValue)) {
- try (Repository repository = gitRepositoryManager.openRepository(Project.nameKey(project));
- RevWalk walk = new RevWalk(repository)) {
- GitPerson committer = null;
- String commitMessage = null;
- if (newRefValue != null) {
- int objectType = walk.parseAny(newRefValue).getType();
- switch (objectType) {
- case OBJ_COMMIT:
- RevCommit commit = walk.parseCommit(newRefValue);
- committer = CommonConverters.toGitPerson(commit.getCommitterIdent());
- commitMessage = commit.getShortMessage();
- break;
- case OBJ_BLOB:
- break;
- default:
- throw new IncorrectObjectTypeException(newRefValue, Constants.typeString(objectType));
- }
- }
- sharedRefDBLog.info(
- gson.toJson(
- new SharedRefLogEntry.UpdateRef(
- project,
- currRef.getName(),
- currRef.getObjectId().getName(),
- newRefValue == null ? ObjectId.zeroId().name() : newRefValue.getName(),
- committer,
- commitMessage)));
- } catch (IOException e) {
- logger.atSevere().withCause(e).log(
- "Cannot log sharedRefDB interaction for ref %s on project %s",
- currRef.getName(), project);
- }
- } else {
- sharedRefDBLog.info(
- gson.toJson(
- new SharedRefLogEntry.DeleteRef(
- project, currRef.getName(), currRef.getObjectId().getName())));
- }
- }
-
- @Override
- public <T> void logRefUpdate(String project, String refName, T currRef, T newRefValue) {
- if (newRefValue != null) {
- sharedRefDBLog.info(
- gson.toJson(
- new SharedRefLogEntry.UpdateRef(
- project, refName, safeToString(currRef), safeToString(newRefValue), null, null)));
- } else {
- sharedRefDBLog.info(
- gson.toJson(new SharedRefLogEntry.DeleteRef(project, refName, safeToString(currRef))));
- }
- }
-
- @Override
- public void logProjectDelete(String project) {
- sharedRefDBLog.info(gson.toJson(new SharedRefLogEntry.DeleteProject(project)));
- }
-
- @Override
- public void logLockAcquisition(String project, String refName) {
- sharedRefDBLog.info(gson.toJson(new SharedRefLogEntry.LockAcquire(project, refName)));
- }
-
- @Override
- public void logLockRelease(String project, String refName) {
- sharedRefDBLog.info(gson.toJson(new SharedRefLogEntry.LockRelease(project, refName)));
- }
-
- @VisibleForTesting
- public void setLogger(Logger logger) {
- this.sharedRefDBLog = logger;
- }
-
- private <T> String safeToString(T currRef) {
- if (currRef == null) {
- return "<null>";
- }
- return currRef.toString();
- }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/Module.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/Module.java
index 708e707..f44f4f7 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/Module.java
@@ -14,14 +14,12 @@
package com.googlesource.gerrit.plugins.multisite;
-import com.gerritforge.gerrit.globalrefdb.GlobalRefDatabase;
-import com.google.gerrit.extensions.registration.DynamicItem;
+import com.gerritforge.gerrit.globalrefdb.validation.LibModule;
import com.google.gerrit.lifecycle.LifecycleModule;
import com.google.gerrit.server.config.SitePaths;
import com.google.inject.CreationException;
import com.google.inject.Inject;
import com.google.inject.Provides;
-import com.google.inject.Scopes;
import com.google.inject.Singleton;
import com.google.inject.spi.Message;
import com.googlesource.gerrit.plugins.multisite.cache.CacheModule;
@@ -29,7 +27,6 @@
import com.googlesource.gerrit.plugins.multisite.forwarder.ForwarderModule;
import com.googlesource.gerrit.plugins.multisite.forwarder.router.RouterModule;
import com.googlesource.gerrit.plugins.multisite.index.IndexModule;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.NoopSharedRefDatabase;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
@@ -58,11 +55,7 @@
throw new CreationException(validationErrors);
}
- DynamicItem.itemOf(binder(), GlobalRefDatabase.class);
- DynamicItem.bind(binder(), GlobalRefDatabase.class)
- .to(NoopSharedRefDatabase.class)
- .in(Scopes.SINGLETON);
- log.info("Shared ref-db engine: none");
+ install(new LibModule());
listener().to(Log4jMessageLogger.class);
bind(MessageLogger.class).to(Log4jMessageLogger.class);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginModule.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginModule.java
index 2eaa5d9..81a0d8d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginModule.java
@@ -14,6 +14,7 @@
package com.googlesource.gerrit.plugins.multisite;
+import com.gerritforge.gerrit.globalrefdb.validation.ProjectDeletedSharedDbCleanup;
import com.google.gerrit.extensions.events.ProjectDeletedListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.lifecycle.LifecycleModule;
@@ -23,7 +24,6 @@
import com.googlesource.gerrit.plugins.multisite.consumer.MultiSiteConsumerRunner;
import com.googlesource.gerrit.plugins.multisite.consumer.SubscriberModule;
import com.googlesource.gerrit.plugins.multisite.forwarder.broker.BrokerForwarderModule;
-import com.googlesource.gerrit.plugins.multisite.validation.ProjectDeletedSharedDbCleanup;
public class PluginModule extends LifecycleModule {
private Configuration config;
@@ -41,7 +41,7 @@
install(new BrokerForwarderModule());
listener().to(MultiSiteConsumerRunner.class);
- if (config.getSharedRefDb().isEnabled()) {
+ if (config.getSharedRefDbConfiguration().getSharedRefDb().isEnabled()) {
listener().to(PluginStartup.class);
DynamicSet.bind(binder(), ProjectDeletedListener.class)
.to(ProjectDeletedSharedDbCleanup.class);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginStartup.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginStartup.java
index 33b54d2..db7064c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginStartup.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginStartup.java
@@ -14,6 +14,7 @@
package com.googlesource.gerrit.plugins.multisite;
+import com.gerritforge.gerrit.globalrefdb.validation.SharedRefDatabaseWrapper;
import com.google.gerrit.extensions.events.LifecycleListener;
import com.google.inject.Inject;
import com.google.inject.Injector;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/ProjectsFilter.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/ProjectsFilter.java
deleted file mode 100644
index d6fac47..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/ProjectsFilter.java
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (C) 2020 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.multisite;
-
-import com.google.common.base.Strings;
-import com.google.common.collect.Sets;
-import com.google.gerrit.common.data.AccessSection;
-import com.google.gerrit.entities.Project;
-import com.google.gerrit.entities.Project.NameKey;
-import com.google.gerrit.server.events.Event;
-import com.google.gerrit.server.events.ProjectEvent;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import java.util.List;
-import java.util.Set;
-
-@Singleton
-public class ProjectsFilter {
- public enum PatternType {
- REGEX,
- WILDCARD,
- EXACT_MATCH;
-
- public static PatternType getPatternType(String pattern) {
- if (pattern.startsWith(AccessSection.REGEX_PREFIX)) {
- return REGEX;
- } else if (pattern.endsWith("*")) {
- return WILDCARD;
- } else {
- return EXACT_MATCH;
- }
- }
- }
-
- private Set<NameKey> globalProjects = Sets.newConcurrentHashSet();
- private Set<NameKey> localProjects = Sets.newConcurrentHashSet();
- private final List<String> projectPatterns;
-
- @Inject
- public ProjectsFilter(Configuration cfg) {
- projectPatterns = cfg.projects().getPatterns();
- }
-
- public boolean matches(Event event) {
- if (event == null) {
- throw new IllegalArgumentException("Event object cannot be null");
- }
- if (event instanceof ProjectEvent) {
- return matches(((ProjectEvent) event).getProjectNameKey());
- }
- return false;
- }
-
- public boolean matches(String projectName) {
- return matches(NameKey.parse(projectName));
- }
-
- public boolean matches(Project.NameKey name) {
- if (name == null || Strings.isNullOrEmpty(name.get())) {
- throw new IllegalArgumentException(
- String.format("Project name cannot be null or empty, but was %s", name));
- }
- if (projectPatterns.isEmpty() || globalProjects.contains(name)) {
- return true;
- }
-
- if (localProjects.contains(name)) {
- return false;
- }
-
- String projectName = name.get();
-
- for (String pattern : projectPatterns) {
- if (matchesPattern(projectName, pattern)) {
- globalProjects.add(name);
- return true;
- }
- }
- localProjects.add(name);
- return false;
- }
-
- private boolean matchesPattern(String projectName, String pattern) {
- boolean match = false;
- switch (PatternType.getPatternType(pattern)) {
- case REGEX:
- match = projectName.matches(pattern);
- break;
- case WILDCARD:
- match = projectName.startsWith(pattern.substring(0, pattern.length() - 1));
- break;
- case EXACT_MATCH:
- match = projectName.equals(pattern);
- }
- return match;
- }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/SharedRefDatabaseWrapper.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/SharedRefDatabaseWrapper.java
deleted file mode 100644
index ddf9d84..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/SharedRefDatabaseWrapper.java
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (C) 2019 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.multisite;
-
-import com.gerritforge.gerrit.globalrefdb.GlobalRefDatabase;
-import com.gerritforge.gerrit.globalrefdb.GlobalRefDbLockException;
-import com.gerritforge.gerrit.globalrefdb.GlobalRefDbSystemError;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.gerrit.entities.Project;
-import com.google.gerrit.extensions.registration.DynamicItem;
-import com.google.inject.Inject;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.NoopSharedRefDatabase;
-import java.util.Optional;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Ref;
-
-public class SharedRefDatabaseWrapper implements GlobalRefDatabase {
- private static final GlobalRefDatabase NOOP_REFDB = new NoopSharedRefDatabase();
-
- @Inject(optional = true)
- private DynamicItem<GlobalRefDatabase> sharedRefDbDynamicItem;
-
- private final SharedRefLogger sharedRefLogger;
-
- @Inject
- public SharedRefDatabaseWrapper(SharedRefLogger sharedRefLogger) {
- this.sharedRefLogger = sharedRefLogger;
- }
-
- @VisibleForTesting
- public SharedRefDatabaseWrapper(
- DynamicItem<GlobalRefDatabase> sharedRefDbDynamicItem, SharedRefLogger sharedRefLogger) {
- this.sharedRefLogger = sharedRefLogger;
- this.sharedRefDbDynamicItem = sharedRefDbDynamicItem;
- }
-
- @Override
- public boolean isUpToDate(Project.NameKey project, Ref ref) throws GlobalRefDbLockException {
- return sharedRefDb().isUpToDate(project, ref);
- }
-
- @Override
- public boolean compareAndPut(Project.NameKey project, Ref currRef, ObjectId newRefValue)
- throws GlobalRefDbSystemError {
- boolean succeeded = sharedRefDb().compareAndPut(project, currRef, newRefValue);
- if (succeeded) {
- sharedRefLogger.logRefUpdate(project.get(), currRef, newRefValue);
- }
- return succeeded;
- }
-
- @Override
- public <T> boolean compareAndPut(Project.NameKey project, String refName, T currValue, T newValue)
- throws GlobalRefDbSystemError {
- boolean succeeded = sharedRefDb().compareAndPut(project, refName, currValue, newValue);
- if (succeeded) {
- sharedRefLogger.logRefUpdate(project.get(), refName, currValue, newValue);
- }
- return succeeded;
- }
-
- @Override
- public AutoCloseable lockRef(Project.NameKey project, String refName)
- throws GlobalRefDbLockException {
- AutoCloseable locker = sharedRefDb().lockRef(project, refName);
- sharedRefLogger.logLockAcquisition(project.get(), refName);
- return locker;
- }
-
- @Override
- public boolean exists(Project.NameKey project, String refName) {
- return sharedRefDb().exists(project, refName);
- }
-
- @Override
- public void remove(Project.NameKey project) throws GlobalRefDbSystemError {
- sharedRefDb().remove(project);
- sharedRefLogger.logProjectDelete(project.get());
- }
-
- @Override
- public <T> Optional<T> get(Project.NameKey nameKey, String s, Class<T> clazz)
- throws GlobalRefDbSystemError {
- return sharedRefDb().get(nameKey, s, clazz);
- }
-
- private GlobalRefDatabase sharedRefDb() {
- return Optional.ofNullable(sharedRefDbDynamicItem).map(di -> di.get()).orElse(NOOP_REFDB);
- }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/SharedRefLogEntry.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/SharedRefLogEntry.java
deleted file mode 100644
index d9e762f..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/SharedRefLogEntry.java
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright (C) 2019 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.multisite;
-
-import com.google.gerrit.common.Nullable;
-import com.google.gerrit.extensions.common.GitPerson;
-
-public class SharedRefLogEntry {
-
- public enum Type {
- UPDATE_REF,
- DELETE_REF,
- DELETE_PROJECT,
- LOCK_ACQUIRE,
- LOCK_RELEASE
- }
-
- public String projectName;
- public Type type;
-
- public static class UpdateRef extends SharedRefLogEntry {
-
- public String refName;
- public String oldId;
- public String newId;
- public GitPerson committer;
- public String comment;
-
- UpdateRef(
- String projectName,
- String refName,
- String oldId,
- String newId,
- @Nullable GitPerson committer,
- @Nullable String comment) {
- this.type = Type.UPDATE_REF;
- this.projectName = projectName;
- this.refName = refName;
- this.oldId = oldId;
- this.newId = newId;
- this.committer = committer;
- this.comment = comment;
- }
- }
-
- public static class DeleteProject extends SharedRefLogEntry {
-
- DeleteProject(String projectName) {
- this.type = Type.DELETE_PROJECT;
- this.projectName = projectName;
- }
- }
-
- public static class DeleteRef extends SharedRefLogEntry {
-
- public String refName;
- public String oldId;
-
- DeleteRef(String projectName, String refName, String oldId) {
- this.type = Type.DELETE_REF;
- this.projectName = projectName;
- this.refName = refName;
- this.oldId = oldId;
- }
- }
-
- public static class LockAcquire extends SharedRefLogEntry {
-
- public String refName;
-
- LockAcquire(String projectName, String refName) {
- this.type = Type.LOCK_ACQUIRE;
- this.projectName = projectName;
- this.refName = refName;
- }
- }
-
- public static class LockRelease extends SharedRefLogEntry {
-
- public String refName;
-
- LockRelease(String projectName, String refName) {
- this.type = Type.LOCK_RELEASE;
- this.projectName = projectName;
- this.refName = refName;
- }
- }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/SharedRefLogger.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/SharedRefLogger.java
deleted file mode 100644
index 3853af6..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/SharedRefLogger.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (C) 2019 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.multisite;
-
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Ref;
-
-public interface SharedRefLogger {
-
- void logRefUpdate(String project, Ref currRef, ObjectId newRefValue);
-
- <T> void logRefUpdate(String project, String refName, T currRef, T newRefValue);
-
- void logProjectDelete(String project);
-
- void logLockAcquisition(String project, String refName);
-
- void logLockRelease(String project, String refName);
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandler.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandler.java
index 2e2f9de..fdc6fc3 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandler.java
@@ -14,13 +14,13 @@
package com.googlesource.gerrit.plugins.multisite.cache;
+import com.gerritforge.gerrit.globalrefdb.validation.ProjectsFilter;
import com.google.gerrit.extensions.events.NewProjectCreatedListener;
import com.google.gerrit.extensions.events.ProjectDeletedListener;
import com.google.gerrit.extensions.events.ProjectEvent;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.inject.Inject;
import com.google.inject.Singleton;
-import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
import com.googlesource.gerrit.plugins.multisite.forwarder.ForwarderTask;
import com.googlesource.gerrit.plugins.multisite.forwarder.ProjectListUpdateForwarder;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/consumer/AbstractSubcriber.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/consumer/AbstractSubcriber.java
index 1f8766a..b37f434 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/consumer/AbstractSubcriber.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/consumer/AbstractSubcriber.java
@@ -15,6 +15,7 @@
package com.googlesource.gerrit.plugins.multisite.consumer;
import com.gerritforge.gerrit.eventbroker.EventMessage;
+import com.google.common.base.Strings;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.server.permissions.PermissionBackendException;
@@ -34,7 +35,7 @@
private final ForwardedEventRouter eventRouter;
private final DynamicSet<DroppedEventListener> droppedEventListeners;
- private final UUID instanceId;
+ private final String instanceId;
private final MessageLogger msgLog;
private SubscriberMetrics subscriberMetrics;
private final Configuration cfg;
@@ -49,7 +50,7 @@
Configuration cfg) {
this.eventRouter = eventRouter;
this.droppedEventListeners = droppedEventListeners;
- this.instanceId = instanceId;
+ this.instanceId = instanceId.toString();
this.msgLog = msgLog;
this.subscriberMetrics = subscriberMetrics;
this.cfg = cfg;
@@ -63,11 +64,18 @@
}
private void processRecord(EventMessage event) {
+ String sourceInstanceId = event.getHeader().sourceInstanceId;
- if (event.getHeader().sourceInstanceId.equals(instanceId)) {
- logger.atFiner().log(
- "Dropping event %s produced by our instanceId %s",
- event.toString(), instanceId.toString());
+ if (Strings.isNullOrEmpty(sourceInstanceId) || instanceId.equals(sourceInstanceId)) {
+ if (Strings.isNullOrEmpty(sourceInstanceId)) {
+ logger.atWarning().log(
+ String.format(
+ "Dropping event %s because sourceInstanceId cannot be null", event.toString()));
+ } else {
+ logger.atFiner().log(
+ String.format(
+ "Dropping event %s produced by our instanceId %s", event.toString(), instanceId));
+ }
droppedEventListeners.forEach(l -> l.onEventDropped(event));
} else {
try {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/event/EventHandler.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/event/EventHandler.java
index a1b7a53..b2efb80 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/event/EventHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/event/EventHandler.java
@@ -14,12 +14,12 @@
package com.googlesource.gerrit.plugins.multisite.event;
+import com.gerritforge.gerrit.globalrefdb.validation.ProjectsFilter;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.server.events.Event;
import com.google.gerrit.server.events.EventListener;
import com.google.gerrit.server.events.ProjectEvent;
import com.google.inject.Inject;
-import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
import com.googlesource.gerrit.plugins.multisite.forwarder.StreamEventForwarder;
import java.util.concurrent.Executor;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/GsonParser.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/CacheKeyJsonParser.java
similarity index 90%
rename from src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/GsonParser.java
rename to src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/CacheKeyJsonParser.java
index 0bbdada..80b2445 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/GsonParser.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/CacheKeyJsonParser.java
@@ -17,17 +17,18 @@
import com.google.common.base.MoreObjects;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.AccountGroup;
+import com.google.gerrit.entities.Project;
import com.google.gerrit.server.events.EventGson;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.inject.Inject;
import com.googlesource.gerrit.plugins.multisite.cache.Constants;
-public final class GsonParser {
+public final class CacheKeyJsonParser {
private final Gson gson;
@Inject
- public GsonParser(@EventGson Gson gson) {
+ public CacheKeyJsonParser(@EventGson Gson gson) {
this.gson = gson;
}
@@ -46,6 +47,9 @@
case Constants.GROUPS_MEMBERS:
key = AccountGroup.uuid(jsonElement(json).getAsJsonObject().get("uuid").getAsString());
break;
+ case Constants.PROJECTS:
+ key = Project.nameKey(jsonElement(json).getAsString());
+ break;
case Constants.PROJECT_LIST:
key = gson.fromJson(nullToEmpty(json).toString(), Object.class);
break;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/CacheEvictionEventRouter.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/CacheEvictionEventRouter.java
index 0fb0c0a..a77e168 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/CacheEvictionEventRouter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/CacheEvictionEventRouter.java
@@ -16,18 +16,18 @@
import com.google.inject.Inject;
import com.googlesource.gerrit.plugins.multisite.forwarder.CacheEntry;
+import com.googlesource.gerrit.plugins.multisite.forwarder.CacheKeyJsonParser;
import com.googlesource.gerrit.plugins.multisite.forwarder.CacheNotFoundException;
import com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedCacheEvictionHandler;
-import com.googlesource.gerrit.plugins.multisite.forwarder.GsonParser;
import com.googlesource.gerrit.plugins.multisite.forwarder.events.CacheEvictionEvent;
public class CacheEvictionEventRouter implements ForwardedEventRouter<CacheEvictionEvent> {
private final ForwardedCacheEvictionHandler cacheEvictionHanlder;
- private final GsonParser gsonParser;
+ private final CacheKeyJsonParser gsonParser;
@Inject
public CacheEvictionEventRouter(
- ForwardedCacheEvictionHandler cacheEvictionHanlder, GsonParser gsonParser) {
+ ForwardedCacheEvictionHandler cacheEvictionHanlder, CacheKeyJsonParser gsonParser) {
this.cacheEvictionHanlder = cacheEvictionHanlder;
this.gsonParser = gsonParser;
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeCheckerImpl.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeCheckerImpl.java
index 02972b0..08b26f7 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeCheckerImpl.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeCheckerImpl.java
@@ -15,7 +15,7 @@
package com.googlesource.gerrit.plugins.multisite.index;
import com.google.gerrit.entities.Change;
-import com.google.gerrit.entities.Comment;
+import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.server.CommentsUtil;
import com.google.gerrit.server.change.ChangeFinder;
@@ -148,7 +148,7 @@
Change change = notes.getChange();
Timestamp changeTs = change.getLastUpdatedOn();
try {
- for (Comment comment : commentsUtil.draftByChange(changeNotes.get())) {
+ for (HumanComment comment : commentsUtil.draftByChange(changeNotes.get())) {
Timestamp commentTs = comment.writtenOn;
changeTs = commentTs.after(changeTs) ? commentTs : changeTs;
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/index/IndexEventHandler.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/index/IndexEventHandler.java
index 5effd0e..eef3e4b 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/index/IndexEventHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/index/IndexEventHandler.java
@@ -14,6 +14,7 @@
package com.googlesource.gerrit.plugins.multisite.index;
+import com.gerritforge.gerrit.globalrefdb.validation.ProjectsFilter;
import com.google.common.base.Objects;
import com.google.gerrit.extensions.events.AccountIndexedListener;
import com.google.gerrit.extensions.events.ChangeIndexedListener;
@@ -21,7 +22,6 @@
import com.google.gerrit.extensions.events.ProjectIndexedListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.inject.Inject;
-import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
import com.googlesource.gerrit.plugins.multisite.forwarder.ForwarderTask;
import com.googlesource.gerrit.plugins.multisite.forwarder.IndexEventForwarder;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidator.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidator.java
deleted file mode 100644
index 0afe308..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidator.java
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation;
-
-import com.google.common.flogger.FluentLogger;
-import com.google.inject.Inject;
-import com.google.inject.assistedinject.Assisted;
-import com.googlesource.gerrit.plugins.multisite.LockWrapper;
-import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
-import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.OutOfSyncException;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement.EnforcePolicy;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import org.eclipse.jgit.lib.BatchRefUpdate;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.ObjectIdRef;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.RefDatabase;
-import org.eclipse.jgit.transport.ReceiveCommand;
-
-public class BatchRefUpdateValidator extends RefUpdateValidator {
- private static final FluentLogger logger = FluentLogger.forEnclosingClass();
-
- public static interface Factory {
- BatchRefUpdateValidator create(String projectName, RefDatabase refDb);
- }
-
- public interface BatchValidationWrapper {
- void apply(BatchRefUpdate batchRefUpdate, NoParameterVoidFunction arg) throws IOException;
- }
-
- @Inject
- public BatchRefUpdateValidator(
- SharedRefDatabaseWrapper sharedRefDb,
- ValidationMetrics validationMetrics,
- SharedRefEnforcement refEnforcement,
- LockWrapper.Factory lockWrapperFactory,
- ProjectsFilter projectsFilter,
- @Assisted String projectName,
- @Assisted RefDatabase refDb) {
- super(
- sharedRefDb,
- validationMetrics,
- refEnforcement,
- lockWrapperFactory,
- projectsFilter,
- projectName,
- refDb);
- }
-
- public void executeBatchUpdateWithValidation(
- BatchRefUpdate batchRefUpdate,
- NoParameterVoidFunction batchRefUpdateFunction,
- OneParameterVoidFunction<List<ReceiveCommand>> batchRefUpdateRollbackFunction)
- throws IOException {
- if (refEnforcement.getPolicy(projectName) == EnforcePolicy.IGNORED
- || !isGlobalProject(projectName)) {
- batchRefUpdateFunction.invoke();
- return;
- }
-
- try {
- doExecuteBatchUpdate(batchRefUpdate, batchRefUpdateFunction, batchRefUpdateRollbackFunction);
- } catch (IOException e) {
- logger.atWarning().withCause(e).log(
- "Failed to execute Batch Update on project %s", projectName);
- if (refEnforcement.getPolicy(projectName) == EnforcePolicy.REQUIRED) {
- throw e;
- }
- }
- }
-
- private void doExecuteBatchUpdate(
- BatchRefUpdate batchRefUpdate,
- NoParameterVoidFunction delegateUpdate,
- OneParameterVoidFunction<List<ReceiveCommand>> delegateUpdateRollback)
- throws IOException {
-
- List<ReceiveCommand> commands = batchRefUpdate.getCommands();
- if (commands.isEmpty()) {
- return;
- }
-
- List<RefPair> refsToUpdate = getRefsPairs(commands).collect(Collectors.toList());
- List<RefPair> refsFailures =
- refsToUpdate.stream().filter(RefPair::hasFailed).collect(Collectors.toList());
- if (!refsFailures.isEmpty()) {
- String allFailuresMessage =
- refsFailures.stream()
- .map(refPair -> String.format("Failed to fetch ref %s", refPair.compareRef.getName()))
- .collect(Collectors.joining(", "));
- Exception firstFailureException = refsFailures.get(0).exception;
-
- logger.atSevere().withCause(firstFailureException).log(allFailuresMessage);
- throw new IOException(allFailuresMessage, firstFailureException);
- }
-
- try (CloseableSet<AutoCloseable> locks = new CloseableSet<>()) {
- final List<RefPair> finalRefsToUpdate = compareAndGetLatestLocalRefs(refsToUpdate, locks);
- delegateUpdate.invoke();
- try {
- updateSharedRefDb(batchRefUpdate.getCommands().stream(), finalRefsToUpdate);
- } catch (Exception e) {
- List<ReceiveCommand> receiveCommands = batchRefUpdate.getCommands();
- logger.atWarning().withCause(e).log(
- String.format(
- "Batch ref-update failing because of failure during the global refdb update. Set all commands Result to LOCK_FAILURE [%d]",
- receiveCommands.size()));
- rollback(delegateUpdateRollback, finalRefsToUpdate, receiveCommands);
- }
- } catch (OutOfSyncException e) {
- List<ReceiveCommand> receiveCommands = batchRefUpdate.getCommands();
- logger.atWarning().withCause(e).log(
- String.format(
- "Batch ref-update failing because node is out of sync with the shared ref-db. Set all commands Result to LOCK_FAILURE [%d]",
- receiveCommands.size()));
- receiveCommands.forEach((command) -> command.setResult(ReceiveCommand.Result.LOCK_FAILURE));
- }
- }
-
- private void rollback(
- OneParameterVoidFunction<List<ReceiveCommand>> delegateUpdateRollback,
- List<RefPair> refsBeforeUpdate,
- List<ReceiveCommand> receiveCommands)
- throws IOException {
- List<ReceiveCommand> rollbackCommands =
- refsBeforeUpdate.stream()
- .map(
- refBeforeUpdate ->
- new ReceiveCommand(
- refBeforeUpdate.putValue,
- refBeforeUpdate.compareRef.getObjectId(),
- refBeforeUpdate.getName()))
- .collect(Collectors.toList());
- delegateUpdateRollback.invoke(rollbackCommands);
- receiveCommands.forEach(command -> command.setResult(ReceiveCommand.Result.LOCK_FAILURE));
- }
-
- private void updateSharedRefDb(Stream<ReceiveCommand> commandStream, List<RefPair> refsToUpdate)
- throws IOException {
- if (commandStream
- .filter(cmd -> cmd.getResult() != ReceiveCommand.Result.OK)
- .findFirst()
- .isPresent()) {
- return;
- }
-
- for (RefPair refPair : refsToUpdate) {
- updateSharedDbOrThrowExceptionFor(refPair);
- }
- }
-
- private Stream<RefPair> getRefsPairs(List<ReceiveCommand> receivedCommands) {
- return receivedCommands.stream().map(this::getRefPairForCommand);
- }
-
- private RefPair getRefPairForCommand(ReceiveCommand command) {
- try {
- switch (command.getType()) {
- case CREATE:
- return new RefPair(nullRef(command.getRefName()), getNewRef(command));
-
- case UPDATE:
- case UPDATE_NONFASTFORWARD:
- return new RefPair(getCurrentRef(command.getRefName()), getNewRef(command));
-
- case DELETE:
- return new RefPair(getCurrentRef(command.getRefName()), ObjectId.zeroId());
-
- default:
- return new RefPair(
- command.getRef(),
- new IllegalArgumentException("Unsupported command type " + command.getType()));
- }
- } catch (IOException e) {
- return new RefPair(command.getRef(), e);
- }
- }
-
- private ObjectId getNewRef(ReceiveCommand command) {
- return command.getNewId();
- }
-
- private List<RefPair> compareAndGetLatestLocalRefs(
- List<RefPair> refsToUpdate, CloseableSet<AutoCloseable> locks) throws IOException {
- List<RefPair> latestRefsToUpdate = new ArrayList<>();
- for (RefPair refPair : refsToUpdate) {
- latestRefsToUpdate.add(compareAndGetLatestLocalRef(refPair, locks));
- }
- return latestRefsToUpdate;
- }
-
- private static final Ref nullRef(String refName) {
- return new ObjectIdRef.Unpeeled(Ref.Storage.NETWORK, refName, ObjectId.zeroId());
- }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteBatchRefUpdate.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteBatchRefUpdate.java
deleted file mode 100644
index fd4f910..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteBatchRefUpdate.java
+++ /dev/null
@@ -1,196 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation;
-
-import com.google.inject.Inject;
-import com.google.inject.assistedinject.Assisted;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.List;
-import org.eclipse.jgit.lib.BatchRefUpdate;
-import org.eclipse.jgit.lib.PersonIdent;
-import org.eclipse.jgit.lib.ProgressMonitor;
-import org.eclipse.jgit.lib.RefDatabase;
-import org.eclipse.jgit.revwalk.RevWalk;
-import org.eclipse.jgit.transport.PushCertificate;
-import org.eclipse.jgit.transport.ReceiveCommand;
-import org.eclipse.jgit.util.time.ProposedTimestamp;
-
-public class MultiSiteBatchRefUpdate extends BatchRefUpdate {
-
- private final BatchRefUpdate batchRefUpdate;
- private final BatchRefUpdate batchRefUpdateRollback;
- private final String project;
- private final BatchRefUpdateValidator.Factory batchRefValidatorFactory;
- private final RefDatabase refDb;
-
- public static interface Factory {
- MultiSiteBatchRefUpdate create(String project, RefDatabase refDb);
- }
-
- @Inject
- public MultiSiteBatchRefUpdate(
- BatchRefUpdateValidator.Factory batchRefValidatorFactory,
- @Assisted String project,
- @Assisted RefDatabase refDb) {
- super(refDb);
- this.refDb = refDb;
- this.project = project;
- this.batchRefUpdate = refDb.newBatchUpdate();
- this.batchRefUpdateRollback = refDb.newBatchUpdate();
- this.batchRefValidatorFactory = batchRefValidatorFactory;
- }
-
- @Override
- public int hashCode() {
- return batchRefUpdate.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- return batchRefUpdate.equals(obj);
- }
-
- @Override
- public boolean isAllowNonFastForwards() {
- return batchRefUpdate.isAllowNonFastForwards();
- }
-
- @Override
- public BatchRefUpdate setAllowNonFastForwards(boolean allow) {
- batchRefUpdateRollback.setAllowNonFastForwards(allow);
- return batchRefUpdate.setAllowNonFastForwards(allow);
- }
-
- @Override
- public PersonIdent getRefLogIdent() {
- return batchRefUpdate.getRefLogIdent();
- }
-
- @Override
- public BatchRefUpdate setRefLogIdent(PersonIdent pi) {
- batchRefUpdateRollback.setRefLogIdent(pi);
- return batchRefUpdate.setRefLogIdent(pi);
- }
-
- @Override
- public String getRefLogMessage() {
- return batchRefUpdate.getRefLogMessage();
- }
-
- @Override
- public boolean isRefLogIncludingResult() {
- return batchRefUpdate.isRefLogIncludingResult();
- }
-
- @Override
- public BatchRefUpdate setRefLogMessage(String msg, boolean appendStatus) {
- batchRefUpdateRollback.setRefLogMessage(msg, appendStatus);
- return batchRefUpdate.setRefLogMessage(msg, appendStatus);
- }
-
- @Override
- public BatchRefUpdate disableRefLog() {
- return batchRefUpdate.disableRefLog();
- }
-
- @Override
- public BatchRefUpdate setForceRefLog(boolean force) {
- batchRefUpdateRollback.setForceRefLog(force);
- return batchRefUpdate.setForceRefLog(force);
- }
-
- @Override
- public boolean isRefLogDisabled() {
- return batchRefUpdate.isRefLogDisabled();
- }
-
- @Override
- public BatchRefUpdate setAtomic(boolean atomic) {
- return batchRefUpdate.setAtomic(atomic);
- }
-
- @Override
- public boolean isAtomic() {
- return batchRefUpdate.isAtomic();
- }
-
- @Override
- public void setPushCertificate(PushCertificate cert) {
- batchRefUpdate.setPushCertificate(cert);
- }
-
- @Override
- public List<ReceiveCommand> getCommands() {
- return batchRefUpdate.getCommands();
- }
-
- @Override
- public BatchRefUpdate addCommand(ReceiveCommand cmd) {
- return batchRefUpdate.addCommand(cmd);
- }
-
- @Override
- public BatchRefUpdate addCommand(ReceiveCommand... cmd) {
- return batchRefUpdate.addCommand(cmd);
- }
-
- @Override
- public BatchRefUpdate addCommand(Collection<ReceiveCommand> cmd) {
- return batchRefUpdate.addCommand(cmd);
- }
-
- @Override
- public List<String> getPushOptions() {
- return batchRefUpdate.getPushOptions();
- }
-
- @Override
- public List<ProposedTimestamp> getProposedTimestamps() {
- return batchRefUpdate.getProposedTimestamps();
- }
-
- @Override
- public BatchRefUpdate addProposedTimestamp(ProposedTimestamp ts) {
- return batchRefUpdate.addProposedTimestamp(ts);
- }
-
- @Override
- public void execute(RevWalk walk, ProgressMonitor monitor, List<String> options)
- throws IOException {
- batchRefValidatorFactory
- .create(project, refDb)
- .executeBatchUpdateWithValidation(
- batchRefUpdate,
- () -> batchRefUpdate.execute(walk, monitor, options),
- (commands) ->
- batchRefUpdateRollback.addCommand(commands).execute(walk, monitor, options));
- }
-
- @Override
- public void execute(RevWalk walk, ProgressMonitor monitor) throws IOException {
- batchRefValidatorFactory
- .create(project, refDb)
- .executeBatchUpdateWithValidation(
- batchRefUpdate,
- () -> batchRefUpdate.execute(walk, monitor),
- (commands) -> batchRefUpdateRollback.addCommand(commands).execute(walk, monitor));
- }
-
- @Override
- public String toString() {
- return batchRefUpdate.toString();
- }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteGitRepositoryManager.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteGitRepositoryManager.java
deleted file mode 100644
index 6ece734..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteGitRepositoryManager.java
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation;
-
-import com.google.gerrit.entities.Project;
-import com.google.gerrit.server.git.GitRepositoryManager;
-import com.google.gerrit.server.git.LocalDiskRepositoryManager;
-import com.google.gerrit.server.git.RepositoryCaseMismatchException;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import java.io.IOException;
-import java.util.SortedSet;
-import org.eclipse.jgit.errors.RepositoryNotFoundException;
-import org.eclipse.jgit.lib.Repository;
-
-@Singleton
-public class MultiSiteGitRepositoryManager implements GitRepositoryManager {
- private final GitRepositoryManager gitRepositoryManager;
- private final MultiSiteRepository.Factory multiSiteRepoFactory;
-
- @Inject
- public MultiSiteGitRepositoryManager(
- MultiSiteRepository.Factory multiSiteRepoFactory,
- LocalDiskRepositoryManager localDiskRepositoryManager) {
- this.multiSiteRepoFactory = multiSiteRepoFactory;
- this.gitRepositoryManager = localDiskRepositoryManager;
- }
-
- @Override
- public Repository openRepository(Project.NameKey name)
- throws RepositoryNotFoundException, IOException {
- return wrap(name, gitRepositoryManager.openRepository(name));
- }
-
- @Override
- public Repository createRepository(Project.NameKey name)
- throws RepositoryCaseMismatchException, RepositoryNotFoundException, IOException {
- return wrap(name, gitRepositoryManager.createRepository(name));
- }
-
- @Override
- public Boolean canPerformGC() {
- return gitRepositoryManager.canPerformGC();
- }
-
- @Override
- public SortedSet<Project.NameKey> list() {
- return gitRepositoryManager.list();
- }
-
- private Repository wrap(Project.NameKey projectName, Repository projectRepo) {
- return multiSiteRepoFactory.create(projectName.get(), projectRepo);
- }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefDatabase.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefDatabase.java
deleted file mode 100644
index e1d1c65..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefDatabase.java
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation;
-
-import com.google.inject.Inject;
-import com.google.inject.assistedinject.Assisted;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import org.eclipse.jgit.lib.BatchRefUpdate;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.RefDatabase;
-import org.eclipse.jgit.lib.RefRename;
-import org.eclipse.jgit.lib.RefUpdate;
-
-public class MultiSiteRefDatabase extends RefDatabase {
- private final MultiSiteRefUpdate.Factory refUpdateFactory;
- private final MultiSiteBatchRefUpdate.Factory batchRefUpdateFactory;
- private final String projectName;
- private final RefDatabase refDatabase;
-
- public interface Factory {
- public MultiSiteRefDatabase create(String projectName, RefDatabase refDatabase);
- }
-
- @Inject
- public MultiSiteRefDatabase(
- MultiSiteRefUpdate.Factory refUpdateFactory,
- MultiSiteBatchRefUpdate.Factory batchRefUpdateFactory,
- @Assisted String projectName,
- @Assisted RefDatabase refDatabase) {
- this.refUpdateFactory = refUpdateFactory;
- this.batchRefUpdateFactory = batchRefUpdateFactory;
- this.projectName = projectName;
- this.refDatabase = refDatabase;
- }
-
- @Override
- public int hashCode() {
- return refDatabase.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- return refDatabase.equals(obj);
- }
-
- @Override
- public void create() throws IOException {
- refDatabase.create();
- }
-
- @Override
- public void close() {
- refDatabase.close();
- }
-
- @Override
- public boolean isNameConflicting(String name) throws IOException {
- return refDatabase.isNameConflicting(name);
- }
-
- @Override
- public Collection<String> getConflictingNames(String name) throws IOException {
- return refDatabase.getConflictingNames(name);
- }
-
- @Override
- public RefUpdate newUpdate(String name, boolean detach) throws IOException {
- return wrapRefUpdate(refDatabase.newUpdate(name, detach));
- }
-
- @Override
- public RefRename newRename(String fromName, String toName) throws IOException {
- return refDatabase.newRename(fromName, toName);
- }
-
- @Override
- public BatchRefUpdate newBatchUpdate() {
- return batchRefUpdateFactory.create(projectName, refDatabase);
- }
-
- @Override
- public boolean performsAtomicTransactions() {
- return refDatabase.performsAtomicTransactions();
- }
-
- @Override
- public String toString() {
- return refDatabase.toString();
- }
-
- @Override
- public Ref exactRef(String name) throws IOException {
- return refDatabase.exactRef(name);
- }
-
- @Override
- public Map<String, Ref> exactRef(String... refs) throws IOException {
- return refDatabase.exactRef(refs);
- }
-
- @Override
- public Ref firstExactRef(String... refs) throws IOException {
- return refDatabase.firstExactRef(refs);
- }
-
- @Override
- public List<Ref> getRefs() throws IOException {
- return refDatabase.getRefs();
- }
-
- @SuppressWarnings("deprecation")
- @Override
- public Map<String, Ref> getRefs(String prefix) throws IOException {
- return refDatabase.getRefs(prefix);
- }
-
- @Override
- public List<Ref> getRefsByPrefix(String prefix) throws IOException {
- return refDatabase.getRefsByPrefix(prefix);
- }
-
- @Override
- public boolean hasRefs() throws IOException {
- return refDatabase.hasRefs();
- }
-
- @Override
- public List<Ref> getAdditionalRefs() throws IOException {
- return refDatabase.getAdditionalRefs();
- }
-
- @Override
- public Ref peel(Ref ref) throws IOException {
- return refDatabase.peel(ref);
- }
-
- @Override
- public void refresh() {
- refDatabase.refresh();
- }
-
- RefUpdate wrapRefUpdate(RefUpdate refUpdate) {
- return refUpdateFactory.create(projectName, refUpdate, refDatabase);
- }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefUpdate.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefUpdate.java
deleted file mode 100644
index 20e12fe..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefUpdate.java
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation;
-
-import com.google.inject.Inject;
-import com.google.inject.assistedinject.Assisted;
-import com.googlesource.gerrit.plugins.multisite.validation.RefUpdateValidator.NoParameterFunction;
-import java.io.IOException;
-import org.eclipse.jgit.lib.AnyObjectId;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.PersonIdent;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.RefDatabase;
-import org.eclipse.jgit.lib.RefUpdate;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevWalk;
-import org.eclipse.jgit.transport.PushCertificate;
-
-public class MultiSiteRefUpdate extends RefUpdate {
-
- protected final RefUpdate refUpdateBase;
- private final String projectName;
- private final RefUpdateValidator.Factory refValidatorFactory;
- private final RefUpdateValidator refUpdateValidator;
-
- public interface Factory {
- MultiSiteRefUpdate create(String projectName, RefUpdate refUpdate, RefDatabase refDb);
- }
-
- @Inject
- public MultiSiteRefUpdate(
- RefUpdateValidator.Factory refValidatorFactory,
- @Assisted String projectName,
- @Assisted RefUpdate refUpdate,
- @Assisted RefDatabase refDb) {
- super(refUpdate.getRef());
- refUpdateBase = refUpdate;
- this.projectName = projectName;
- this.refValidatorFactory = refValidatorFactory;
- refUpdateValidator = this.refValidatorFactory.create(this.projectName, refDb);
- }
-
- @Override
- protected RefDatabase getRefDatabase() {
- return notImplementedException();
- }
-
- private <T> T notImplementedException() {
- throw new IllegalStateException("This method should have never been invoked");
- }
-
- @Override
- protected Repository getRepository() {
- return notImplementedException();
- }
-
- @Override
- protected boolean tryLock(boolean deref) throws IOException {
- return notImplementedException();
- }
-
- @Override
- protected void unlock() {
- notImplementedException();
- }
-
- @Override
- protected Result doUpdate(Result result) throws IOException {
- return notImplementedException();
- }
-
- @Override
- protected Result doDelete(Result result) throws IOException {
- return notImplementedException();
- }
-
- @Override
- protected Result doLink(String target) throws IOException {
- return notImplementedException();
- }
-
- @Override
- public Result update() throws IOException {
- return refUpdateValidator.executeRefUpdate(
- refUpdateBase,
- refUpdateBase::update,
- objectId -> rollback(objectId, refUpdateBase::update));
- }
-
- @Override
- public Result update(RevWalk rev) throws IOException {
- return refUpdateValidator.executeRefUpdate(
- refUpdateBase,
- () -> refUpdateBase.update(rev),
- objectId -> rollback(objectId, () -> refUpdateBase.update(rev)));
- }
-
- @Override
- public Result delete() throws IOException {
- return refUpdateValidator.executeRefUpdate(
- refUpdateBase,
- refUpdateBase::delete,
- objectId -> rollback(objectId, refUpdateBase::update));
- }
-
- @Override
- public Result delete(RevWalk walk) throws IOException {
- return refUpdateValidator.executeRefUpdate(
- refUpdateBase,
- () -> refUpdateBase.delete(walk),
- objectId -> rollback(objectId, () -> refUpdateBase.update(walk)));
- }
-
- @Override
- public int hashCode() {
- return refUpdateBase.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- return refUpdateBase.equals(obj);
- }
-
- @Override
- public String toString() {
- return refUpdateBase.toString();
- }
-
- @Override
- public String getName() {
- return refUpdateBase.getName();
- }
-
- @Override
- public Ref getRef() {
- return refUpdateBase.getRef();
- }
-
- @Override
- public ObjectId getNewObjectId() {
- return refUpdateBase.getNewObjectId();
- }
-
- @Override
- public void setDetachingSymbolicRef() {
- refUpdateBase.setDetachingSymbolicRef();
- }
-
- @Override
- public boolean isDetachingSymbolicRef() {
- return refUpdateBase.isDetachingSymbolicRef();
- }
-
- @Override
- public void setNewObjectId(AnyObjectId id) {
- refUpdateBase.setNewObjectId(id);
- }
-
- @Override
- public ObjectId getExpectedOldObjectId() {
- return refUpdateBase.getExpectedOldObjectId();
- }
-
- @Override
- public void setExpectedOldObjectId(AnyObjectId id) {
- refUpdateBase.setExpectedOldObjectId(id);
- }
-
- @Override
- public boolean isForceUpdate() {
- return refUpdateBase.isForceUpdate();
- }
-
- @Override
- public void setForceUpdate(boolean b) {
- refUpdateBase.setForceUpdate(b);
- }
-
- @Override
- public PersonIdent getRefLogIdent() {
- return refUpdateBase.getRefLogIdent();
- }
-
- @Override
- public void setRefLogIdent(PersonIdent pi) {
- refUpdateBase.setRefLogIdent(pi);
- }
-
- @Override
- public String getRefLogMessage() {
- return refUpdateBase.getRefLogMessage();
- }
-
- @Override
- public void setRefLogMessage(String msg, boolean appendStatus) {
- refUpdateBase.setRefLogMessage(msg, appendStatus);
- }
-
- @Override
- public void disableRefLog() {
- refUpdateBase.disableRefLog();
- }
-
- @Override
- public void setForceRefLog(boolean force) {
- refUpdateBase.setForceRefLog(force);
- }
-
- @Override
- public ObjectId getOldObjectId() {
- return refUpdateBase.getOldObjectId();
- }
-
- @Override
- public void setPushCertificate(PushCertificate cert) {
- refUpdateBase.setPushCertificate(cert);
- }
-
- @Override
- public Result getResult() {
- return refUpdateBase.getResult();
- }
-
- @Override
- public Result forceUpdate() throws IOException {
- return refUpdateValidator.executeRefUpdate(
- refUpdateBase,
- refUpdateBase::forceUpdate,
- objectId -> rollback(objectId, refUpdateBase::forceUpdate));
- }
-
- @Override
- public Result link(String target) throws IOException {
- return refUpdateBase.link(target);
- }
-
- @Override
- public void setCheckConflicting(boolean check) {
- refUpdateBase.setCheckConflicting(check);
- }
-
- private Result rollback(ObjectId objectId, NoParameterFunction<Result> updateFunction)
- throws IOException {
- refUpdateBase.setExpectedOldObjectId(refUpdateBase.getNewObjectId());
- refUpdateBase.setNewObjectId(objectId);
- return updateFunction.invoke();
- }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRepository.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRepository.java
deleted file mode 100644
index fa3de64..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRepository.java
+++ /dev/null
@@ -1,407 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation;
-
-import com.google.inject.Inject;
-import com.google.inject.assistedinject.Assisted;
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.eclipse.jgit.attributes.AttributesNodeProvider;
-import org.eclipse.jgit.dircache.DirCache;
-import org.eclipse.jgit.errors.AmbiguousObjectException;
-import org.eclipse.jgit.errors.CorruptObjectException;
-import org.eclipse.jgit.errors.IncorrectObjectTypeException;
-import org.eclipse.jgit.errors.MissingObjectException;
-import org.eclipse.jgit.errors.NoWorkTreeException;
-import org.eclipse.jgit.errors.RevisionSyntaxException;
-import org.eclipse.jgit.events.ListenerList;
-import org.eclipse.jgit.events.RepositoryEvent;
-import org.eclipse.jgit.lib.AnyObjectId;
-import org.eclipse.jgit.lib.BaseRepositoryBuilder;
-import org.eclipse.jgit.lib.ObjectDatabase;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.ObjectInserter;
-import org.eclipse.jgit.lib.ObjectLoader;
-import org.eclipse.jgit.lib.ObjectReader;
-import org.eclipse.jgit.lib.ProgressMonitor;
-import org.eclipse.jgit.lib.RebaseTodoLine;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.RefDatabase;
-import org.eclipse.jgit.lib.RefRename;
-import org.eclipse.jgit.lib.RefUpdate;
-import org.eclipse.jgit.lib.ReflogReader;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.lib.RepositoryState;
-import org.eclipse.jgit.lib.StoredConfig;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.util.FS;
-
-public class MultiSiteRepository extends Repository {
-
- private final Repository repository;
- private final RefDatabase refDatabase;
- private final MultiSiteRefDatabase multiSiteRefDatabase;
-
- public interface Factory {
- public MultiSiteRepository create(String projectName, Repository repository);
- }
-
- @Inject
- public MultiSiteRepository(
- MultiSiteRefDatabase.Factory multiSiteRefDbFactory,
- @Assisted String projectName,
- @Assisted Repository repository) {
- super(new BaseRepositoryBuilder());
- this.repository = repository;
- this.refDatabase = repository.getRefDatabase();
- this.multiSiteRefDatabase = multiSiteRefDbFactory.create(projectName, refDatabase);
- }
-
- @Override
- public void create(boolean b) throws IOException {}
-
- @Override
- public ObjectDatabase getObjectDatabase() {
- return repository.getObjectDatabase();
- }
-
- @Override
- public RefDatabase getRefDatabase() {
- return multiSiteRefDatabase;
- }
-
- @Override
- public StoredConfig getConfig() {
- return repository.getConfig();
- }
-
- @Override
- public AttributesNodeProvider createAttributesNodeProvider() {
- return repository.createAttributesNodeProvider();
- }
-
- @Override
- public void scanForRepoChanges() throws IOException {
- repository.scanForRepoChanges();
- }
-
- @Override
- public void notifyIndexChanged(boolean b) {
- repository.notifyIndexChanged(b);
- }
-
- @Override
- public ReflogReader getReflogReader(String s) throws IOException {
- return repository.getReflogReader(s);
- }
-
- @Override
- public int hashCode() {
- return repository.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- return repository.equals(obj);
- }
-
- @Override
- public ListenerList getListenerList() {
- return repository.getListenerList();
- }
-
- @Override
- public void fireEvent(RepositoryEvent<?> event) {
- repository.fireEvent(event);
- }
-
- @Override
- public void create() throws IOException {
- repository.create();
- }
-
- @Override
- public File getDirectory() {
- return repository.getDirectory();
- }
-
- @Override
- public ObjectInserter newObjectInserter() {
- return repository.newObjectInserter();
- }
-
- @Override
- public ObjectReader newObjectReader() {
- return repository.newObjectReader();
- }
-
- @Override
- public FS getFS() {
- return repository.getFS();
- }
-
- @SuppressWarnings("deprecation")
- @Override
- public boolean hasObject(AnyObjectId objectId) {
- return repository.hasObject(objectId);
- }
-
- @Override
- public ObjectLoader open(AnyObjectId objectId) throws MissingObjectException, IOException {
- return repository.open(objectId);
- }
-
- @Override
- public ObjectLoader open(AnyObjectId objectId, int typeHint)
- throws MissingObjectException, IncorrectObjectTypeException, IOException {
- return repository.open(objectId, typeHint);
- }
-
- @Override
- public RefUpdate updateRef(String ref) throws IOException {
- return multiSiteRefDatabase.wrapRefUpdate(repository.updateRef(ref));
- }
-
- @Override
- public RefUpdate updateRef(String ref, boolean detach) throws IOException {
- return multiSiteRefDatabase.wrapRefUpdate(repository.updateRef(ref, detach));
- }
-
- @Override
- public RefRename renameRef(String fromRef, String toRef) throws IOException {
- return repository.renameRef(fromRef, toRef);
- }
-
- @Override
- public ObjectId resolve(String revstr)
- throws AmbiguousObjectException, IncorrectObjectTypeException, RevisionSyntaxException,
- IOException {
- return repository.resolve(revstr);
- }
-
- @Override
- public String simplify(String revstr) throws AmbiguousObjectException, IOException {
- return repository.simplify(revstr);
- }
-
- @Override
- public void incrementOpen() {
- repository.incrementOpen();
- }
-
- @Override
- public void close() {
- repository.close();
- }
-
- @Override
- public String toString() {
- return repository.toString();
- }
-
- @Override
- public String getFullBranch() throws IOException {
- return repository.getFullBranch();
- }
-
- @Override
- public String getBranch() throws IOException {
- return repository.getBranch();
- }
-
- @Override
- public Set<ObjectId> getAdditionalHaves() {
- return repository.getAdditionalHaves();
- }
-
- @SuppressWarnings("deprecation")
- @Override
- public Map<String, Ref> getAllRefs() {
- return repository.getAllRefs();
- }
-
- @SuppressWarnings("deprecation")
- @Override
- public Map<String, Ref> getTags() {
- return repository.getTags();
- }
-
- @SuppressWarnings("deprecation")
- @Override
- public Ref peel(Ref ref) {
- return repository.peel(ref);
- }
-
- @Override
- public Map<AnyObjectId, Set<Ref>> getAllRefsByPeeledObjectId() {
- return repository.getAllRefsByPeeledObjectId();
- }
-
- @Override
- public File getIndexFile() throws NoWorkTreeException {
- return repository.getIndexFile();
- }
-
- @Override
- public RevCommit parseCommit(AnyObjectId id)
- throws IncorrectObjectTypeException, IOException, MissingObjectException {
- return repository.parseCommit(id);
- }
-
- @Override
- public DirCache readDirCache() throws NoWorkTreeException, CorruptObjectException, IOException {
- return repository.readDirCache();
- }
-
- @Override
- public DirCache lockDirCache() throws NoWorkTreeException, CorruptObjectException, IOException {
- return repository.lockDirCache();
- }
-
- @Override
- public RepositoryState getRepositoryState() {
- return repository.getRepositoryState();
- }
-
- @Override
- public boolean isBare() {
- return repository.isBare();
- }
-
- @Override
- public File getWorkTree() throws NoWorkTreeException {
- return repository.getWorkTree();
- }
-
- @Override
- public String shortenRemoteBranchName(String refName) {
- return repository.shortenRemoteBranchName(refName);
- }
-
- @Override
- public String getRemoteName(String refName) {
- return repository.getRemoteName(refName);
- }
-
- @Override
- public String getGitwebDescription() throws IOException {
- return repository.getGitwebDescription();
- }
-
- @Override
- public void setGitwebDescription(String description) throws IOException {
- repository.setGitwebDescription(description);
- }
-
- @Override
- public String readMergeCommitMsg() throws IOException, NoWorkTreeException {
- return repository.readMergeCommitMsg();
- }
-
- @Override
- public void writeMergeCommitMsg(String msg) throws IOException {
- repository.writeMergeCommitMsg(msg);
- }
-
- @Override
- public String readCommitEditMsg() throws IOException, NoWorkTreeException {
- return repository.readCommitEditMsg();
- }
-
- @Override
- public void writeCommitEditMsg(String msg) throws IOException {
- repository.writeCommitEditMsg(msg);
- }
-
- @Override
- public List<ObjectId> readMergeHeads() throws IOException, NoWorkTreeException {
- return repository.readMergeHeads();
- }
-
- @Override
- public void writeMergeHeads(List<? extends ObjectId> heads) throws IOException {
- repository.writeMergeHeads(heads);
- }
-
- @Override
- public ObjectId readCherryPickHead() throws IOException, NoWorkTreeException {
- return repository.readCherryPickHead();
- }
-
- @Override
- public ObjectId readRevertHead() throws IOException, NoWorkTreeException {
- return repository.readRevertHead();
- }
-
- @Override
- public void writeCherryPickHead(ObjectId head) throws IOException {
- repository.writeCherryPickHead(head);
- }
-
- @Override
- public void writeRevertHead(ObjectId head) throws IOException {
- repository.writeRevertHead(head);
- }
-
- @Override
- public void writeOrigHead(ObjectId head) throws IOException {
- repository.writeOrigHead(head);
- }
-
- @Override
- public ObjectId readOrigHead() throws IOException, NoWorkTreeException {
- return repository.readOrigHead();
- }
-
- @Override
- public String readSquashCommitMsg() throws IOException {
- return repository.readSquashCommitMsg();
- }
-
- @Override
- public void writeSquashCommitMsg(String msg) throws IOException {
- repository.writeSquashCommitMsg(msg);
- }
-
- @Override
- public List<RebaseTodoLine> readRebaseTodo(String path, boolean includeComments)
- throws IOException {
- return repository.readRebaseTodo(path, includeComments);
- }
-
- @Override
- public void writeRebaseTodoFile(String path, List<RebaseTodoLine> steps, boolean append)
- throws IOException {
- repository.writeRebaseTodoFile(path, steps, append);
- }
-
- @Override
- public Set<String> getRemoteNames() {
- return repository.getRemoteNames();
- }
-
- @Override
- public void autoGC(ProgressMonitor monitor) {
- repository.autoGC(monitor);
- }
-
- @Override
- public String getIdentifier() {
- return repository.getIdentifier();
- }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationPushFilter.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationPushFilter.java
index f831671..98f4897 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationPushFilter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationPushFilter.java
@@ -15,13 +15,13 @@
package com.googlesource.gerrit.plugins.multisite.validation;
import com.gerritforge.gerrit.globalrefdb.GlobalRefDbLockException;
+import com.gerritforge.gerrit.globalrefdb.validation.SharedRefDatabaseWrapper;
import com.google.common.base.Preconditions;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.entities.Project;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.inject.Inject;
import com.google.inject.Singleton;
-import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
import com.googlesource.gerrit.plugins.replication.ReplicationPushFilter;
import java.io.IOException;
import java.util.Collections;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectDeletedSharedDbCleanup.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectDeletedSharedDbCleanup.java
deleted file mode 100644
index 329c1c3..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectDeletedSharedDbCleanup.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation;
-
-import com.gerritforge.gerrit.globalrefdb.GlobalRefDbSystemError;
-import com.google.common.flogger.FluentLogger;
-import com.google.gerrit.entities.Project;
-import com.google.gerrit.extensions.events.ProjectDeletedListener;
-import com.google.inject.Inject;
-import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
-
-public class ProjectDeletedSharedDbCleanup implements ProjectDeletedListener {
- private static final FluentLogger logger = FluentLogger.forEnclosingClass();
-
- private final SharedRefDatabaseWrapper sharedDb;
-
- private final ValidationMetrics validationMetrics;
-
- @Inject
- public ProjectDeletedSharedDbCleanup(
- SharedRefDatabaseWrapper sharedDb, ValidationMetrics validationMetrics) {
- this.sharedDb = sharedDb;
- this.validationMetrics = validationMetrics;
- }
-
- @Override
- public void onProjectDeleted(Event event) {
- String projectName = event.getProjectName();
- logger.atInfo().log(
- "Deleting project '%s'. Will perform a cleanup in Shared-Ref database.", projectName);
-
- try {
- sharedDb.remove(Project.nameKey(projectName));
- } catch (GlobalRefDbSystemError e) {
- validationMetrics.incrementSplitBrain();
- logger.atSevere().withCause(e).log(
- "Project '%s' deleted from GIT but it was not able to cleanup"
- + " from Shared-Ref database",
- projectName);
- }
- }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdate.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdate.java
index c8ddb43..28eddbb 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdate.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdate.java
@@ -18,6 +18,8 @@
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
import com.gerritforge.gerrit.globalrefdb.GlobalRefDbSystemError;
+import com.gerritforge.gerrit.globalrefdb.validation.ProjectsFilter;
+import com.gerritforge.gerrit.globalrefdb.validation.SharedRefDatabaseWrapper;
import com.google.common.collect.ImmutableSet;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.entities.Project;
@@ -31,8 +33,6 @@
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.googlesource.gerrit.plugins.multisite.ProjectVersionLogger;
-import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
-import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
import java.io.IOException;
import java.util.Optional;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/RefPair.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/RefPair.java
deleted file mode 100644
index 77ae4f1..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/RefPair.java
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation;
-
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Ref;
-
-public class RefPair {
- public final Ref compareRef;
- public final ObjectId putValue;
- public final Exception exception;
-
- RefPair(Ref oldRef, ObjectId newRefValue) {
- if (oldRef == null) {
- throw new IllegalArgumentException("Required not-null ref in RefPair");
- }
- this.compareRef = oldRef;
- this.putValue = newRefValue;
- this.exception = null;
- }
-
- RefPair(Ref newRef, Exception e) {
- this.compareRef = newRef;
- this.exception = e;
- this.putValue = ObjectId.zeroId();
- }
-
- public String getName() {
- return compareRef.getName();
- }
-
- public boolean hasFailed() {
- return exception != null;
- }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidator.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidator.java
deleted file mode 100644
index c110f0f..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidator.java
+++ /dev/null
@@ -1,309 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation;
-
-import com.gerritforge.gerrit.globalrefdb.GlobalRefDbSystemError;
-import com.google.common.base.MoreObjects;
-import com.google.common.flogger.FluentLogger;
-import com.google.gerrit.entities.Project;
-import com.google.inject.Inject;
-import com.google.inject.assistedinject.Assisted;
-import com.googlesource.gerrit.plugins.multisite.LockWrapper;
-import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
-import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.OutOfSyncException;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedDbSplitBrainException;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedLockException;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement.EnforcePolicy;
-import java.io.IOException;
-import java.util.HashMap;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.ObjectIdRef;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.RefDatabase;
-import org.eclipse.jgit.lib.RefUpdate;
-import org.eclipse.jgit.lib.RefUpdate.Result;
-
-public class RefUpdateValidator {
- private static final FluentLogger logger = FluentLogger.forEnclosingClass();
-
- protected final SharedRefDatabaseWrapper sharedRefDb;
- protected final ValidationMetrics validationMetrics;
-
- protected final String projectName;
- private final LockWrapper.Factory lockWrapperFactory;
- protected final RefDatabase refDb;
- protected final SharedRefEnforcement refEnforcement;
- protected final ProjectsFilter projectsFilter;
-
- public static interface Factory {
- RefUpdateValidator create(String projectName, RefDatabase refDb);
- }
-
- public interface ExceptionThrowingSupplier<T, E extends Exception> {
- T create() throws E;
- }
-
- public interface RefValidationWrapper {
- RefUpdate.Result apply(NoParameterFunction<RefUpdate.Result> arg, RefUpdate refUpdate)
- throws IOException;
- }
-
- public interface NoParameterFunction<T> {
- T invoke() throws IOException;
- }
-
- public interface NoParameterVoidFunction {
- void invoke() throws IOException;
- }
-
- public interface OneParameterFunction<F, T> {
- T invoke(F f) throws IOException;
- }
-
- public interface OneParameterVoidFunction<T> {
- void invoke(T f) throws IOException;
- }
-
- @Inject
- public RefUpdateValidator(
- SharedRefDatabaseWrapper sharedRefDb,
- ValidationMetrics validationMetrics,
- SharedRefEnforcement refEnforcement,
- LockWrapper.Factory lockWrapperFactory,
- ProjectsFilter projectsFilter,
- @Assisted String projectName,
- @Assisted RefDatabase refDb) {
- this.sharedRefDb = sharedRefDb;
- this.validationMetrics = validationMetrics;
- this.lockWrapperFactory = lockWrapperFactory;
- this.refDb = refDb;
- this.projectName = projectName;
- this.refEnforcement = refEnforcement;
- this.projectsFilter = projectsFilter;
- }
-
- public RefUpdate.Result executeRefUpdate(
- RefUpdate refUpdate,
- NoParameterFunction<RefUpdate.Result> refUpdateFunction,
- OneParameterFunction<ObjectId, Result> rollbackFunction)
- throws IOException {
- if (isProjectVersionUpdate(refUpdate.getName())
- || !isGlobalProject(projectName)
- || refEnforcement.getPolicy(projectName) == EnforcePolicy.IGNORED) {
- return refUpdateFunction.invoke();
- }
-
- return doExecuteRefUpdate(refUpdate, refUpdateFunction, rollbackFunction);
- }
-
- private Boolean isProjectVersionUpdate(String refName) {
- Boolean isProjectVersionUpdate =
- refName.equals(ProjectVersionRefUpdate.MULTI_SITE_VERSIONING_REF);
- logger.atFine().log("Is project version update? " + isProjectVersionUpdate);
- return isProjectVersionUpdate;
- }
-
- private <T extends Throwable> void softFailBasedOnEnforcement(T e, EnforcePolicy policy)
- throws T {
- logger.atWarning().withCause(e).log(
- String.format(
- "Failure while running with policy enforcement %s. Error message: %s",
- policy, e.getMessage()));
- if (policy == EnforcePolicy.REQUIRED) {
- throw e;
- }
- }
-
- protected Boolean isGlobalProject(String projectName) {
- Boolean isGlobalProject = projectsFilter.matches(projectName);
- logger.atFine().log("Is global project? " + isGlobalProject);
- return isGlobalProject;
- }
-
- protected RefUpdate.Result doExecuteRefUpdate(
- RefUpdate refUpdate,
- NoParameterFunction<Result> refUpdateFunction,
- OneParameterFunction<ObjectId, Result> rollbackFunction)
- throws IOException {
- try (CloseableSet<AutoCloseable> locks = new CloseableSet<>()) {
- RefPair refPairForUpdate = newRefPairFrom(refUpdate);
- compareAndGetLatestLocalRef(refPairForUpdate, locks);
- RefUpdate.Result result = refUpdateFunction.invoke();
- try {
- if (isSuccessful(result)) {
- updateSharedDbOrThrowExceptionFor(refPairForUpdate);
- }
- } catch (Exception e) {
- result = rollbackFunction.invoke(refPairForUpdate.compareRef.getObjectId());
- if (isSuccessful(result)) {
- result = RefUpdate.Result.LOCK_FAILURE;
- }
- logger.atSevere().withCause(e).log(
- String.format(
- "Failed to update global refdb, the local refdb has been rolled back: %s",
- e.getMessage()));
- }
- return result;
- } catch (OutOfSyncException e) {
- logger.atWarning().withCause(e).log(
- String.format("Local node is out of sync with ref-db: %s", e.getMessage()));
-
- return RefUpdate.Result.LOCK_FAILURE;
- }
- }
-
- protected void updateSharedDbOrThrowExceptionFor(RefPair refPair) throws IOException {
- // We are not checking refs that should be ignored
- final EnforcePolicy refEnforcementPolicy =
- refEnforcement.getPolicy(projectName, refPair.getName());
- if (refEnforcementPolicy == EnforcePolicy.IGNORED) return;
-
- String errorMessage =
- String.format(
- "Not able to persist the data in Zookeeper for project '%s' and ref '%s',"
- + "the cluster is now in Split Brain since the commit has been "
- + "persisted locally but not in SharedRef the value %s",
- projectName, refPair.getName(), refPair.putValue);
- boolean succeeded;
- try {
- succeeded =
- sharedRefDb.compareAndPut(
- Project.nameKey(projectName), refPair.compareRef, refPair.putValue);
- } catch (GlobalRefDbSystemError e) {
- logger.atWarning().withCause(e).log(
- "Not able to persist the data in Zookeeper for project '{}' and ref '{}', message: {}",
- projectName,
- refPair.getName(),
- e.getMessage());
- throw e;
- }
-
- if (!succeeded) {
- throw new SharedDbSplitBrainException(errorMessage);
- }
- }
-
- protected RefPair compareAndGetLatestLocalRef(RefPair refPair, CloseableSet<AutoCloseable> locks)
- throws SharedLockException, OutOfSyncException, IOException {
- String refName = refPair.getName();
- EnforcePolicy refEnforcementPolicy = refEnforcement.getPolicy(projectName, refName);
- if (refEnforcementPolicy == EnforcePolicy.IGNORED) {
- return refPair;
- }
-
- locks.addResourceIfNotExist(
- String.format("%s-%s", projectName, refName),
- () ->
- lockWrapperFactory.create(
- projectName, refName, sharedRefDb.lockRef(Project.nameKey(projectName), refName)));
-
- RefPair latestRefPair = getLatestLocalRef(refPair);
- if (sharedRefDb.isUpToDate(Project.nameKey(projectName), latestRefPair.compareRef)) {
- return latestRefPair;
- }
-
- if (isNullRef(latestRefPair.compareRef)
- || sharedRefDb.exists(Project.nameKey(projectName), refName)) {
- validationMetrics.incrementSplitBrainPrevention();
-
- softFailBasedOnEnforcement(
- new OutOfSyncException(projectName, latestRefPair.compareRef), refEnforcementPolicy);
- }
-
- return latestRefPair;
- }
-
- private boolean isNullRef(Ref ref) {
- return ref.getObjectId().equals(ObjectId.zeroId());
- }
-
- private RefPair getLatestLocalRef(RefPair refPair) throws IOException {
- Ref latestRef = refDb.exactRef(refPair.getName());
- return new RefPair(
- latestRef == null ? nullRef(refPair.getName()) : latestRef, refPair.putValue);
- }
-
- private Ref nullRef(String name) {
- return new ObjectIdRef.Unpeeled(Ref.Storage.NETWORK, name, ObjectId.zeroId());
- }
-
- protected boolean isSuccessful(RefUpdate.Result result) {
- switch (result) {
- case NEW:
- case FORCED:
- case FAST_FORWARD:
- case NO_CHANGE:
- case RENAMED:
- return true;
-
- case REJECTED_OTHER_REASON:
- case REJECTED_MISSING_OBJECT:
- case REJECTED_CURRENT_BRANCH:
- case NOT_ATTEMPTED:
- case LOCK_FAILURE:
- case IO_FAILURE:
- case REJECTED:
- default:
- return false;
- }
- }
-
- protected RefPair newRefPairFrom(RefUpdate refUpdate) throws IOException {
- return new RefPair(getCurrentRef(refUpdate.getName()), refUpdate.getNewObjectId());
- }
-
- protected Ref getCurrentRef(String refName) throws IOException {
- return MoreObjects.firstNonNull(refDb.findRef(refName), nullRef(refName));
- }
-
- public static class CloseableSet<T extends AutoCloseable> implements AutoCloseable {
- private final HashMap<String, AutoCloseable> elements;
-
- public CloseableSet() {
- this(new HashMap<>());
- }
-
- public CloseableSet(HashMap<String, AutoCloseable> elements) {
- this.elements = elements;
- }
-
- public void addResourceIfNotExist(
- String key, ExceptionThrowingSupplier<T, SharedLockException> resourceFactory)
- throws SharedLockException {
- if (!elements.containsKey(key)) {
- elements.put(key, resourceFactory.create());
- }
- }
-
- @Override
- public void close() {
- elements.values().stream()
- .forEach(
- closeable -> {
- try {
- closeable.close();
- } catch (Exception closingException) {
- logger.atSevere().withCause(closingException).log(
- "Exception trying to release resource %s, "
- + "the locked resources won't be accessible in all cluster unless"
- + " the lock is removed from ZK manually",
- closeable);
- }
- });
- }
- }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ValidationMetrics.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ValidationMetrics.java
deleted file mode 100644
index cd2129a..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ValidationMetrics.java
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation;
-
-import com.google.gerrit.metrics.Counter1;
-import com.google.gerrit.metrics.MetricMaker;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import com.googlesource.gerrit.plugins.multisite.MultiSiteMetrics;
-
-@Singleton
-public class ValidationMetrics extends MultiSiteMetrics {
- private static final String GIT_UPDATE_SPLIT_BRAIN_PREVENTED = "git_update_split_brain_prevented";
- private static final String GIT_UPDATE_SPLIT_BRAIN = "git_update_split_brain";
-
- private final Counter1<String> splitBrainPreventionCounter;
- private final Counter1<String> splitBrainCounter;
-
- @Inject
- public ValidationMetrics(MetricMaker metricMaker) {
- this.splitBrainPreventionCounter =
- metricMaker.newCounter(
- "multi_site/validation/git_update_split_brain_prevented",
- rateDescription("errors", "Rate of REST API error responses"),
- stringField(
- GIT_UPDATE_SPLIT_BRAIN_PREVENTED,
- "Ref-update operations, split-brain detected and prevented"));
-
- this.splitBrainCounter =
- metricMaker.newCounter(
- "multi_site/validation/git_update_split_brain",
- rateDescription("errors", "Rate of REST API error responses"),
- stringField(
- GIT_UPDATE_SPLIT_BRAIN,
- "Ref-update operation left node in a split-brain scenario"));
- }
-
- public void incrementSplitBrainPrevention() {
- splitBrainPreventionCounter.increment(GIT_UPDATE_SPLIT_BRAIN_PREVENTED);
- }
-
- public void incrementSplitBrain() {
- splitBrainCounter.increment(GIT_UPDATE_SPLIT_BRAIN);
- }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ValidationModule.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ValidationModule.java
index 4a34b7a..fe224ae 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ValidationModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ValidationModule.java
@@ -14,20 +14,31 @@
package com.googlesource.gerrit.plugins.multisite.validation;
+import com.gerritforge.gerrit.globalrefdb.validation.BatchRefUpdateValidator;
+import com.gerritforge.gerrit.globalrefdb.validation.LockWrapper;
+import com.gerritforge.gerrit.globalrefdb.validation.Log4jSharedRefLogger;
+import com.gerritforge.gerrit.globalrefdb.validation.RefUpdateValidator;
+import com.gerritforge.gerrit.globalrefdb.validation.SharedRefDatabaseWrapper;
+import com.gerritforge.gerrit.globalrefdb.validation.SharedRefDbBatchRefUpdate;
+import com.gerritforge.gerrit.globalrefdb.validation.SharedRefDbConfiguration;
+import com.gerritforge.gerrit.globalrefdb.validation.SharedRefDbGitRepositoryManager;
+import com.gerritforge.gerrit.globalrefdb.validation.SharedRefDbRefDatabase;
+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.common.collect.ImmutableSet;
import com.google.gerrit.extensions.config.FactoryModule;
import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.inject.Scopes;
+import com.google.inject.TypeLiteral;
+import com.google.inject.name.Names;
import com.googlesource.gerrit.plugins.multisite.Configuration;
-import com.googlesource.gerrit.plugins.multisite.LockWrapper;
import com.googlesource.gerrit.plugins.multisite.Log4jProjectVersionLogger;
-import com.googlesource.gerrit.plugins.multisite.Log4jSharedRefLogger;
import com.googlesource.gerrit.plugins.multisite.ProjectVersionLogger;
-import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
-import com.googlesource.gerrit.plugins.multisite.SharedRefLogger;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.CustomSharedRefEnforcementByProject;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.DefaultSharedRefEnforcement;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement;
import com.googlesource.gerrit.plugins.replication.ReplicationExtensionPointModule;
import com.googlesource.gerrit.plugins.replication.ReplicationPushFilter;
@@ -47,18 +58,25 @@
bind(ProjectVersionLogger.class).to(Log4jProjectVersionLogger.class);
factory(LockWrapper.Factory.class);
- factory(MultiSiteRepository.Factory.class);
- factory(MultiSiteRefDatabase.Factory.class);
- factory(MultiSiteRefUpdate.Factory.class);
- factory(MultiSiteBatchRefUpdate.Factory.class);
+ factory(SharedRefDbRepository.Factory.class);
+ factory(SharedRefDbRefDatabase.Factory.class);
+ factory(SharedRefDbRefUpdate.Factory.class);
+ factory(SharedRefDbBatchRefUpdate.Factory.class);
factory(RefUpdateValidator.Factory.class);
factory(BatchRefUpdateValidator.Factory.class);
- bind(GitRepositoryManager.class).to(MultiSiteGitRepositoryManager.class);
+ bind(SharedRefDbConfiguration.class).toInstance(cfg.getSharedRefDbConfiguration());
+ bind(new TypeLiteral<ImmutableSet<String>>() {})
+ .annotatedWith(Names.named(SharedRefDbGitRepositoryManager.IGNORED_REFS))
+ .toInstance(
+ ImmutableSet.of(
+ ProjectVersionRefUpdate.MULTI_SITE_VERSIONING_REF,
+ ProjectVersionRefUpdate.MULTI_SITE_VERSIONING_VALUE_REF));
+ bind(GitRepositoryManager.class).to(SharedRefDbGitRepositoryManager.class);
DynamicItem.bind(binder(), ReplicationPushFilter.class)
.to(MultisiteReplicationPushFilter.class);
- if (cfg.getSharedRefDb().getEnforcementRules().isEmpty()) {
+ if (cfg.getSharedRefDbConfiguration().getSharedRefDb().getEnforcementRules().isEmpty()) {
bind(SharedRefEnforcement.class).to(DefaultSharedRefEnforcement.class).in(Scopes.SINGLETON);
} else {
bind(SharedRefEnforcement.class)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/CustomSharedRefEnforcementByProject.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/CustomSharedRefEnforcementByProject.java
deleted file mode 100644
index 77a0c0b..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/CustomSharedRefEnforcementByProject.java
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation.dfsrefdb;
-
-import static com.google.common.base.Suppliers.memoize;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Splitter;
-import com.google.common.base.Supplier;
-import com.google.common.collect.ImmutableMap;
-import com.google.inject.Inject;
-import com.googlesource.gerrit.plugins.multisite.Configuration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-public class CustomSharedRefEnforcementByProject implements SharedRefEnforcement {
- private static final String ALL = ".*";
-
- private final Supplier<Map<String, Map<String, EnforcePolicy>>> predefEnforcements;
-
- @Inject
- public CustomSharedRefEnforcementByProject(Configuration config) {
- this.predefEnforcements = memoize(() -> parseDryRunEnforcementsToMap(config));
- }
-
- private static Map<String, Map<String, EnforcePolicy>> parseDryRunEnforcementsToMap(
- Configuration config) {
- Map<String, Map<String, EnforcePolicy>> enforcementMap = new HashMap<>();
-
- for (Map.Entry<EnforcePolicy, String> enforcementEntry :
- config.getSharedRefDb().getEnforcementRules().entries()) {
- parseEnforcementEntry(enforcementMap, enforcementEntry);
- }
-
- return enforcementMap;
- }
-
- private static void parseEnforcementEntry(
- Map<String, Map<String, EnforcePolicy>> enforcementMap,
- Map.Entry<EnforcePolicy, String> enforcementEntry) {
- Iterator<String> projectAndRef = Splitter.on(':').split(enforcementEntry.getValue()).iterator();
- EnforcePolicy enforcementPolicy = enforcementEntry.getKey();
-
- if (projectAndRef.hasNext()) {
- String projectName = emptyToAll(projectAndRef.next());
- String refName = emptyToAll(projectAndRef.hasNext() ? projectAndRef.next() : ALL);
-
- Map<String, EnforcePolicy> existingOrDefaultRef =
- enforcementMap.getOrDefault(projectName, new HashMap<>());
-
- existingOrDefaultRef.put(refName, enforcementPolicy);
-
- enforcementMap.put(projectName, existingOrDefaultRef);
- }
- }
-
- private static String emptyToAll(String value) {
- return value.trim().isEmpty() ? ALL : value;
- }
-
- @Override
- public EnforcePolicy getPolicy(String projectName, String refName) {
- if (isRefToBeIgnoredBySharedRefDb(refName)) {
- return EnforcePolicy.IGNORED;
- }
-
- return getRefEnforcePolicy(projectName, refName);
- }
-
- private EnforcePolicy getRefEnforcePolicy(String projectName, String refName) {
- Map<String, EnforcePolicy> orDefault =
- predefEnforcements
- .get()
- .getOrDefault(
- projectName, predefEnforcements.get().getOrDefault(ALL, ImmutableMap.of()));
-
- return MoreObjects.firstNonNull(
- orDefault.getOrDefault(refName, orDefault.get(ALL)), EnforcePolicy.REQUIRED);
- }
-
- @Override
- public EnforcePolicy getPolicy(String projectName) {
- Map<String, EnforcePolicy> policiesForProject =
- predefEnforcements
- .get()
- .getOrDefault(
- projectName, predefEnforcements.get().getOrDefault(ALL, ImmutableMap.of()));
- return policiesForProject.getOrDefault(ALL, EnforcePolicy.REQUIRED);
- }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/DefaultSharedRefEnforcement.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/DefaultSharedRefEnforcement.java
deleted file mode 100644
index 01cd5c5..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/DefaultSharedRefEnforcement.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation.dfsrefdb;
-
-public class DefaultSharedRefEnforcement implements SharedRefEnforcement {
-
- @Override
- public EnforcePolicy getPolicy(String projectName, String refName) {
- return isRefToBeIgnoredBySharedRefDb(refName) ? EnforcePolicy.IGNORED : EnforcePolicy.REQUIRED;
- }
-
- @Override
- public EnforcePolicy getPolicy(String projectName) {
- return EnforcePolicy.REQUIRED;
- }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/NoopSharedRefDatabase.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/NoopSharedRefDatabase.java
deleted file mode 100644
index 1530838..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/NoopSharedRefDatabase.java
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation.dfsrefdb;
-
-import com.gerritforge.gerrit.globalrefdb.GlobalRefDatabase;
-import com.gerritforge.gerrit.globalrefdb.GlobalRefDbLockException;
-import com.gerritforge.gerrit.globalrefdb.GlobalRefDbSystemError;
-import com.google.gerrit.entities.Project;
-import java.util.Optional;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Ref;
-
-public class NoopSharedRefDatabase implements GlobalRefDatabase {
-
- @Override
- public boolean isUpToDate(Project.NameKey project, Ref ref) throws GlobalRefDbLockException {
- return true;
- }
-
- @Override
- public boolean compareAndPut(Project.NameKey project, Ref currRef, ObjectId newRefValue)
- throws GlobalRefDbSystemError {
- return true;
- }
-
- @Override
- public <T> boolean compareAndPut(Project.NameKey project, String refName, T currValue, T newValue)
- throws GlobalRefDbSystemError {
- return false;
- }
-
- @Override
- public AutoCloseable lockRef(Project.NameKey project, String refName)
- throws GlobalRefDbLockException {
- return () -> {};
- }
-
- @Override
- public boolean exists(Project.NameKey project, String refName) {
- return false;
- }
-
- @Override
- public void remove(Project.NameKey project) throws GlobalRefDbSystemError {}
-
- @Override
- public <T> Optional<T> get(Project.NameKey project, String refName, Class<T> clazz)
- throws GlobalRefDbSystemError {
- return Optional.empty();
- }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/OutOfSyncException.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/OutOfSyncException.java
deleted file mode 100644
index 50f06b9..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/OutOfSyncException.java
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation.dfsrefdb;
-
-import java.io.IOException;
-import org.eclipse.jgit.lib.Ref;
-
-/** Local project/ref is out of sync with the shared refdb */
-public class OutOfSyncException extends IOException {
- private static final long serialVersionUID = 1L;
-
- public OutOfSyncException(String project, Ref localRef) {
- super(
- localRef == null
- ? String.format(
- "Local ref doesn't exists locally for project %s but exists in the shared ref-db",
- project)
- : String.format(
- "Local ref %s (ObjectId=%s) on project %s is out of sync with the shared ref-db",
- localRef.getName(), localRef.getObjectId().getName(), project));
- }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/SharedDbSplitBrainException.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/SharedDbSplitBrainException.java
deleted file mode 100644
index 8ca54c9..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/SharedDbSplitBrainException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation.dfsrefdb;
-
-import java.io.IOException;
-
-public class SharedDbSplitBrainException extends IOException {
- private static final long serialVersionUID = 1L;
-
- public SharedDbSplitBrainException(String message) {
- super(message);
- }
-
- public SharedDbSplitBrainException(String message, Throwable cause) {
- super(message, cause);
- }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/SharedLockException.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/SharedLockException.java
deleted file mode 100644
index e53c37c..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/SharedLockException.java
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation.dfsrefdb;
-
-import java.io.IOException;
-
-/** Unable to lock a project/ref resource. */
-public class SharedLockException extends IOException {
- private static final long serialVersionUID = 1L;
-
- public SharedLockException(String project, String refName, Exception cause) {
- super(String.format("Unable to lock project %s on ref %s", project, refName), cause);
- }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/SharedRefEnforcement.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/SharedRefEnforcement.java
deleted file mode 100644
index 100def2..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/SharedRefEnforcement.java
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation.dfsrefdb;
-
-/** Type of enforcement to implement between the local and shared RefDb. */
-public interface SharedRefEnforcement {
- public enum EnforcePolicy {
- IGNORED,
- REQUIRED;
- }
-
- /**
- * Get the enforcement policy for a project/refName.
- *
- * @param projectName project to be enforced
- * @param refName ref name to be enforced
- * @return the {@link EnforcePolicy} value
- */
- public EnforcePolicy getPolicy(String projectName, String refName);
-
- /**
- * Get the enforcement policy for a project
- *
- * @param projectName
- * @return the {@link EnforcePolicy} value
- */
- public EnforcePolicy getPolicy(String projectName);
-
- /**
- * Check if a refName should be ignored by shared Ref-Db
- *
- * @param refName
- * @return true if ref should be ignored; false otherwise
- */
- default boolean isRefToBeIgnoredBySharedRefDb(String refName) {
- return refName == null
- || refName.startsWith("refs/draft-comments")
- || (refName.startsWith("refs/changes") && !refName.endsWith("/meta"))
- || refName.startsWith("refs/cache-automerge");
- }
-}
diff --git a/src/main/resources/Documentation/about.md b/src/main/resources/Documentation/about.md
index b6de0a9..623871b 100644
--- a/src/main/resources/Documentation/about.md
+++ b/src/main/resources/Documentation/about.md
@@ -10,6 +10,8 @@
* events-broker library must be installed as a library module in the
`$GERRIT_SITE/lib` directory of all the masters
+* global-refdb library must be installed as a library module in the
+ `$GERRIT_SITE/lib` directory of all the masters
* connected to the same message broker
* behind a load balancer (e.g., HAProxy)
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/ProjectsFilterTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/ProjectsFilterTest.java
deleted file mode 100644
index e81c906..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/ProjectsFilterTest.java
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright (C) 2020 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.multisite;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import com.google.common.collect.Lists;
-import com.google.gerrit.entities.Project.NameKey;
-import com.google.gerrit.server.events.Event;
-import com.google.gerrit.server.events.ProjectEvent;
-import com.google.gerrit.server.events.RefUpdatedEvent;
-import com.google.gerrit.testing.GerritJUnit;
-import com.googlesource.gerrit.plugins.multisite.Configuration.Projects;
-import java.util.Collections;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-
-@RunWith(MockitoJUnitRunner.class)
-public class ProjectsFilterTest {
-
- @Mock private Configuration configuration;
- @Mock private Projects projects;
-
- private ProjectsFilter objectUnderTest;
-
- @Test
- public void shouldMatchByExactProjectName() {
- when(projects.getPatterns()).thenReturn(Lists.newArrayList("test_project"));
- when(configuration.projects()).thenReturn(projects);
-
- objectUnderTest = new ProjectsFilter(configuration);
-
- assertThat(objectUnderTest.matches(NameKey.parse("test_project"))).isTrue();
- assertThat(objectUnderTest.matches(NameKey.parse("test_project2"))).isFalse();
- }
-
- @Test
- public void shouldMatchByWildcard() {
- when(projects.getPatterns()).thenReturn(Lists.newArrayList("test_project*"));
- when(configuration.projects()).thenReturn(projects);
-
- objectUnderTest = new ProjectsFilter(configuration);
-
- assertThat(objectUnderTest.matches(NameKey.parse("test_project"))).isTrue();
- assertThat(objectUnderTest.matches(NameKey.parse("test_project2"))).isTrue();
- assertThat(objectUnderTest.matches(NameKey.parse("2test_project"))).isFalse();
- }
-
- @Test
- public void shouldMatchByRegex() {
- when(projects.getPatterns()).thenReturn(Lists.newArrayList("^test_(project|project2)"));
- when(configuration.projects()).thenReturn(projects);
-
- objectUnderTest = new ProjectsFilter(configuration);
-
- assertThat(objectUnderTest.matches(NameKey.parse("test_project"))).isTrue();
- assertThat(objectUnderTest.matches(NameKey.parse("test_project2"))).isTrue();
- assertThat(objectUnderTest.matches(NameKey.parse("test_project3"))).isFalse();
- }
-
- @Test
- public void shouldExcludeByRegex() {
- when(projects.getPatterns()).thenReturn(Lists.newArrayList("^(?:(?!test_project3).)*$"));
- when(configuration.projects()).thenReturn(projects);
-
- objectUnderTest = new ProjectsFilter(configuration);
-
- assertThat(objectUnderTest.matches(NameKey.parse("test_project"))).isTrue();
- assertThat(objectUnderTest.matches(NameKey.parse("test_project2"))).isTrue();
- assertThat(objectUnderTest.matches(NameKey.parse("test_project3"))).isFalse();
- }
-
- @Test
- public void shouldExcludeByMultipleProjectsRegexPattern() {
- when(projects.getPatterns())
- .thenReturn(Lists.newArrayList("^(?:(?!(test_project3|test_project4)).)*$"));
- when(configuration.projects()).thenReturn(projects);
-
- objectUnderTest = new ProjectsFilter(configuration);
-
- assertThat(objectUnderTest.matches(NameKey.parse("test_project"))).isTrue();
- assertThat(objectUnderTest.matches(NameKey.parse("test_project2"))).isTrue();
- assertThat(objectUnderTest.matches(NameKey.parse("test_project3"))).isFalse();
- assertThat(objectUnderTest.matches(NameKey.parse("test_project4"))).isFalse();
- }
-
- @Test
- public void shouldMatchWhenNoPatternProvided() {
- when(projects.getPatterns()).thenReturn(Collections.emptyList());
- when(configuration.projects()).thenReturn(projects);
-
- objectUnderTest = new ProjectsFilter(configuration);
-
- assertThat(objectUnderTest.matches(NameKey.parse("test_project"))).isTrue();
- }
-
- @Test
- public void shouldMatchProjectEvent() {
- ProjectEvent event = mock(ProjectEvent.class);
- when(event.getProjectNameKey()).thenReturn(NameKey.parse("test_project"));
- when(projects.getPatterns()).thenReturn(Lists.newArrayList("test_project"));
- when(configuration.projects()).thenReturn(projects);
-
- objectUnderTest = new ProjectsFilter(configuration);
-
- assertThat(objectUnderTest.matches(event)).isTrue();
- }
-
- @Test
- public void shouldMatchRefUpdatedEvent() {
- RefUpdatedEvent event = mock(RefUpdatedEvent.class);
- when(event.getProjectNameKey()).thenReturn(NameKey.parse("test_project"));
- when(projects.getPatterns()).thenReturn(Lists.newArrayList("test_project"));
- when(configuration.projects()).thenReturn(projects);
-
- objectUnderTest = new ProjectsFilter(configuration);
-
- assertThat(objectUnderTest.matches(event)).isTrue();
- }
-
- @Test
- public void shouldExcludedNonProjectEvents() {
- Event event = mock(Event.class);
- when(projects.getPatterns()).thenReturn(Lists.newArrayList("test_project)"));
- when(configuration.projects()).thenReturn(projects);
-
- objectUnderTest = new ProjectsFilter(configuration);
-
- assertThat(objectUnderTest.matches(event)).isFalse();
- }
-
- @Test
- public void shouldThrowExceptionWhenProjecNameIsNull() {
- when(projects.getPatterns()).thenReturn(Collections.emptyList());
- when(configuration.projects()).thenReturn(projects);
-
- objectUnderTest = new ProjectsFilter(configuration);
-
- GerritJUnit.assertThrows(
- IllegalArgumentException.class, () -> objectUnderTest.matches((NameKey) null));
- }
-
- @Test
- public void shouldThrowExceptionWhenProjecNameIsEmpty() {
- when(projects.getPatterns()).thenReturn(Collections.emptyList());
- when(configuration.projects()).thenReturn(projects);
-
- objectUnderTest = new ProjectsFilter(configuration);
-
- GerritJUnit.assertThrows(
- IllegalArgumentException.class, () -> objectUnderTest.matches(NameKey.parse("")));
- }
-
- @Test
- public void shouldThrowExceptionWhenEventIsNull() {
- when(projects.getPatterns()).thenReturn(Collections.emptyList());
- when(configuration.projects()).thenReturn(projects);
-
- objectUnderTest = new ProjectsFilter(configuration);
-
- GerritJUnit.assertThrows(
- IllegalArgumentException.class, () -> objectUnderTest.matches((Event) null));
- }
-}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandlerTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandlerTest.java
index 2a25c37..4263ddb 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandlerTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandlerTest.java
@@ -23,11 +23,11 @@
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
+import com.gerritforge.gerrit.globalrefdb.validation.ProjectsFilter;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.gerrit.extensions.events.NewProjectCreatedListener;
import com.google.gerrit.extensions.events.ProjectDeletedListener;
import com.google.gerrit.extensions.registration.DynamicSet;
-import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.cache.ProjectListUpdateHandler.ProjectListUpdateTask;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
import com.googlesource.gerrit.plugins.multisite.forwarder.ProjectListUpdateForwarder;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/consumer/SubscriberMetricsTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/consumer/SubscriberMetricsTest.java
index 99148fa..8aa043d 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/consumer/SubscriberMetricsTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/consumer/SubscriberMetricsTest.java
@@ -18,6 +18,7 @@
import static org.mockito.Mockito.when;
import com.gerritforge.gerrit.eventbroker.EventMessage;
+import com.gerritforge.gerrit.globalrefdb.validation.SharedRefDatabaseWrapper;
import com.google.common.base.Suppliers;
import com.google.gerrit.entities.Project;
import com.google.gerrit.metrics.MetricMaker;
@@ -25,7 +26,6 @@
import com.google.gerrit.server.events.RefUpdatedEvent;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.googlesource.gerrit.plugins.multisite.ProjectVersionLogger;
-import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
import com.googlesource.gerrit.plugins.multisite.validation.ProjectVersionRefUpdate;
import java.util.Optional;
import java.util.UUID;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/event/CacheEvictionEventRouterTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/event/CacheEvictionEventRouterTest.java
index a632b74..bf5c5d9 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/event/CacheEvictionEventRouterTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/event/CacheEvictionEventRouterTest.java
@@ -18,8 +18,8 @@
import com.google.gson.Gson;
import com.googlesource.gerrit.plugins.multisite.forwarder.CacheEntry;
+import com.googlesource.gerrit.plugins.multisite.forwarder.CacheKeyJsonParser;
import com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedCacheEvictionHandler;
-import com.googlesource.gerrit.plugins.multisite.forwarder.GsonParser;
import com.googlesource.gerrit.plugins.multisite.forwarder.events.CacheEvictionEvent;
import com.googlesource.gerrit.plugins.multisite.forwarder.router.CacheEvictionEventRouter;
import org.junit.Before;
@@ -36,7 +36,7 @@
@Before
public void setUp() {
- router = new CacheEvictionEventRouter(cacheEvictionHandler, new GsonParser(new Gson()));
+ router = new CacheEvictionEventRouter(cacheEvictionHandler, new CacheKeyJsonParser(new Gson()));
}
@Test
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/event/EventHandlerTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/event/EventHandlerTest.java
index bac0851..b9b416d 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/event/EventHandlerTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/event/EventHandlerTest.java
@@ -22,12 +22,12 @@
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
+import com.gerritforge.gerrit.globalrefdb.validation.ProjectsFilter;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.server.events.Event;
import com.google.gerrit.server.events.ProjectEvent;
import com.google.gerrit.server.events.RefUpdatedEvent;
-import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.event.EventHandler.EventTask;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
import com.googlesource.gerrit.plugins.multisite.forwarder.StreamEventForwarder;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/GsonParserTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/CacheKeyJsonParserTest.java
similarity index 81%
rename from src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/GsonParserTest.java
rename to src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/CacheKeyJsonParserTest.java
index 12bdb74..7efd4dd 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/GsonParserTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/CacheKeyJsonParserTest.java
@@ -18,16 +18,17 @@
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.AccountGroup;
+import com.google.gerrit.entities.Project;
import com.google.gerrit.server.events.EventGsonProvider;
import com.google.gson.Gson;
import com.googlesource.gerrit.plugins.multisite.cache.Constants;
import org.junit.Test;
-public class GsonParserTest {
+public class CacheKeyJsonParserTest {
private static final Object EMPTY_JSON = "{}";
private final Gson gson = new EventGsonProvider().get();
- private final GsonParser gsonParser = new GsonParser(gson);
+ private final CacheKeyJsonParser gsonParser = new CacheKeyJsonParser(gson);
@Test
public void accountIDParse() {
@@ -51,9 +52,16 @@
}
@Test
+ public void projectNameKeyParse() {
+ Project.NameKey name = Project.nameKey("foo");
+ String json = gson.toJson(name);
+ assertThat(name).isEqualTo(gsonParser.fromJson(Constants.PROJECTS, json));
+ }
+
+ @Test
public void stringParse() {
String key = "key";
- assertThat(key).isEqualTo(gsonParser.fromJson(Constants.PROJECTS, key));
+ assertThat(key).isEqualTo(gsonParser.fromJson("any-cache-with-string-key", key));
}
@Test
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedCacheEvictionHandlerIT.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedCacheEvictionHandlerIT.java
new file mode 100644
index 0000000..fb2a50b
--- /dev/null
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedCacheEvictionHandlerIT.java
@@ -0,0 +1,132 @@
+// Copyright (C) 2021 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.multisite.forwarder;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.gerritforge.gerrit.globalrefdb.validation.SharedRefDbConfiguration;
+import com.google.common.cache.RemovalNotification;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
+import com.google.gerrit.acceptance.TestPlugin;
+import com.google.gerrit.extensions.registration.DynamicSet;
+import com.google.gerrit.extensions.registration.RegistrationHandle;
+import com.google.gerrit.server.cache.CacheRemovalListener;
+import com.google.gerrit.server.events.EventGson;
+import com.google.gerrit.server.project.ProjectCacheImpl;
+import com.google.gson.Gson;
+import com.google.inject.AbstractModule;
+import com.google.inject.Inject;
+import com.googlesource.gerrit.plugins.multisite.cache.CacheModule;
+import com.googlesource.gerrit.plugins.multisite.forwarder.events.CacheEvictionEvent;
+import com.googlesource.gerrit.plugins.multisite.forwarder.router.CacheEvictionEventRouter;
+import com.googlesource.gerrit.plugins.multisite.forwarder.router.RouterModule;
+import com.googlesource.gerrit.plugins.multisite.index.IndexModule;
+import java.time.Duration;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import org.eclipse.jgit.lib.Config;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+@TestPlugin(
+ name = "multi-site",
+ sysModule =
+ "com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedCacheEvictionHandlerIT$TestModule")
+public class ForwardedCacheEvictionHandlerIT extends LightweightPluginDaemonTest {
+ private static final Duration CACHE_EVICTIONS_WAIT_TIMEOUT = Duration.ofMinutes(1);
+
+ @SuppressWarnings("rawtypes")
+ @Inject
+ private DynamicSet<CacheRemovalListener> cacheRemovalListeners;
+
+ @Inject private CacheEvictionEventRouter objectUnderTest;
+ @Inject @EventGson private Gson gson;
+ private CacheEvictionsTracker<?, ?> evictionsCacheTracker;
+ private RegistrationHandle cacheEvictionRegistrationHandle;
+
+ public static class TestModule extends AbstractModule {
+ @Override
+ protected void configure() {
+ install(new ForwarderModule());
+ install(new CacheModule());
+ install(new RouterModule());
+ install(new IndexModule());
+ SharedRefDbConfiguration sharedRefDbConfig =
+ new SharedRefDbConfiguration(new Config(), "multi-site");
+ bind(SharedRefDbConfiguration.class).toInstance(sharedRefDbConfig);
+ }
+ }
+
+ public static class CacheEvictionsTracker<K, V> implements CacheRemovalListener<K, V> {
+ private final Map<String, Set<Object>> trackedEvictions;
+ private final CountDownLatch allExpectedEvictionsArrived;
+
+ public CacheEvictionsTracker(int numExpectedEvictions) {
+ allExpectedEvictionsArrived = new CountDownLatch(numExpectedEvictions);
+ trackedEvictions = Maps.newHashMap();
+ }
+
+ public Set<Object> trackedEvictionsFor(String cacheName) {
+ return trackedEvictions.getOrDefault(cacheName, Collections.emptySet());
+ }
+
+ public void waitForExpectedEvictions() throws InterruptedException {
+ allExpectedEvictionsArrived.await(
+ CACHE_EVICTIONS_WAIT_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
+ }
+
+ @Override
+ public void onRemoval(
+ String pluginName, String cacheName, RemovalNotification<K, V> notification) {
+ trackedEvictions.compute(
+ cacheName,
+ (k, v) -> {
+ if (v == null) {
+ return Sets.newHashSet(notification.getKey());
+ }
+ v.add(notification.getKey());
+ return v;
+ });
+ allExpectedEvictionsArrived.countDown();
+ }
+ }
+
+ @Before
+ public void startTrackingCacheEvictions() {
+ evictionsCacheTracker = new CacheEvictionsTracker<>(1);
+ cacheEvictionRegistrationHandle = cacheRemovalListeners.add("gerrit", evictionsCacheTracker);
+ }
+
+ @After
+ public void stopTrackingCacheEvictions() {
+ cacheEvictionRegistrationHandle.remove();
+ }
+
+ @Test
+ public void shouldEvictProjectCache() throws Exception {
+ objectUnderTest.route(
+ new CacheEvictionEvent(ProjectCacheImpl.CACHE_NAME, gson.toJson(project)));
+ evictionsCacheTracker.waitForExpectedEvictions();
+
+ assertThat(evictionsCacheTracker.trackedEvictionsFor(ProjectCacheImpl.CACHE_NAME))
+ .contains(project);
+ }
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/index/IndexEventHandlerTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/index/IndexEventHandlerTest.java
index 022dec5..660a302 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/index/IndexEventHandlerTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/index/IndexEventHandlerTest.java
@@ -21,9 +21,9 @@
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
+import com.gerritforge.gerrit.globalrefdb.validation.ProjectsFilter;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.gerrit.extensions.registration.DynamicSet;
-import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.forwarder.IndexEventForwarder;
import com.googlesource.gerrit.plugins.multisite.forwarder.events.ProjectIndexEvent;
import com.googlesource.gerrit.plugins.multisite.index.IndexEventHandler.IndexProjectTask;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidatorTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidatorTest.java
deleted file mode 100644
index 41bebc2..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidatorTest.java
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.eclipse.jgit.transport.ReceiveCommand.Type.UPDATE;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.lenient;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import com.google.gerrit.entities.Project;
-import com.google.gerrit.metrics.DisabledMetricMaker;
-import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
-import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
-import com.googlesource.gerrit.plugins.multisite.validation.RefUpdateValidator.OneParameterVoidFunction;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.DefaultSharedRefEnforcement;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import org.eclipse.jgit.internal.storage.file.RefDirectory;
-import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
-import org.eclipse.jgit.junit.TestRepository;
-import org.eclipse.jgit.lib.BatchRefUpdate;
-import org.eclipse.jgit.lib.NullProgressMonitor;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.revwalk.RevWalk;
-import org.eclipse.jgit.transport.ReceiveCommand;
-import org.eclipse.jgit.transport.ReceiveCommand.Result;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TestName;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-
-@RunWith(MockitoJUnitRunner.class)
-public class BatchRefUpdateValidatorTest extends LocalDiskRepositoryTestCase implements RefFixture {
- @Rule public TestName nameRule = new TestName();
-
- private Repository diskRepo;
- private TestRepository<Repository> repo;
- private RefDirectory refdir;
- private RevCommit A;
- private RevCommit B;
-
- @Mock SharedRefDatabaseWrapper sharedRefDatabase;
-
- @Mock SharedRefEnforcement tmpRefEnforcement;
-
- @Mock ProjectsFilter projectsFilter;
-
- @Mock OneParameterVoidFunction<List<ReceiveCommand>> rollbackFunction;
-
- @Before
- public void setup() throws Exception {
- super.setUp();
- when(projectsFilter.matches(anyString())).thenReturn(true);
- gitRepoSetup();
- }
-
- private void gitRepoSetup() throws Exception {
- diskRepo = createBareRepository();
- refdir = (RefDirectory) diskRepo.getRefDatabase();
- repo = new TestRepository<>(diskRepo);
- A = repo.commit().create();
- B = repo.commit(repo.getRevWalk().parseCommit(A));
- }
-
- @Test
- public void immutableChangeShouldNotBeWrittenIntoZk() throws Exception {
- String AN_IMMUTABLE_REF = "refs/changes/01/1/1";
-
- List<ReceiveCommand> cmds = Arrays.asList(new ReceiveCommand(A, B, AN_IMMUTABLE_REF, UPDATE));
-
- BatchRefUpdate batchRefUpdate = newBatchUpdate(cmds);
- BatchRefUpdateValidator BatchRefUpdateValidator = newDefaultValidator(A_TEST_PROJECT_NAME);
-
- BatchRefUpdateValidator.executeBatchUpdateWithValidation(
- batchRefUpdate, () -> execute(batchRefUpdate), this::defaultRollback);
-
- verify(sharedRefDatabase, never())
- .compareAndPut(any(Project.NameKey.class), any(Ref.class), any(ObjectId.class));
- }
-
- @Test
- public void compareAndPutShouldAlwaysIngoreAlwaysDraftCommentsEvenOutOfOrder() throws Exception {
- String DRAFT_COMMENT = "refs/draft-comments/56/450756/1013728";
- List<ReceiveCommand> cmds = Arrays.asList(new ReceiveCommand(A, B, DRAFT_COMMENT, UPDATE));
-
- BatchRefUpdate batchRefUpdate = newBatchUpdate(cmds);
- BatchRefUpdateValidator BatchRefUpdateValidator = newDefaultValidator(A_TEST_PROJECT_NAME);
-
- BatchRefUpdateValidator.executeBatchUpdateWithValidation(
- batchRefUpdate, () -> execute(batchRefUpdate), this::defaultRollback);
-
- verify(sharedRefDatabase, never())
- .compareAndPut(A_TEST_PROJECT_NAME_KEY, newRef(DRAFT_COMMENT, A.getId()), B.getId());
- }
-
- @Test
- public void validationShouldFailWhenLocalRefDbIsOutOfSync() throws Exception {
- String AN_OUT_OF_SYNC_REF = "refs/changes/01/1/1";
- BatchRefUpdate batchRefUpdate =
- newBatchUpdate(
- Collections.singletonList(new ReceiveCommand(A, B, AN_OUT_OF_SYNC_REF, UPDATE)));
- BatchRefUpdateValidator batchRefUpdateValidator =
- getRefValidatorForEnforcement(A_TEST_PROJECT_NAME, tmpRefEnforcement);
-
- doReturn(SharedRefEnforcement.EnforcePolicy.REQUIRED)
- .when(batchRefUpdateValidator.refEnforcement)
- .getPolicy(A_TEST_PROJECT_NAME, AN_OUT_OF_SYNC_REF);
- lenient()
- .doReturn(false)
- .when(sharedRefDatabase)
- .isUpToDate(A_TEST_PROJECT_NAME_KEY, newRef(AN_OUT_OF_SYNC_REF, AN_OBJECT_ID_1));
-
- batchRefUpdateValidator.executeBatchUpdateWithValidation(
- batchRefUpdate, () -> execute(batchRefUpdate), rollbackFunction);
-
- verify(rollbackFunction, never()).invoke(any());
-
- final List<ReceiveCommand> commands = batchRefUpdate.getCommands();
- assertThat(commands.size()).isEqualTo(1);
- commands.forEach(
- (command) -> assertThat(command.getResult()).isEqualTo(ReceiveCommand.Result.LOCK_FAILURE));
- }
-
- @Test
- public void shouldNotUpdateSharedRefDbWhenProjectIsLocal() throws Exception {
- when(projectsFilter.matches(anyString())).thenReturn(false);
-
- String AN_OUT_OF_SYNC_REF = "refs/changes/01/1/1";
- BatchRefUpdate batchRefUpdate =
- newBatchUpdate(
- Collections.singletonList(new ReceiveCommand(A, B, AN_OUT_OF_SYNC_REF, UPDATE)));
- BatchRefUpdateValidator batchRefUpdateValidator =
- getRefValidatorForEnforcement(A_TEST_PROJECT_NAME, tmpRefEnforcement);
-
- batchRefUpdateValidator.executeBatchUpdateWithValidation(
- batchRefUpdate, () -> execute(batchRefUpdate), this::defaultRollback);
-
- verify(sharedRefDatabase, never())
- .compareAndPut(any(Project.NameKey.class), any(Ref.class), any(ObjectId.class));
- }
-
- private BatchRefUpdateValidator newDefaultValidator(String projectName) {
- return getRefValidatorForEnforcement(projectName, new DefaultSharedRefEnforcement());
- }
-
- private BatchRefUpdateValidator getRefValidatorForEnforcement(
- String projectName, SharedRefEnforcement sharedRefEnforcement) {
- return new BatchRefUpdateValidator(
- sharedRefDatabase,
- new ValidationMetrics(new DisabledMetricMaker()),
- sharedRefEnforcement,
- new DummyLockWrapper(),
- projectsFilter,
- projectName,
- diskRepo.getRefDatabase());
- }
-
- private Void execute(BatchRefUpdate u) throws IOException {
- try (RevWalk rw = new RevWalk(diskRepo)) {
- u.execute(rw, NullProgressMonitor.INSTANCE);
- }
- return null;
- }
-
- private BatchRefUpdate newBatchUpdate(List<ReceiveCommand> cmds) {
- BatchRefUpdate u = refdir.newBatchUpdate();
- u.addCommand(cmds);
- cmds.forEach(c -> c.setResult(Result.OK));
- return u;
- }
-
- @Override
- public String testBranch() {
- return "branch_" + nameRule.getMethodName();
- }
-
- private void defaultRollback(List<ReceiveCommand> cmds) throws IOException {
- // do nothing
- }
-}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/DisabledSharedRefLogger.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/DisabledSharedRefLogger.java
deleted file mode 100644
index 047a1c5..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/DisabledSharedRefLogger.java
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation;
-
-import com.googlesource.gerrit.plugins.multisite.SharedRefLogger;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Ref;
-import org.junit.Ignore;
-
-@Ignore
-public class DisabledSharedRefLogger implements SharedRefLogger {
-
- @Override
- public void logRefUpdate(String project, Ref currRef, ObjectId newRefValue) {}
-
- @Override
- public void logProjectDelete(String project) {}
-
- @Override
- public void logLockAcquisition(String project, String refName) {}
-
- @Override
- public void logLockRelease(String project, String refName) {}
-
- @Override
- public <T> void logRefUpdate(String project, String refName, T currRef, T newRefValue) {}
-}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/DummyLockWrapper.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/DummyLockWrapper.java
deleted file mode 100644
index 1ff0429..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/DummyLockWrapper.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.googlesource.gerrit.plugins.multisite.validation;
-
-import com.googlesource.gerrit.plugins.multisite.LockWrapper;
-import org.junit.Ignore;
-
-@Ignore
-public class DummyLockWrapper implements LockWrapper.Factory {
-
- @Override
- public LockWrapper create(String project, String refName, AutoCloseable lock) {
- return new LockWrapper(new DisabledSharedRefLogger(), project, refName, lock);
- }
-}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/Log4jSharedRefLoggerTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/Log4jSharedRefLoggerTest.java
deleted file mode 100644
index 3debdf4..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/Log4jSharedRefLoggerTest.java
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.gerrit.acceptance.AbstractDaemonTest;
-import com.google.gerrit.acceptance.PushOneCommit;
-import com.google.gerrit.entities.RefNames;
-import com.google.gerrit.json.OutputFormat;
-import com.google.gerrit.server.config.SitePaths;
-import com.google.gerrit.server.notedb.Sequences;
-import com.google.gerrit.server.util.SystemLog;
-import com.google.gson.Gson;
-import com.googlesource.gerrit.plugins.multisite.Log4jSharedRefLogger;
-import com.googlesource.gerrit.plugins.multisite.SharedRefLogEntry;
-import java.io.IOException;
-import java.io.StringWriter;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import org.apache.log4j.LogManager;
-import org.apache.log4j.PatternLayout;
-import org.apache.log4j.WriterAppender;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class Log4jSharedRefLoggerTest extends AbstractDaemonTest {
-
- private static final Gson gson = OutputFormat.JSON_COMPACT.newGson();
- private StringWriter logWriter;
- private Log4jSharedRefLogger log4jSharedRefLogger;
-
- @Before
- public void setUp() throws IOException {
- this.logWriter = new StringWriter();
- this.log4jSharedRefLogger = newLog4jSharedRefLogger();
- }
-
- @Test
- public void shouldLogProjectDeletion() {
- log4jSharedRefLogger.logProjectDelete(project.get());
-
- SharedRefLogEntry.DeleteProject gotLogEntry =
- gson.fromJson(logWriter.toString(), SharedRefLogEntry.DeleteProject.class);
-
- assertThat(gotLogEntry.type).isEqualTo(SharedRefLogEntry.Type.DELETE_PROJECT);
- assertThat(gotLogEntry.projectName).isEqualTo(project.get());
- }
-
- @Test
- public void shouldLogUpdateRef() throws Exception {
- final String refName = "refs/remotes/origin/master";
- Ref currRef = repo().exactRef(refName);
- PushOneCommit.Result result = pushTo(refName);
- ObjectId newRefValue = result.getCommit().toObjectId();
-
- log4jSharedRefLogger.logRefUpdate(project.get(), currRef, newRefValue);
-
- SharedRefLogEntry.UpdateRef gotLogEntry =
- gson.fromJson(logWriter.toString(), SharedRefLogEntry.UpdateRef.class);
-
- assertThat(gotLogEntry.type).isEqualTo(SharedRefLogEntry.Type.UPDATE_REF);
- assertThat(gotLogEntry.projectName).isEqualTo(project.get());
- assertThat(gotLogEntry.refName).isEqualTo(refName);
- assertThat(gotLogEntry.oldId).isEqualTo(currRef.getObjectId().getName());
- assertThat(gotLogEntry.newId).isEqualTo(newRefValue.getName());
- assertThat(gotLogEntry.comment).isNotNull();
- assertThat(gotLogEntry.committer).isNotNull();
- }
-
- @Test
- public void shouldLogDeleteRef() throws Exception {
- final String refName = "refs/remotes/origin/master";
- Ref currRef = repo().exactRef(refName);
-
- log4jSharedRefLogger.logRefUpdate(project.get(), currRef, ObjectId.zeroId());
-
- SharedRefLogEntry.DeleteRef gotLogEntry =
- gson.fromJson(logWriter.toString(), SharedRefLogEntry.DeleteRef.class);
-
- assertThat(gotLogEntry.type).isEqualTo(SharedRefLogEntry.Type.DELETE_REF);
- assertThat(gotLogEntry.projectName).isEqualTo(project.get());
- assertThat(gotLogEntry.refName).isEqualTo(refName);
- assertThat(gotLogEntry.oldId).isEqualTo(currRef.getObjectId().getName());
- }
-
- @Test
- public void shouldLogBlobRefs() throws Exception {
- Repository allUsersRepo = repoManager.openRepository(allUsers);
- String blobRefName = RefNames.REFS_SEQUENCES + Sequences.NAME_ACCOUNTS;
- Ref currRef = allUsersRepo.exactRef(blobRefName);
- log4jSharedRefLogger.logRefUpdate(allUsers.get(), currRef, currRef.getObjectId());
-
- SharedRefLogEntry.UpdateRef gotLogEntry =
- gson.fromJson(logWriter.toString(), SharedRefLogEntry.UpdateRef.class);
-
- assertThat(gotLogEntry.type).isEqualTo(SharedRefLogEntry.Type.UPDATE_REF);
- assertThat(gotLogEntry.projectName).isEqualTo(allUsers.get());
- assertThat(gotLogEntry.refName).isEqualTo(blobRefName);
- assertThat(gotLogEntry.oldId).isEqualTo(currRef.getObjectId().getName());
- assertThat(gotLogEntry.newId).isEqualTo(currRef.getObjectId().getName());
- assertThat(gotLogEntry.comment).isNull();
- assertThat(gotLogEntry.committer).isNull();
- }
-
- @Test
- public void shouldLogLockAcquisition() {
- String refName = "refs/foo/bar";
- log4jSharedRefLogger.logLockAcquisition(project.get(), refName);
-
- SharedRefLogEntry.LockAcquire gotLogEntry =
- gson.fromJson(logWriter.toString(), SharedRefLogEntry.LockAcquire.class);
-
- assertThat(gotLogEntry.type).isEqualTo(SharedRefLogEntry.Type.LOCK_ACQUIRE);
- assertThat(gotLogEntry.projectName).isEqualTo(project.get());
- assertThat(gotLogEntry.refName).isEqualTo(refName);
- }
-
- @Test
- public void shouldLogLockRelease() {
- String refName = "refs/foo/bar";
- log4jSharedRefLogger.logLockRelease(project.get(), refName);
-
- SharedRefLogEntry.LockAcquire gotLogEntry =
- gson.fromJson(logWriter.toString(), SharedRefLogEntry.LockAcquire.class);
-
- assertThat(gotLogEntry.type).isEqualTo(SharedRefLogEntry.Type.LOCK_RELEASE);
- assertThat(gotLogEntry.projectName).isEqualTo(project.get());
- assertThat(gotLogEntry.refName).isEqualTo(refName);
- }
-
- private Log4jSharedRefLogger newLog4jSharedRefLogger() throws IOException {
- final Log4jSharedRefLogger log4jSharedRefLogger =
- new Log4jSharedRefLogger(new SystemLog(new SitePaths(newPath()), baseConfig), repoManager);
- log4jSharedRefLogger.setLogger(logWriterLogger());
- return log4jSharedRefLogger;
- }
-
- private Logger logWriterLogger() {
- org.apache.log4j.Logger logger = LogManager.getLogger("logWriterLogger");
- logger.addAppender(new WriterAppender(new PatternLayout("%m"), logWriter));
- return LoggerFactory.getLogger("logWriterLogger");
- }
-
- private static Path newPath() throws IOException {
- Path tmp = Files.createTempFile("gerrit_test_", "_site");
- Files.deleteIfExists(tmp);
- return tmp;
- }
-}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteBatchRefUpdateTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteBatchRefUpdateTest.java
deleted file mode 100644
index 4aa4ba1..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteBatchRefUpdateTest.java
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation;
-
-import static java.util.Arrays.asList;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
-import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
-import com.googlesource.gerrit.plugins.multisite.validation.RefUpdateValidator.OneParameterVoidFunction;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.DefaultSharedRefEnforcement;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import org.eclipse.jgit.lib.BatchRefUpdate;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.ObjectIdRef;
-import org.eclipse.jgit.lib.ProgressMonitor;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.RefDatabase;
-import org.eclipse.jgit.revwalk.RevWalk;
-import org.eclipse.jgit.transport.ReceiveCommand;
-import org.eclipse.jgit.transport.ReceiveCommand.Result;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TestName;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatcher;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-
-@RunWith(MockitoJUnitRunner.class)
-public class MultiSiteBatchRefUpdateTest implements RefFixture {
-
- @Mock SharedRefDatabaseWrapper sharedRefDb;
- @Mock BatchRefUpdate batchRefUpdate;
- @Mock BatchRefUpdateValidator batchRefUpdateValidator;
- @Mock RefDatabase refDatabase;
- @Mock RevWalk revWalk;
- @Mock ProgressMonitor progressMonitor;
- @Mock ValidationMetrics validationMetrics;
- @Mock ProjectsFilter projectsFilter;
- @Mock OneParameterVoidFunction<List<ReceiveCommand>> rollbackFunction;
-
- private final Ref oldRef =
- new ObjectIdRef.Unpeeled(Ref.Storage.NETWORK, A_TEST_REF_NAME, AN_OBJECT_ID_1);
- private final Ref newRef =
- new ObjectIdRef.Unpeeled(Ref.Storage.NETWORK, A_TEST_REF_NAME, AN_OBJECT_ID_2);
- ReceiveCommand receiveCommandBeforeExecution =
- createReceiveCommand(
- oldRef.getObjectId(), newRef.getObjectId(), oldRef.getName(), Result.NOT_ATTEMPTED);
-
- ReceiveCommand successReceiveCommandAfterExecution =
- createReceiveCommand(oldRef.getObjectId(), newRef.getObjectId(), oldRef.getName(), Result.OK);
-
- ReceiveCommand rejectReceiveCommandAfterExecution =
- createReceiveCommand(
- oldRef.getObjectId(),
- newRef.getObjectId(),
- oldRef.getName(),
- Result.REJECTED_NONFASTFORWARD);
-
- private ReceiveCommand createReceiveCommand(
- ObjectId oldRefObjectId, ObjectId newRefObjectId, String refName, Result result) {
- ReceiveCommand receiveCommand = new ReceiveCommand(oldRefObjectId, newRefObjectId, refName);
- receiveCommand.setResult(result);
- return receiveCommand;
- }
-
- private MultiSiteBatchRefUpdate multiSiteRefUpdate;
-
- @Rule public TestName nameRule = new TestName();
-
- @Override
- public String testBranch() {
- return "branch_" + nameRule.getMethodName();
- }
-
- @Before
- public void setup() {
- when(projectsFilter.matches(anyString())).thenReturn(true);
- }
-
- @SuppressWarnings("deprecation")
- private void setMockRequiredReturnValues() throws IOException {
-
- doReturn(batchRefUpdate).when(refDatabase).newBatchUpdate();
-
- when(batchRefUpdate.getCommands())
- .thenReturn(asList(receiveCommandBeforeExecution))
- .thenReturn(asList(successReceiveCommandAfterExecution));
-
- doReturn(oldRef).when(refDatabase).getRef(A_TEST_REF_NAME);
- doReturn(oldRef).when(refDatabase).exactRef(A_TEST_REF_NAME);
-
- multiSiteRefUpdate = getMultiSiteBatchRefUpdateWithDefaultPolicyEnforcement();
-
- verifyZeroInteractions(validationMetrics);
- }
-
- @Test
- public void executeAndDelegateSuccessfullyWithNoExceptions() throws Exception {
- setMockRequiredReturnValues();
-
- // When compareAndPut against sharedDb succeeds
- doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, oldRef);
- doReturn(true)
- .when(sharedRefDb)
- .compareAndPut(eq(A_TEST_PROJECT_NAME_KEY), refEquals(oldRef), eq(newRef.getObjectId()));
- multiSiteRefUpdate.execute(revWalk, progressMonitor, Collections.emptyList());
- verify(sharedRefDb)
- .compareAndPut(eq(A_TEST_PROJECT_NAME_KEY), refEquals(oldRef), eq(newRef.getObjectId()));
- }
-
- private Ref refEquals(Ref oldRef) {
- return argThat(new RefMatcher(oldRef));
- }
-
- @Test(expected = IOException.class)
- public void executeAndFailsWithExceptions() throws IOException {
- multiSiteRefUpdate = getMultiSiteBatchRefUpdateWithMockedValidator();
- doThrow(new IOException("IO Test Exception"))
- .when(batchRefUpdateValidator)
- .executeBatchUpdateWithValidation(any(), any(), any());
-
- multiSiteRefUpdate.execute(revWalk, progressMonitor, Collections.emptyList());
- }
-
- @Test
- public void executeSuccessfullyWithNoExceptionsWhenOutOfSync() throws IOException {
- setMockRequiredReturnValues();
- doReturn(true).when(sharedRefDb).exists(A_TEST_PROJECT_NAME_KEY, A_TEST_REF_NAME);
- doReturn(false).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, oldRef);
-
- multiSiteRefUpdate.execute(revWalk, progressMonitor, Collections.emptyList());
-
- verify(validationMetrics).incrementSplitBrainPrevention();
- }
-
- @Test
- public void executeSuccessfullyWithNoExceptionsWhenEmptyList() throws IOException {
- doReturn(batchRefUpdate).when(refDatabase).newBatchUpdate();
- doReturn(Collections.emptyList()).when(batchRefUpdate).getCommands();
-
- multiSiteRefUpdate = getMultiSiteBatchRefUpdateWithDefaultPolicyEnforcement();
-
- multiSiteRefUpdate.execute(revWalk, progressMonitor, Collections.emptyList());
- }
-
- private MultiSiteBatchRefUpdate getMultiSiteBatchRefUpdateWithDefaultPolicyEnforcement() {
- BatchRefUpdateValidator.Factory batchRefValidatorFactory =
- new BatchRefUpdateValidator.Factory() {
- @Override
- public BatchRefUpdateValidator create(String projectName, RefDatabase refDb) {
- return new BatchRefUpdateValidator(
- sharedRefDb,
- validationMetrics,
- new DefaultSharedRefEnforcement(),
- new DummyLockWrapper(),
- projectsFilter,
- projectName,
- refDb);
- }
- };
- return new MultiSiteBatchRefUpdate(batchRefValidatorFactory, A_TEST_PROJECT_NAME, refDatabase);
- }
-
- private MultiSiteBatchRefUpdate getMultiSiteBatchRefUpdateWithMockedValidator() {
- BatchRefUpdateValidator.Factory batchRefValidatorFactory =
- new BatchRefUpdateValidator.Factory() {
- @Override
- public BatchRefUpdateValidator create(String projectName, RefDatabase refDb) {
- return batchRefUpdateValidator;
- }
- };
- return new MultiSiteBatchRefUpdate(batchRefValidatorFactory, A_TEST_PROJECT_NAME, refDatabase);
- }
-
- protected static class RefMatcher implements ArgumentMatcher<Ref> {
- private Ref left;
-
- public RefMatcher(Ref ref) {
- this.left = ref;
- }
-
- @Override
- public boolean matches(Ref right) {
- return left.getName().equals(right.getName())
- && left.getObjectId().equals(right.getObjectId());
- }
- }
-}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteGitRepositoryManagerTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteGitRepositoryManagerTest.java
deleted file mode 100644
index 491ced4..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteGitRepositoryManagerTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation;
-
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.verify;
-
-import com.google.gerrit.server.git.LocalDiskRepositoryManager;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
-import org.eclipse.jgit.lib.Repository;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-
-@RunWith(MockitoJUnitRunner.class)
-public class MultiSiteGitRepositoryManagerTest implements RefFixture {
-
- @Mock LocalDiskRepositoryManager localDiskRepositoryManagerMock;
-
- @Mock MultiSiteRepository.Factory multiSiteRepositoryFactoryMock;
-
- @Mock Repository repositoryMock;
-
- @Mock MultiSiteRepository multiSiteRepositoryMock;
-
- MultiSiteGitRepositoryManager msRepoMgr;
-
- @Override
- public String testBranch() {
- return "foo";
- }
-
- @Before
- public void setUp() throws Exception {
- doReturn(multiSiteRepositoryMock)
- .when(multiSiteRepositoryFactoryMock)
- .create(A_TEST_PROJECT_NAME, repositoryMock);
- msRepoMgr =
- new MultiSiteGitRepositoryManager(
- multiSiteRepositoryFactoryMock, localDiskRepositoryManagerMock);
- }
-
- @Test
- public void openRepositoryShouldCreateMultiSiteRepositoryWrapper() throws Exception {
- doReturn(repositoryMock)
- .when(localDiskRepositoryManagerMock)
- .openRepository(A_TEST_PROJECT_NAME_KEY);
-
- msRepoMgr.openRepository(A_TEST_PROJECT_NAME_KEY);
-
- verifyThatMultiSiteRepositoryWrapperHasBeenCreated();
- }
-
- @Test
- public void createRepositoryShouldCreateMultiSiteRepositoryWrapper() throws Exception {
- doReturn(repositoryMock)
- .when(localDiskRepositoryManagerMock)
- .createRepository(A_TEST_PROJECT_NAME_KEY);
-
- msRepoMgr.createRepository(A_TEST_PROJECT_NAME_KEY);
-
- verifyThatMultiSiteRepositoryWrapperHasBeenCreated();
- }
-
- private void verifyThatMultiSiteRepositoryWrapperHasBeenCreated() {
- verify(multiSiteRepositoryFactoryMock).create(A_TEST_PROJECT_NAME, repositoryMock);
- }
-}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefDatabaseTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefDatabaseTest.java
deleted file mode 100644
index 41b83e5..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefDatabaseTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation;
-
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.verify;
-
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
-import org.eclipse.jgit.lib.RefDatabase;
-import org.eclipse.jgit.lib.RefUpdate;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TestName;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-
-@RunWith(MockitoJUnitRunner.class)
-public class MultiSiteRefDatabaseTest implements RefFixture {
-
- @Rule public TestName nameRule = new TestName();
-
- @Mock MultiSiteRefUpdate.Factory refUpdateFactoryMock;
- @Mock MultiSiteBatchRefUpdate.Factory refBatchUpdateFactoryMock;
-
- @Mock RefDatabase refDatabaseMock;
-
- @Mock RefUpdate refUpdateMock;
-
- @Override
- public String testBranch() {
- return "branch_" + nameRule.getMethodName();
- }
-
- @Test
- public void newUpdateShouldCreateMultiSiteRefUpdate() throws Exception {
- String refName = aBranchRef();
- MultiSiteRefDatabase multiSiteRefDb =
- new MultiSiteRefDatabase(
- refUpdateFactoryMock, refBatchUpdateFactoryMock, A_TEST_PROJECT_NAME, refDatabaseMock);
- doReturn(refUpdateMock).when(refDatabaseMock).newUpdate(refName, false);
-
- multiSiteRefDb.newUpdate(refName, false);
-
- verify(refUpdateFactoryMock).create(A_TEST_PROJECT_NAME, refUpdateMock, refDatabaseMock);
- }
-}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefUpdateTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefUpdateTest.java
deleted file mode 100644
index 029a4c6..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefUpdateTest.java
+++ /dev/null
@@ -1,203 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
-import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
-import com.googlesource.gerrit.plugins.multisite.validation.RefUpdateValidator.Factory;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.DefaultSharedRefEnforcement;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefUpdateStub;
-import java.io.IOException;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.ObjectIdRef;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.RefDatabase;
-import org.eclipse.jgit.lib.RefUpdate;
-import org.eclipse.jgit.lib.RefUpdate.Result;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TestName;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-
-@RunWith(MockitoJUnitRunner.class)
-@Ignore // The focus of this test suite is unclear and all tests are failing when the code is
-// working, and the other way around
-public class MultiSiteRefUpdateTest implements RefFixture {
-
- @Mock SharedRefDatabaseWrapper sharedRefDb;
- @Mock ValidationMetrics validationMetrics;
- @Mock RefDatabase refDb;
- @Mock ProjectsFilter projectsFilter;
-
- private final Ref oldRef =
- new ObjectIdRef.Unpeeled(Ref.Storage.NETWORK, A_TEST_REF_NAME, AN_OBJECT_ID_1);
- private final Ref newRef =
- new ObjectIdRef.Unpeeled(Ref.Storage.NETWORK, A_TEST_REF_NAME, AN_OBJECT_ID_2);
-
- @Rule public TestName nameRule = new TestName();
-
- @Override
- public String testBranch() {
- return "branch_" + nameRule.getMethodName();
- }
-
- @Before
- public void setup() {
- when(projectsFilter.matches(anyString())).thenReturn(true);
- }
-
- @Test
- public void newUpdateShouldValidateAndSucceed() throws Exception {
-
- doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, oldRef);
- doReturn(true)
- .when(sharedRefDb)
- .compareAndPut(A_TEST_PROJECT_NAME_KEY, oldRef, newRef.getObjectId());
-
- RefUpdate refUpdate = RefUpdateStub.forSuccessfulUpdate(oldRef, newRef.getObjectId());
-
- MultiSiteRefUpdate multiSiteRefUpdate =
- getMultiSiteRefUpdateWithDefaultPolicyEnforcement(refUpdate);
-
- assertThat(multiSiteRefUpdate.update()).isEqualTo(Result.FAST_FORWARD);
- verifyZeroInteractions(validationMetrics);
- }
-
- @Test(expected = Exception.class)
- public void newUpdateShouldValidateAndFailWithIOException() throws Exception {
-
- doReturn(false).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, oldRef);
-
- RefUpdate refUpdate = RefUpdateStub.forSuccessfulUpdate(oldRef, newRef.getObjectId());
-
- MultiSiteRefUpdate multiSiteRefUpdate =
- getMultiSiteRefUpdateWithDefaultPolicyEnforcement(refUpdate);
- multiSiteRefUpdate.update();
- }
-
- @Test
- public void newUpdateShouldIncreaseRefUpdateFailureCountWhenFailing() {
-
- doReturn(false).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, oldRef);
-
- RefUpdate refUpdate = RefUpdateStub.forSuccessfulUpdate(oldRef, newRef.getObjectId());
-
- MultiSiteRefUpdate multiSiteRefUpdate =
- getMultiSiteRefUpdateWithDefaultPolicyEnforcement(refUpdate);
-
- assertThrows(IOException.class, () -> multiSiteRefUpdate.update());
- verify(validationMetrics).incrementSplitBrainPrevention();
- }
-
- @Test
- public void newUpdateShouldNotIncreaseSplitBrainPreventedCounterIfFailingSharedDbPostUpdate() {
-
- doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, oldRef);
- doReturn(false)
- .when(sharedRefDb)
- .compareAndPut(A_TEST_PROJECT_NAME_KEY, oldRef, newRef.getObjectId());
-
- RefUpdate refUpdate = RefUpdateStub.forSuccessfulUpdate(oldRef, newRef.getObjectId());
-
- MultiSiteRefUpdate multiSiteRefUpdate =
- getMultiSiteRefUpdateWithDefaultPolicyEnforcement(refUpdate);
-
- assertThrows(IOException.class, () -> multiSiteRefUpdate.update());
- verify(validationMetrics, never()).incrementSplitBrainPrevention();
- }
-
- @Test
- public void newUpdateShouldtIncreaseSplitBrainCounterIfFailingSharedDbPostUpdate() {
-
- doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, oldRef);
- doReturn(false)
- .when(sharedRefDb)
- .compareAndPut(A_TEST_PROJECT_NAME_KEY, oldRef, newRef.getObjectId());
-
- RefUpdate refUpdate = RefUpdateStub.forSuccessfulUpdate(oldRef, newRef.getObjectId());
-
- MultiSiteRefUpdate multiSiteRefUpdate =
- getMultiSiteRefUpdateWithDefaultPolicyEnforcement(refUpdate);
-
- assertThrows(IOException.class, () -> multiSiteRefUpdate.update());
- verify(validationMetrics).incrementSplitBrain();
- }
-
- @Test
- public void deleteShouldValidateAndSucceed() throws IOException {
- doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, oldRef);
-
- doReturn(true)
- .when(sharedRefDb)
- .compareAndPut(A_TEST_PROJECT_NAME_KEY, oldRef, ObjectId.zeroId());
-
- RefUpdate refUpdate = RefUpdateStub.forSuccessfulDelete(oldRef);
-
- MultiSiteRefUpdate multiSiteRefUpdate =
- getMultiSiteRefUpdateWithDefaultPolicyEnforcement(refUpdate);
-
- assertThat(multiSiteRefUpdate.delete()).isEqualTo(Result.FORCED);
- verifyZeroInteractions(validationMetrics);
- }
-
- @Test
- public void deleteShouldIncreaseRefUpdateFailureCountWhenFailing() {
-
- doReturn(false).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, oldRef);
-
- RefUpdate refUpdate = RefUpdateStub.forSuccessfulDelete(oldRef);
-
- MultiSiteRefUpdate multiSiteRefUpdate =
- getMultiSiteRefUpdateWithDefaultPolicyEnforcement(refUpdate);
-
- assertThrows(IOException.class, () -> multiSiteRefUpdate.delete());
- verify(validationMetrics).incrementSplitBrainPrevention();
- }
-
- private MultiSiteRefUpdate getMultiSiteRefUpdateWithDefaultPolicyEnforcement(
- RefUpdate refUpdate) {
- Factory batchRefValidatorFactory =
- new Factory() {
- @Override
- public RefUpdateValidator create(String projectName, RefDatabase refDb) {
- RefUpdateValidator RefUpdateValidator =
- new RefUpdateValidator(
- sharedRefDb,
- validationMetrics,
- new DefaultSharedRefEnforcement(),
- new DummyLockWrapper(),
- projectsFilter,
- projectName,
- refDb);
- return RefUpdateValidator;
- }
- };
- return new MultiSiteRefUpdate(batchRefValidatorFactory, A_TEST_PROJECT_NAME, refUpdate, refDb);
- }
-}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRepositoryTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRepositoryTest.java
deleted file mode 100644
index 15c596f..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRepositoryTest.java
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.verify;
-
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
-import java.io.IOException;
-import org.eclipse.jgit.lib.RefDatabase;
-import org.eclipse.jgit.lib.RefUpdate.Result;
-import org.eclipse.jgit.lib.Repository;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-
-@RunWith(MockitoJUnitRunner.class)
-public class MultiSiteRepositoryTest implements RefFixture {
-
- @Mock MultiSiteRefDatabase.Factory multiSiteRefDbFactory;
- @Mock MultiSiteRefDatabase multiSiteRefDb;
- @Mock RefDatabase genericRefDb;
-
- @Mock MultiSiteRefUpdate multiSiteRefUpdate;
-
- @Mock Repository repository;
-
- private final String PROJECT_NAME = "ProjectName";
- private final String REFS_HEADS_MASTER = "refs/heads/master";
-
- @Override
- public String testBranch() {
- return null;
- }
-
- private void setMockitoCommon() {
- doReturn(genericRefDb).when(repository).getRefDatabase();
- doReturn(multiSiteRefDb).when(multiSiteRefDbFactory).create(PROJECT_NAME, genericRefDb);
- }
-
- @Test
- public void shouldInvokeMultiSiteRefDbFactoryCreate() {
- setMockitoCommon();
- try (MultiSiteRepository multiSiteRepository =
- new MultiSiteRepository(multiSiteRefDbFactory, PROJECT_NAME, repository)) {
-
- multiSiteRepository.getRefDatabase();
- verify(multiSiteRefDbFactory).create(PROJECT_NAME, genericRefDb);
- }
- }
-
- @Test
- public void shouldInvokeNewUpdateInMultiSiteRefDatabase() throws IOException {
- setMockitoCommon();
- try (MultiSiteRepository multiSiteRepository =
- new MultiSiteRepository(multiSiteRefDbFactory, PROJECT_NAME, repository)) {
- multiSiteRepository.getRefDatabase().newUpdate(REFS_HEADS_MASTER, false);
-
- verify(multiSiteRefDb).newUpdate(REFS_HEADS_MASTER, false);
- }
- }
-
- @Test
- public void shouldInvokeUpdateInMultiSiteRefUpdate() throws IOException {
- setMockitoCommon();
- doReturn(Result.NEW).when(multiSiteRefUpdate).update();
- doReturn(multiSiteRefUpdate).when(multiSiteRefDb).newUpdate(REFS_HEADS_MASTER, false);
-
- try (MultiSiteRepository multiSiteRepository =
- new MultiSiteRepository(multiSiteRefDbFactory, PROJECT_NAME, repository)) {
-
- Result updateResult =
- multiSiteRepository.getRefDatabase().newUpdate(REFS_HEADS_MASTER, false).update();
-
- verify(multiSiteRefUpdate).update();
- assertThat(updateResult).isEqualTo(Result.NEW);
- }
- }
-}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectDeletedSharedDbCleanupTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectDeletedSharedDbCleanupTest.java
deleted file mode 100644
index ba381a4..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectDeletedSharedDbCleanupTest.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.googlesource.gerrit.plugins.multisite.validation;
-
-import com.google.gerrit.extensions.api.changes.NotifyHandling;
-import com.google.gerrit.extensions.events.ProjectDeletedListener;
-import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TestName;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.junit.MockitoJUnitRunner;
-
-@RunWith(MockitoJUnitRunner.class)
-public class ProjectDeletedSharedDbCleanupTest implements RefFixture {
- @Rule public TestName nameRule = new TestName();
-
- @Mock ValidationMetrics mockValidationMetrics;
- @Mock SharedRefDatabaseWrapper sharedRefDatabase;
-
- @Test
- public void aDeleteProjectEventShouldCleanupProjectFromZk() throws Exception {
- String projectName = A_TEST_PROJECT_NAME;
- ProjectDeletedSharedDbCleanup projectDeletedSharedDbCleanup =
- new ProjectDeletedSharedDbCleanup(sharedRefDatabase, mockValidationMetrics);
-
- ProjectDeletedListener.Event event =
- new ProjectDeletedListener.Event() {
- @Override
- public String getProjectName() {
- return projectName;
- }
-
- @Override
- public NotifyHandling getNotify() {
- return NotifyHandling.NONE;
- }
- };
-
- projectDeletedSharedDbCleanup.onProjectDeleted(event);
-
- Mockito.verify(sharedRefDatabase, Mockito.times(1)).remove(A_TEST_PROJECT_NAME_KEY);
- }
-}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdateTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdateTest.java
index d437a73..917c6bf 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdateTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdateTest.java
@@ -24,6 +24,8 @@
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
+import com.gerritforge.gerrit.globalrefdb.validation.ProjectsFilter;
+import com.gerritforge.gerrit.globalrefdb.validation.SharedRefDatabaseWrapper;
import com.google.gerrit.entities.Project;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.server.events.Event;
@@ -34,14 +36,13 @@
import com.google.gerrit.testing.InMemoryTestEnvironment;
import com.google.inject.Inject;
import com.googlesource.gerrit.plugins.multisite.ProjectVersionLogger;
-import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
-import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
-import org.apache.commons.io.IOUtils;
+import org.eclipse.jgit.errors.LargeObjectException;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.ObjectId;
@@ -121,8 +122,7 @@
assertThat(ref).isNotNull();
ObjectLoader loader = repo.getRepository().open(ref.getObjectId());
- long storedVersion =
- Long.parseLong(IOUtils.toString(loader.openStream(), StandardCharsets.UTF_8.name()));
+ long storedVersion = readLongObject(loader);
assertThat(storedVersion).isGreaterThan((long) masterCommit.getCommitTime());
verify(verLogger).log(A_TEST_PROJECT_NAME_KEY, storedVersion, 0);
@@ -167,8 +167,7 @@
assertThat(ref).isNotNull();
ObjectLoader loader = repo.getRepository().open(ref.getObjectId());
- long storedVersion =
- Long.parseLong(IOUtils.toString(loader.openStream(), StandardCharsets.UTF_8.name()));
+ long storedVersion = readLongObject(loader);
assertThat(storedVersion).isGreaterThan((long) masterPlusOneCommit.getCommitTime());
verify(verLogger).log(A_TEST_PROJECT_NAME_KEY, storedVersion, 0);
@@ -208,8 +207,7 @@
assertThat(ref).isNotNull();
ObjectLoader loader = repo.getRepository().open(ref.getObjectId());
- long storedVersion =
- Long.parseLong(IOUtils.toString(loader.openStream(), StandardCharsets.UTF_8.name()));
+ long storedVersion = readLongObject(loader);
assertThat(storedVersion).isGreaterThan((long) masterCommit.getCommitTime());
verify(verLogger).log(A_TEST_PROJECT_NAME_KEY, storedVersion, 0);
@@ -226,6 +224,12 @@
producerShouldNotUpdateProjectVersionUponMagicRefUpdatedEvent(RefNames.REFS_STARRED_CHANGES);
}
+ private long readLongObject(ObjectLoader loader)
+ throws LargeObjectException, UnsupportedEncodingException {
+ String boutString = new String(loader.getBytes(), StandardCharsets.UTF_8.name());
+ return Long.parseLong(boutString);
+ }
+
private void producerShouldNotUpdateProjectVersionUponMagicRefUpdatedEvent(String magicRefPrefix)
throws Exception {
String magicRefName = magicRefPrefix + "/foo";
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidatorTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidatorTest.java
deleted file mode 100644
index b9b07bd..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidatorTest.java
+++ /dev/null
@@ -1,244 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.lenient;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import com.google.gerrit.entities.Project;
-import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
-import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
-import com.googlesource.gerrit.plugins.multisite.SharedRefLogger;
-import com.googlesource.gerrit.plugins.multisite.validation.RefUpdateValidator.OneParameterFunction;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.DefaultSharedRefEnforcement;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.RefDatabase;
-import org.eclipse.jgit.lib.RefUpdate;
-import org.eclipse.jgit.lib.RefUpdate.Result;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-
-@RunWith(MockitoJUnitRunner.class)
-public class RefUpdateValidatorTest implements RefFixture {
- private static final DefaultSharedRefEnforcement defaultRefEnforcement =
- new DefaultSharedRefEnforcement();
-
- @Mock SharedRefDatabaseWrapper sharedRefDb;
-
- @Mock SharedRefLogger sharedRefLogger;
-
- @Mock RefDatabase localRefDb;
-
- @Mock ValidationMetrics validationMetrics;
-
- @Mock RefUpdate refUpdate;
-
- @Mock ProjectsFilter projectsFilter;
-
- @Mock OneParameterFunction<ObjectId, Result> rollbackFunction;
-
- String refName;
- Ref oldUpdateRef;
- Ref newUpdateRef;
- Ref localRef;
-
- RefUpdateValidator refUpdateValidator;
-
- @Before
- public void setupMocks() throws Exception {
- refName = aBranchRef();
- oldUpdateRef = newRef(refName, AN_OBJECT_ID_1);
- newUpdateRef = newRef(refName, AN_OBJECT_ID_2);
- localRef = newRef(refName, AN_OBJECT_ID_3);
-
- doReturn(localRef).when(localRefDb).findRef(refName);
- doReturn(localRef).when(localRefDb).exactRef(refName);
- doReturn(newUpdateRef.getObjectId()).when(refUpdate).getNewObjectId();
- doReturn(refName).when(refUpdate).getName();
- lenient().doReturn(oldUpdateRef.getObjectId()).when(refUpdate).getOldObjectId();
- doReturn(Result.FAST_FORWARD).when(rollbackFunction).invoke(any());
-
- doReturn(true).when(projectsFilter).matches(anyString());
-
- refUpdateValidator = newRefUpdateValidator(sharedRefDb);
- }
-
- @Test
- public void validationShouldSucceedWhenSharedRefDbIsNoop() throws Exception {
- SharedRefDatabaseWrapper noopSharedRefDbWrapper = new SharedRefDatabaseWrapper(sharedRefLogger);
-
- Result result =
- newRefUpdateValidator(noopSharedRefDbWrapper)
- .executeRefUpdate(refUpdate, () -> RefUpdate.Result.NEW, this::defaultRollback);
- assertThat(result).isEqualTo(RefUpdate.Result.NEW);
- }
-
- @Test
- public void validationShouldSucceedWhenLocalRefDbIsUpToDate() throws Exception {
- lenient()
- .doReturn(false)
- .when(sharedRefDb)
- .isUpToDate(any(Project.NameKey.class), any(Ref.class));
- doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, localRef);
- lenient()
- .doReturn(false)
- .when(sharedRefDb)
- .compareAndPut(any(Project.NameKey.class), any(Ref.class), any(ObjectId.class));
- doReturn(true)
- .when(sharedRefDb)
- .compareAndPut(A_TEST_PROJECT_NAME_KEY, localRef, newUpdateRef.getObjectId());
-
- Result result =
- refUpdateValidator.executeRefUpdate(
- refUpdate, () -> RefUpdate.Result.NEW, this::defaultRollback);
-
- assertThat(result).isEqualTo(RefUpdate.Result.NEW);
- }
-
- @Test
- public void sharedRefDbShouldBeUpdatedWithRefDeleted() throws Exception {
- doReturn(ObjectId.zeroId()).when(refUpdate).getNewObjectId();
- doReturn(true).when(sharedRefDb).isUpToDate(any(Project.NameKey.class), any(Ref.class));
- lenient()
- .doReturn(false)
- .when(sharedRefDb)
- .compareAndPut(any(Project.NameKey.class), any(Ref.class), any(ObjectId.class));
- doReturn(true)
- .when(sharedRefDb)
- .compareAndPut(A_TEST_PROJECT_NAME_KEY, localRef, ObjectId.zeroId());
- doReturn(localRef).doReturn(null).when(localRefDb).findRef(refName);
-
- Result result =
- refUpdateValidator.executeRefUpdate(
- refUpdate, () -> RefUpdate.Result.FORCED, this::defaultRollback);
-
- assertThat(result).isEqualTo(RefUpdate.Result.FORCED);
- }
-
- @Test
- public void sharedRefDbShouldBeUpdatedWithNewRefCreated() throws Exception {
- Ref localNullRef = nullRef(refName);
-
- doReturn(true).when(sharedRefDb).isUpToDate(any(Project.NameKey.class), any(Ref.class));
- lenient()
- .doReturn(false)
- .when(sharedRefDb)
- .compareAndPut(any(Project.NameKey.class), any(Ref.class), any(ObjectId.class));
- doReturn(true)
- .when(sharedRefDb)
- .compareAndPut(A_TEST_PROJECT_NAME_KEY, localNullRef, newUpdateRef.getObjectId());
- doReturn(localNullRef).doReturn(newUpdateRef).when(localRefDb).findRef(refName);
-
- Result result =
- refUpdateValidator.executeRefUpdate(
- refUpdate, () -> RefUpdate.Result.NEW, this::defaultRollback);
-
- assertThat(result).isEqualTo(RefUpdate.Result.NEW);
- }
-
- @Test
- public void validationShouldFailWhenLocalRefDbIsOutOfSync() throws Exception {
- lenient()
- .doReturn(true)
- .when(sharedRefDb)
- .isUpToDate(any(Project.NameKey.class), any(Ref.class));
- doReturn(true).when(sharedRefDb).exists(A_TEST_PROJECT_NAME_KEY, refName);
- doReturn(false).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, localRef);
-
- Result result =
- refUpdateValidator.executeRefUpdate(
- refUpdate, () -> RefUpdate.Result.NEW, this::defaultRollback);
-
- assertThat(result).isEqualTo(Result.LOCK_FAILURE);
- }
-
- @Test
- public void shouldRollbackWhenLocalRefDbIsUpToDateButFinalCompareAndPutIsFailing()
- throws Exception {
- lenient()
- .doReturn(false)
- .when(sharedRefDb)
- .isUpToDate(any(Project.NameKey.class), any(Ref.class));
- doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, localRef);
- lenient()
- .doReturn(true)
- .when(sharedRefDb)
- .compareAndPut(any(Project.NameKey.class), any(Ref.class), any(ObjectId.class));
- doReturn(false)
- .when(sharedRefDb)
- .compareAndPut(A_TEST_PROJECT_NAME_KEY, localRef, newUpdateRef.getObjectId());
-
- Result result =
- refUpdateValidator.executeRefUpdate(refUpdate, () -> Result.NEW, rollbackFunction);
-
- verify(rollbackFunction, times(1)).invoke(any());
- assertThat(result).isEqualTo(Result.LOCK_FAILURE);
- }
-
- @Test
- public void shouldNotUpdateSharedRefDbWhenFinalCompareAndPutIsFailing() throws Exception {
- lenient()
- .doReturn(false)
- .when(sharedRefDb)
- .isUpToDate(any(Project.NameKey.class), any(Ref.class));
- doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, localRef);
-
- Result result =
- refUpdateValidator.executeRefUpdate(
- refUpdate, () -> Result.LOCK_FAILURE, this::defaultRollback);
-
- verify(sharedRefDb, never())
- .compareAndPut(any(Project.NameKey.class), any(Ref.class), any(ObjectId.class));
- assertThat(result).isEqualTo(RefUpdate.Result.LOCK_FAILURE);
- }
-
- @Test
- public void shouldNotUpdateSharedRefDbWhenProjectIsLocal() throws Exception {
- when(projectsFilter.matches(anyString())).thenReturn(false);
-
- refUpdateValidator.executeRefUpdate(
- refUpdate, () -> RefUpdate.Result.NEW, this::defaultRollback);
-
- verify(sharedRefDb, never())
- .compareAndPut(any(Project.NameKey.class), any(Ref.class), any(ObjectId.class));
- }
-
- private RefUpdateValidator newRefUpdateValidator(SharedRefDatabaseWrapper refDbWrapper) {
- return new RefUpdateValidator(
- refDbWrapper,
- validationMetrics,
- defaultRefEnforcement,
- new DummyLockWrapper(),
- projectsFilter,
- A_TEST_PROJECT_NAME,
- localRefDb);
- }
-
- private Result defaultRollback(ObjectId objectId) {
- return Result.NO_CHANGE;
- }
-}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/CustomSharedRefEnforcementByProjectTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/CustomSharedRefEnforcementByProjectTest.java
deleted file mode 100644
index f3008a2..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/CustomSharedRefEnforcementByProjectTest.java
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation.dfsrefdb;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.googlesource.gerrit.plugins.multisite.Configuration;
-import com.googlesource.gerrit.plugins.multisite.Configuration.SharedRefDatabase;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement.EnforcePolicy;
-import java.util.Arrays;
-import org.eclipse.jgit.lib.Config;
-import org.eclipse.jgit.lib.Ref;
-import org.junit.Before;
-import org.junit.Test;
-
-public class CustomSharedRefEnforcementByProjectTest implements RefFixture {
-
- SharedRefEnforcement refEnforcement;
-
- @Before
- public void setUp() {
- Config sharedRefDbConfig = new Config();
- sharedRefDbConfig.setStringList(
- SharedRefDatabase.SECTION,
- SharedRefDatabase.SUBSECTION_ENFORCEMENT_RULES,
- EnforcePolicy.IGNORED.name(),
- Arrays.asList(
- "ProjectOne",
- "ProjectTwo:refs/heads/master/test",
- "ProjectTwo:refs/heads/master/test2"));
-
- refEnforcement = newCustomRefEnforcement(sharedRefDbConfig);
- }
-
- @Test
- public void projectOneShouldReturnDesiredForAllRefs() {
- Ref aRef = newRef("refs/heads/master/2", AN_OBJECT_ID_1);
- assertThat(refEnforcement.getPolicy("ProjectOne", aRef.getName()))
- .isEqualTo(EnforcePolicy.IGNORED);
- }
-
- @Test
- public void projectOneEnforcementShouldAlwaysPrevail() {
- Ref aRef = newRef("refs/heads/master/test", AN_OBJECT_ID_1);
- assertThat(refEnforcement.getPolicy("ProjectOne", aRef.getName()))
- .isEqualTo(EnforcePolicy.IGNORED);
- }
-
- @Test
- public void aNonListedProjectShouldRequireRefForMasterTest() {
- Ref aRef = newRef("refs/heads/master/test", AN_OBJECT_ID_1);
- assertThat(refEnforcement.getPolicy("NonListedProject", aRef.getName()))
- .isEqualTo(EnforcePolicy.REQUIRED);
- }
-
- @Test
- public void projectTwoSpecificRefShouldReturnIgnoredPolicy() {
- Ref refOne = newRef("refs/heads/master/test", AN_OBJECT_ID_1);
- Ref refTwo = newRef("refs/heads/master/test2", AN_OBJECT_ID_1);
-
- assertThat(refEnforcement.getPolicy("ProjectTwo", refOne.getName()))
- .isEqualTo(EnforcePolicy.IGNORED);
- assertThat(refEnforcement.getPolicy("ProjectTwo", refTwo.getName()))
- .isEqualTo(EnforcePolicy.IGNORED);
- }
-
- @Test
- public void aNonListedProjectShouldReturnRequired() {
- Ref refOne = newRef("refs/heads/master/newChange", AN_OBJECT_ID_1);
- assertThat(refEnforcement.getPolicy("NonListedProject", refOne.getName()))
- .isEqualTo(EnforcePolicy.REQUIRED);
- }
-
- @Test
- public void aNonListedRefInProjectShouldReturnRequired() {
- Ref refOne = newRef("refs/heads/master/test3", AN_OBJECT_ID_1);
- assertThat(refEnforcement.getPolicy("ProjectTwo", refOne.getName()))
- .isEqualTo(EnforcePolicy.REQUIRED);
- }
-
- @Test
- public void aNonListedProjectAndRefShouldReturnRequired() {
- Ref refOne = newRef("refs/heads/master/test3", AN_OBJECT_ID_1);
- assertThat(refEnforcement.getPolicy("NonListedProject", refOne.getName()))
- .isEqualTo(EnforcePolicy.REQUIRED);
- }
-
- @Test
- public void getProjectPolicyForProjectOneShouldReturnIgnored() {
- assertThat(refEnforcement.getPolicy("ProjectOne")).isEqualTo(EnforcePolicy.IGNORED);
- }
-
- @Test
- public void getProjectPolicyForProjectTwoShouldReturnRequired() {
- assertThat(refEnforcement.getPolicy("ProjectTwo")).isEqualTo(EnforcePolicy.REQUIRED);
- }
-
- @Test
- public void getProjectPolicyForNonListedProjectShouldReturnRequired() {
- assertThat(refEnforcement.getPolicy("NonListedProject")).isEqualTo(EnforcePolicy.REQUIRED);
- }
-
- @Test
- public void getProjectPolicyForNonListedProjectWhenSingleProject() {
- SharedRefEnforcement customEnforcement =
- newCustomRefEnforcementWithValue(EnforcePolicy.IGNORED, ":refs/heads/master");
-
- assertThat(customEnforcement.getPolicy("NonListedProject")).isEqualTo(EnforcePolicy.REQUIRED);
- }
-
- @Test
- public void getANonListedProjectWhenOnlyOneProjectIsListedShouldReturnRequired() {
- SharedRefEnforcement customEnforcement =
- newCustomRefEnforcementWithValue(EnforcePolicy.IGNORED, "AProject:");
- assertThat(customEnforcement.getPolicy("NonListedProject", "refs/heads/master"))
- .isEqualTo(EnforcePolicy.REQUIRED);
- }
-
- private SharedRefEnforcement newCustomRefEnforcementWithValue(
- EnforcePolicy policy, String... projectAndRefs) {
- Config sharedRefDbConfiguration = new Config();
- sharedRefDbConfiguration.setStringList(
- SharedRefDatabase.SECTION,
- SharedRefDatabase.SUBSECTION_ENFORCEMENT_RULES,
- policy.name(),
- Arrays.asList(projectAndRefs));
- return newCustomRefEnforcement(sharedRefDbConfiguration);
- }
-
- private SharedRefEnforcement newCustomRefEnforcement(Config sharedRefDbConfig) {
- return new CustomSharedRefEnforcementByProject(
- new Configuration(sharedRefDbConfig, new Config()));
- }
-
- @Override
- public String testBranch() {
- return "fooBranch";
- }
-}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/DefaultSharedRefEnforcementTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/DefaultSharedRefEnforcementTest.java
deleted file mode 100644
index 2964e15..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/DefaultSharedRefEnforcementTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation.dfsrefdb;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement.EnforcePolicy;
-import org.eclipse.jgit.lib.Ref;
-import org.junit.Test;
-
-public class DefaultSharedRefEnforcementTest implements RefFixture {
-
- SharedRefEnforcement refEnforcement = new DefaultSharedRefEnforcement();
-
- @Test
- public void anImmutableChangeShouldBeIgnored() {
- Ref immutableChangeRef = newRef(A_REF_NAME_OF_A_PATCHSET, AN_OBJECT_ID_1);
- assertThat(refEnforcement.getPolicy(A_TEST_PROJECT_NAME, immutableChangeRef.getName()))
- .isEqualTo(EnforcePolicy.IGNORED);
- }
-
- @Test
- public void aChangeMetaShouldNotBeIgnored() {
- Ref immutableChangeRef = newRef("refs/changes/01/1/meta", AN_OBJECT_ID_1);
- assertThat(refEnforcement.getPolicy(A_TEST_PROJECT_NAME, immutableChangeRef.getName()))
- .isEqualTo(EnforcePolicy.REQUIRED);
- }
-
- @Test
- public void aCacheAutomergeShouldBeIgnored() {
- Ref immutableChangeRef = newRef("refs/cache-automerge/01/1/1000000", AN_OBJECT_ID_1);
- assertThat(refEnforcement.getPolicy(A_TEST_PROJECT_NAME, immutableChangeRef.getName()))
- .isEqualTo(EnforcePolicy.IGNORED);
- }
-
- @Test
- public void aDraftCommentsShouldBeIgnored() {
- Ref immutableChangeRef = newRef("refs/draft-comments/01/1/1000000", AN_OBJECT_ID_1);
- assertThat(refEnforcement.getPolicy(A_TEST_PROJECT_NAME, immutableChangeRef.getName()))
- .isEqualTo(EnforcePolicy.IGNORED);
- }
-
- @Test
- public void regularRefHeadsMasterShouldNotBeIgnored() {
- Ref immutableChangeRef = newRef("refs/heads/master", AN_OBJECT_ID_1);
- assertThat(refEnforcement.getPolicy(A_TEST_PROJECT_NAME, immutableChangeRef.getName()))
- .isEqualTo(EnforcePolicy.REQUIRED);
- }
-
- @Test
- public void regularCommitShouldNotBeIgnored() {
- Ref immutableChangeRef = newRef("refs/heads/stable-2.16", AN_OBJECT_ID_1);
- assertThat(refEnforcement.getPolicy(A_TEST_PROJECT_NAME, immutableChangeRef.getName()))
- .isEqualTo(EnforcePolicy.REQUIRED);
- }
-
- @Test
- public void allUsersExternalIdsRefShouldBeRequired() {
- Ref refOne = newRef("refs/meta/external-ids", AN_OBJECT_ID_1);
- assertThat(refEnforcement.getPolicy("All-Users", refOne.getName()))
- .isEqualTo(EnforcePolicy.REQUIRED);
- }
-
- @Override
- public String testBranch() {
- return "fooBranch";
- }
-}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/MultisiteReplicationPushFilterTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/MultisiteReplicationPushFilterTest.java
deleted file mode 100644
index f2b57a1..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/MultisiteReplicationPushFilterTest.java
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation.dfsrefdb;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import com.gerritforge.gerrit.globalrefdb.GlobalRefDatabase;
-import com.gerritforge.gerrit.globalrefdb.GlobalRefDbLockException;
-import com.gerritforge.gerrit.globalrefdb.GlobalRefDbSystemError;
-import com.google.gerrit.entities.Project;
-import com.google.gerrit.extensions.registration.DynamicItem;
-import com.google.gerrit.testing.InMemoryRepositoryManager;
-import com.google.gerrit.testing.InMemoryTestEnvironment;
-import com.google.inject.Inject;
-import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
-import com.googlesource.gerrit.plugins.multisite.validation.DisabledSharedRefLogger;
-import com.googlesource.gerrit.plugins.multisite.validation.MultisiteReplicationPushFilter;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
-import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
-import org.eclipse.jgit.junit.TestRepository;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.ObjectIdRef;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.transport.RemoteRefUpdate;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-
-@RunWith(MockitoJUnitRunner.class)
-public class MultisiteReplicationPushFilterTest extends LocalDiskRepositoryTestCase
- implements RefFixture {
-
- @Rule public InMemoryTestEnvironment testEnvironment = new InMemoryTestEnvironment();
-
- @Mock SharedRefDatabaseWrapper sharedRefDatabaseMock;
-
- @Inject private InMemoryRepositoryManager gitRepositoryManager;
-
- String project = A_TEST_PROJECT_NAME;
- Project.NameKey projectName = A_TEST_PROJECT_NAME_KEY;
-
- private TestRepository<InMemoryRepository> repo;
-
- @Before
- public void setupTestRepo() throws Exception {
- InMemoryRepository inMemoryRepo =
- gitRepositoryManager.createRepository(A_TEST_PROJECT_NAME_KEY);
- repo = new TestRepository<>(inMemoryRepo);
- }
-
- @Test
- public void shouldReturnAllRefUpdatesWhenAllUpToDate() throws Exception {
- List<RemoteRefUpdate> refUpdates =
- Arrays.asList(refUpdate("refs/heads/foo"), refUpdate("refs/heads/bar"));
- doReturn(true).when(sharedRefDatabaseMock).isUpToDate(eq(projectName), any());
-
- MultisiteReplicationPushFilter pushFilter =
- new MultisiteReplicationPushFilter(sharedRefDatabaseMock, gitRepositoryManager);
- List<RemoteRefUpdate> filteredRefUpdates = pushFilter.filter(project, refUpdates);
-
- assertThat(filteredRefUpdates).containsExactlyElementsIn(refUpdates);
- }
-
- @Test
- public void shouldFilterOutOneOutdatedRef() throws Exception {
- RemoteRefUpdate refUpToDate = refUpdate("refs/heads/uptodate");
- RemoteRefUpdate outdatedRef = refUpdate("refs/heads/outdated");
- List<RemoteRefUpdate> refUpdates = Arrays.asList(refUpToDate, outdatedRef);
- SharedRefDatabaseWrapper sharedRefDatabase = newSharedRefDatabase(outdatedRef.getSrcRef());
-
- MultisiteReplicationPushFilter pushFilter =
- new MultisiteReplicationPushFilter(sharedRefDatabase, gitRepositoryManager);
- List<RemoteRefUpdate> filteredRefUpdates = pushFilter.filter(project, refUpdates);
-
- assertThat(filteredRefUpdates).containsExactly(refUpToDate);
- }
-
- @Test
- public void shouldLoadLocalVersionAndNotFilter() throws Exception {
- RemoteRefUpdate temporaryOutdated = refUpdate("refs/heads/temporaryOutdated");
- List<RemoteRefUpdate> refUpdates = Collections.singletonList(temporaryOutdated);
- doReturn(false).doReturn(true).when(sharedRefDatabaseMock).isUpToDate(eq(projectName), any());
-
- MultisiteReplicationPushFilter pushFilter =
- new MultisiteReplicationPushFilter(sharedRefDatabaseMock, gitRepositoryManager);
- List<RemoteRefUpdate> filteredRefUpdates = pushFilter.filter(project, refUpdates);
-
- assertThat(filteredRefUpdates).containsExactly(temporaryOutdated);
- verify(sharedRefDatabaseMock, times(2)).isUpToDate(any(), any());
- }
-
- @Test
- public void shouldLoadLocalVersionAndFilter() throws Exception {
- RemoteRefUpdate temporaryOutdated = refUpdate("refs/heads/temporaryOutdated");
- repo.branch("refs/heads/temporaryOutdated").commit().create();
- List<RemoteRefUpdate> refUpdates = Collections.singletonList(temporaryOutdated);
- doReturn(false).doReturn(false).when(sharedRefDatabaseMock).isUpToDate(eq(projectName), any());
-
- MultisiteReplicationPushFilter pushFilter =
- new MultisiteReplicationPushFilter(sharedRefDatabaseMock, gitRepositoryManager);
- List<RemoteRefUpdate> filteredRefUpdates = pushFilter.filter(project, refUpdates);
-
- assertThat(filteredRefUpdates).isEmpty();
- verify(sharedRefDatabaseMock, times(2)).isUpToDate(any(), any());
- }
-
- @Test
- public void shouldFilterOutAllOutdatedChangesRef() throws Exception {
- RemoteRefUpdate refUpToDate = refUpdate("refs/heads/uptodate");
- RemoteRefUpdate refChangeUpToDate = refUpdate("refs/changes/25/1225/2");
- RemoteRefUpdate changeMetaRef = refUpdate("refs/changes/12/4512/meta");
- RemoteRefUpdate changeRef = refUpdate("refs/changes/12/4512/1");
- List<RemoteRefUpdate> refUpdates =
- Arrays.asList(refUpToDate, refChangeUpToDate, changeMetaRef, changeRef);
- SharedRefDatabaseWrapper sharedRefDatabase = newSharedRefDatabase(changeMetaRef.getSrcRef());
-
- MultisiteReplicationPushFilter pushFilter =
- new MultisiteReplicationPushFilter(sharedRefDatabase, gitRepositoryManager);
- List<RemoteRefUpdate> filteredRefUpdates = pushFilter.filter(project, refUpdates);
-
- assertThat(filteredRefUpdates).containsExactly(refUpToDate, refChangeUpToDate);
- }
-
- private SharedRefDatabaseWrapper newSharedRefDatabase(String... rejectedRefs) {
- Set<String> rejectedSet = new HashSet<>();
- rejectedSet.addAll(Arrays.asList(rejectedRefs));
-
- GlobalRefDatabase sharedRefDatabase =
- new GlobalRefDatabase() {
-
- @Override
- public boolean isUpToDate(Project.NameKey project, Ref ref)
- throws GlobalRefDbLockException {
- return !rejectedSet.contains(ref.getName());
- }
-
- @Override
- public boolean exists(Project.NameKey project, String refName) {
- return true;
- }
-
- @Override
- public boolean compareAndPut(Project.NameKey project, Ref currRef, ObjectId newRefValue)
- throws GlobalRefDbSystemError {
- return false;
- }
-
- @Override
- public <T> boolean compareAndPut(
- Project.NameKey project, String refName, T currValue, T newValue)
- throws GlobalRefDbSystemError {
- return false;
- }
-
- @Override
- public AutoCloseable lockRef(Project.NameKey project, String refName)
- throws GlobalRefDbLockException {
- return null;
- }
-
- @Override
- public void remove(Project.NameKey project) throws GlobalRefDbSystemError {}
-
- @Override
- public <T> Optional<T> get(Project.NameKey project, String refName, Class<T> clazz)
- throws GlobalRefDbSystemError {
- return Optional.empty();
- }
- };
- return new SharedRefDatabaseWrapper(
- DynamicItem.itemOf(GlobalRefDatabase.class, sharedRefDatabase),
- new DisabledSharedRefLogger());
- }
-
- private RemoteRefUpdate refUpdate(String refName) throws Exception {
- ObjectId srcObjId = ObjectId.fromString("0000000000000000000000000000000000000001");
- Ref srcRef = new ObjectIdRef.Unpeeled(Ref.Storage.NEW, refName, srcObjId);
- repo.branch(refName).commit().create();
- return new RemoteRefUpdate(null, srcRef, "origin", false, "origin", srcObjId);
- }
-}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/NoopSharedRefDatabaseTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/NoopSharedRefDatabaseTest.java
deleted file mode 100644
index c63530a..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/NoopSharedRefDatabaseTest.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.eclipse.jgit.lib.Ref;
-import org.junit.Test;
-
-public class NoopSharedRefDatabaseTest implements RefFixture {
-
- private Ref sampleRef = newRef(A_TEST_REF_NAME, AN_OBJECT_ID_1);
- private NoopSharedRefDatabase objectUnderTest = new NoopSharedRefDatabase();
-
- @Test
- public void isUpToDateShouldAlwaysReturnTrue() {
- assertThat(objectUnderTest.isUpToDate(A_TEST_PROJECT_NAME_KEY, sampleRef)).isTrue();
- }
-
- @Test
- public void compareAndPutShouldAlwaysReturnTrue() {
- assertThat(objectUnderTest.compareAndPut(A_TEST_PROJECT_NAME_KEY, sampleRef, AN_OBJECT_ID_2))
- .isTrue();
- }
-
- @Test
- public void existsShouldAlwaysReturnFalse() {
- assertThat(objectUnderTest.exists(A_TEST_PROJECT_NAME_KEY, A_TEST_REF_NAME)).isFalse();
- }
-}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/RefSharedDatabaseTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/RefSharedDatabaseTest.java
deleted file mode 100644
index c9eeaa8..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/RefSharedDatabaseTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation.dfsrefdb;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.ObjectIdRef;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Ref.Storage;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TestName;
-
-public class RefSharedDatabaseTest implements RefFixture {
- @Rule public TestName nameRule = new TestName();
-
- @Override
- public String testBranch() {
- return "branch_" + nameRule.getMethodName();
- }
-
- @Test
- public void shouldCreateANewRef() {
-
- ObjectId objectId = AN_OBJECT_ID_1;
- String refName = aBranchRef();
-
- Ref aNewRef = new ObjectIdRef.Unpeeled(Ref.Storage.NETWORK, refName, objectId);
-
- assertThat(aNewRef.getName()).isEqualTo(refName);
- assertThat(aNewRef.getObjectId()).isEqualTo(objectId);
- assertThat(aNewRef.getStorage()).isEqualTo(Storage.NETWORK);
- }
-}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/RefUpdateStub.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/RefUpdateStub.java
deleted file mode 100644
index 7c1d7b4..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/RefUpdateStub.java
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation.dfsrefdb;
-
-import java.io.IOException;
-import org.apache.commons.lang.NotImplementedException;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.RefDatabase;
-import org.eclipse.jgit.lib.RefUpdate;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevWalk;
-import org.junit.Ignore;
-
-@Ignore
-public class RefUpdateStub extends RefUpdate {
-
- public static RefUpdate forSuccessfulCreate(Ref newRef) {
- return new RefUpdateStub(Result.NEW, null, newRef, newRef.getObjectId());
- }
-
- public static RefUpdate forSuccessfulUpdate(Ref oldRef, ObjectId newObjectId) {
- return new RefUpdateStub(Result.FAST_FORWARD, null, oldRef, newObjectId);
- }
-
- public static RefUpdate forSuccessfulDelete(Ref oldRef) {
- return new RefUpdateStub(null, Result.FORCED, oldRef, ObjectId.zeroId());
- }
-
- private final Result updateResult;
- private final Result deleteResult;
-
- public RefUpdateStub(Result updateResult, Result deleteResult, Ref oldRef, ObjectId newObjectId) {
- super(oldRef);
- this.setNewObjectId(newObjectId);
- this.updateResult = updateResult;
- this.deleteResult = deleteResult;
- }
-
- @Override
- protected RefDatabase getRefDatabase() {
- throw new NotImplementedException("Method not implemented yet, not assumed you needed it!!");
- }
-
- @Override
- protected Repository getRepository() {
- throw new NotImplementedException("Method not implemented yet, not assumed you needed it!!");
- }
-
- @Override
- protected boolean tryLock(boolean deref) throws IOException {
- throw new NotImplementedException("Method not implemented yet, not assumed you needed it!!");
- }
-
- @Override
- protected void unlock() {
- throw new NotImplementedException("Method not implemented yet, not assumed you needed it!!");
- }
-
- @Override
- protected Result doUpdate(Result desiredResult) throws IOException {
- throw new NotImplementedException("Method not implemented, shouldn't be called!!");
- }
-
- @Override
- protected Result doDelete(Result desiredResult) throws IOException {
- throw new NotImplementedException("Method not implemented, shouldn't be called!!");
- }
-
- @Override
- protected Result doLink(String target) throws IOException {
- throw new NotImplementedException("Method not implemented yet, not assumed you needed it!!");
- }
-
- @Override
- public Result update() throws IOException {
- if (updateResult != null) return updateResult;
-
- throw new NotImplementedException("Not assumed you needed to stub this call!!");
- }
-
- @Override
- public Result update(RevWalk walk) throws IOException {
- if (updateResult != null) return updateResult;
-
- throw new NotImplementedException("Not assumed you needed to stub this call!!");
- }
-
- @Override
- public Result delete() throws IOException {
- if (deleteResult != null) return deleteResult;
-
- throw new NotImplementedException("Not assumed you needed to stub this call!!");
- }
-
- @Override
- public Result delete(RevWalk walk) throws IOException {
- if (deleteResult != null) return deleteResult;
-
- throw new NotImplementedException("Not assumed you needed to stub this call!!");
- }
-}