Parse refs/multi-site/version as a Long BLOB value
The refs/multi-site/version was internally managed as a long
variable, however, the primitives for reading it from the Git
BLOB were using an Integer, causing exceptions at read time.
Parse the BLOB directly using a standard Java Long.parseLong()
avoiding the reuse of Gerrit NoteDb-specific Integer parsing.
Change-Id: I09c59fed3ec1d38d1473abf21f060955c5c3cc70
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdateImpl.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdateImpl.java
index 4bbfd91..51ad219 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdateImpl.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdateImpl.java
@@ -20,6 +20,7 @@
import com.gerritforge.gerrit.globalrefdb.GlobalRefDbSystemError;
import com.gerritforge.gerrit.globalrefdb.validation.ProjectsFilter;
import com.gerritforge.gerrit.globalrefdb.validation.SharedRefDatabaseWrapper;
+import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableSet;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.entities.Project;
@@ -29,17 +30,18 @@
import com.google.gerrit.server.events.RefUpdatedEvent;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.GitRepositoryManager;
-import com.google.gerrit.server.notedb.IntBlob;
import com.google.inject.Inject;
import com.googlesource.gerrit.plugins.multisite.ProjectVersionLogger;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.util.Optional;
import java.util.Set;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectIdRef;
import org.eclipse.jgit.lib.ObjectInserter;
+import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
@@ -220,9 +222,9 @@
public Optional<Long> getProjectLocalVersion(String projectName) {
try (Repository repository =
gitRepositoryManager.openRepository(Project.NameKey.parse(projectName))) {
- Optional<IntBlob> blob = IntBlob.parse(repository, MULTI_SITE_VERSIONING_REF);
+ Optional<Long> blob = longBlobParse(repository, MULTI_SITE_VERSIONING_REF);
if (blob.isPresent()) {
- Long repoVersion = Integer.toUnsignedLong(blob.get().value());
+ Long repoVersion = blob.get();
logger.atFine().log("Local project '%s' has version %d", projectName, repoVersion);
return Optional.of(repoVersion);
}
@@ -234,6 +236,24 @@
return Optional.empty();
}
+ private Optional<Long> longBlobParse(Repository repo, String ref) throws IOException {
+ return Optional.ofNullable(repo.exactRef(ref))
+ .map(
+ (r) -> {
+ ObjectLoader loader;
+ try {
+ loader = repo.open(r.getObjectId());
+ String boutString = new String(loader.getBytes(), StandardCharsets.UTF_8);
+ return Long.parseLong(boutString);
+ } catch (IOException e) {
+ logger.atSevere().withCause(e).log(
+ "Unable to extract long BLOB from %s:%s", repo.getDirectory(), ref);
+ return null;
+ }
+ })
+ .filter(Predicates.notNull());
+ }
+
/* (non-Javadoc)
* @see com.googlesource.gerrit.plugins.multisite.validation.ProjectVersionRefUpdate#getProjectRemoteVersion(java.lang.String)
*/
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 0d6fb67..464b886 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
@@ -155,9 +155,10 @@
when(refUpdatedEvent.getProjectNameKey()).thenReturn(A_TEST_PROJECT_NAME_KEY);
when(refUpdatedEvent.getRefName()).thenReturn(A_TEST_REF_NAME);
- new ProjectVersionRefUpdateImpl(
- repoManager, sharedRefDb, gitReferenceUpdated, verLogger, projectsFilter)
- .onEvent(refUpdatedEvent);
+ ProjectVersionRefUpdateImpl projectVersion =
+ new ProjectVersionRefUpdateImpl(
+ repoManager, sharedRefDb, gitReferenceUpdated, verLogger, projectsFilter);
+ projectVersion.onEvent(refUpdatedEvent);
Ref ref = repo.getRepository().findRef(MULTI_SITE_VERSIONING_REF);
@@ -168,6 +169,10 @@
ObjectLoader loader = repo.getRepository().open(ref.getObjectId());
long storedVersion = readLongObject(loader);
+
+ Optional<Long> localStoredVersion = projectVersion.getProjectLocalVersion(A_TEST_PROJECT_NAME);
+ assertThat(localStoredVersion).isEqualTo(Optional.of(storedVersion));
+
assertThat(storedVersion).isGreaterThan((long) masterPlusOneCommit.getCommitTime());
verify(verLogger).log(A_TEST_PROJECT_NAME_KEY, storedVersion, 0);