use of com.google.gerrit.server.update.RetryHelper in project gerrit by GerritCodeReview.
the class AccountIT method failAfterRetryerGivesUp.
@Test
public void failAfterRetryerGivesUp() throws Exception {
List<String> status = ImmutableList.of("foo", "bar", "baz");
String fullName = "Foo";
AtomicInteger bgCounter = new AtomicInteger(0);
PersonIdent ident = serverIdent.get();
AccountsUpdate update = new AccountsUpdate(repoManager, gitReferenceUpdated, Optional.empty(), allUsers, externalIds, metaDataUpdateInternalFactory, new RetryHelper(cfg, retryMetrics, null, null, null, exceptionHooks, r -> r.withStopStrategy(StopStrategies.stopAfterAttempt(status.size())).withBlockStrategy(noSleepBlockStrategy)), extIdNotesFactory, ident, ident, () -> {
try {
accountsUpdateProvider.get().update("Set Status", admin.id(), u -> u.setStatus(status.get(bgCounter.getAndAdd(1))));
} catch (IOException | ConfigInvalidException | StorageException e) {
// Ignore, the expected exception is asserted later
}
}, Runnables.doNothing());
assertThat(bgCounter.get()).isEqualTo(0);
AccountInfo accountInfo = gApi.accounts().id(admin.id().get()).get();
assertThat(accountInfo.status).isNull();
assertThat(accountInfo.name).isNotEqualTo(fullName);
assertThrows(LockFailureException.class, () -> update.update("Set Full Name", admin.id(), u -> u.setFullName(fullName)));
assertThat(bgCounter.get()).isEqualTo(status.size());
Account updatedAccount = accounts.get(admin.id()).get().account();
assertThat(updatedAccount.status()).isEqualTo(Iterables.getLast(status));
assertThat(updatedAccount.fullName()).isEqualTo(admin.fullName());
accountInfo = gApi.accounts().id(admin.id().get()).get();
assertThat(accountInfo.status).isEqualTo(Iterables.getLast(status));
assertThat(accountInfo.name).isEqualTo(admin.fullName());
}
use of com.google.gerrit.server.update.RetryHelper in project gerrit by GerritCodeReview.
the class AccountIT method atomicReadMofifyWriteExternalIds.
@Test
public void atomicReadMofifyWriteExternalIds() throws Exception {
projectOperations.allProjectsForUpdate().add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS)).update();
Account.Id accountId = Account.id(seq.nextAccountId());
ExternalId extIdA1 = externalIdFactory.create("foo", "A-1", accountId);
accountsUpdateProvider.get().insert("Create Test Account", accountId, u -> u.addExternalId(extIdA1));
AtomicInteger bgCounterA1 = new AtomicInteger(0);
AtomicInteger bgCounterA2 = new AtomicInteger(0);
PersonIdent ident = serverIdent.get();
ExternalId extIdA2 = externalIdFactory.create("foo", "A-2", accountId);
AccountsUpdate update = new AccountsUpdate(repoManager, gitReferenceUpdated, Optional.empty(), allUsers, externalIds, metaDataUpdateInternalFactory, new RetryHelper(cfg, retryMetrics, null, null, null, exceptionHooks, r -> r.withBlockStrategy(noSleepBlockStrategy)), extIdNotesFactory, ident, ident, Runnables.doNothing(), () -> {
try {
accountsUpdateProvider.get().update("Update External ID", accountId, u -> u.replaceExternalId(extIdA1, extIdA2));
} catch (IOException | ConfigInvalidException | StorageException e) {
// Ignore, the expected exception is asserted later
}
});
assertThat(bgCounterA1.get()).isEqualTo(0);
assertThat(bgCounterA2.get()).isEqualTo(0);
assertThat(gApi.accounts().id(accountId.get()).getExternalIds().stream().map(i -> i.identity).collect(toSet())).containsExactly(extIdA1.key().get());
ExternalId extIdB1 = externalIdFactory.create("foo", "B-1", accountId);
ExternalId extIdB2 = externalIdFactory.create("foo", "B-2", accountId);
Optional<AccountState> updatedAccount = update.update("Update External ID", accountId, (a, u) -> {
if (a.externalIds().contains(extIdA1)) {
bgCounterA1.getAndIncrement();
u.replaceExternalId(extIdA1, extIdB1);
}
if (a.externalIds().contains(extIdA2)) {
bgCounterA2.getAndIncrement();
u.replaceExternalId(extIdA2, extIdB2);
}
});
assertThat(bgCounterA1.get()).isEqualTo(1);
assertThat(bgCounterA2.get()).isEqualTo(1);
assertThat(updatedAccount).isPresent();
assertThat(updatedAccount.get().externalIds()).containsExactly(extIdB2);
assertThat(accounts.get(accountId).get().externalIds()).containsExactly(extIdB2);
assertThat(gApi.accounts().id(accountId.get()).getExternalIds().stream().map(i -> i.identity).collect(toSet())).containsExactly(extIdB2.key().get());
}
use of com.google.gerrit.server.update.RetryHelper in project gerrit by GerritCodeReview.
the class AccountIT method retryOnLockFailure.
@Test
public void retryOnLockFailure() throws Exception {
String status = "happy";
String fullName = "Foo";
AtomicBoolean doneBgUpdate = new AtomicBoolean(false);
PersonIdent ident = serverIdent.get();
AccountsUpdate update = new AccountsUpdate(repoManager, gitReferenceUpdated, Optional.empty(), allUsers, externalIds, metaDataUpdateInternalFactory, new RetryHelper(cfg, retryMetrics, null, null, null, exceptionHooks, r -> r.withBlockStrategy(noSleepBlockStrategy)), extIdNotesFactory, ident, ident, () -> {
if (!doneBgUpdate.getAndSet(true)) {
try {
accountsUpdateProvider.get().update("Set Status", admin.id(), u -> u.setStatus(status));
} catch (IOException | ConfigInvalidException | StorageException e) {
// Ignore, the successful update of the account is asserted later
}
}
}, Runnables.doNothing());
assertThat(doneBgUpdate.get()).isFalse();
AccountInfo accountInfo = gApi.accounts().id(admin.id().get()).get();
assertThat(accountInfo.status).isNull();
assertThat(accountInfo.name).isNotEqualTo(fullName);
Optional<AccountState> updatedAccountState = update.update("Set Full Name", admin.id(), u -> u.setFullName(fullName));
assertThat(doneBgUpdate.get()).isTrue();
assertThat(updatedAccountState).isPresent();
Account updatedAccount = updatedAccountState.get().account();
assertThat(updatedAccount.status()).isEqualTo(status);
assertThat(updatedAccount.fullName()).isEqualTo(fullName);
accountInfo = gApi.accounts().id(admin.id().get()).get();
assertThat(accountInfo.status).isEqualTo(status);
assertThat(accountInfo.name).isEqualTo(fullName);
}
use of com.google.gerrit.server.update.RetryHelper in project gerrit by GerritCodeReview.
the class AccountIT method atomicReadMofifyWrite.
@Test
public void atomicReadMofifyWrite() throws Exception {
gApi.accounts().id(admin.id().get()).setStatus("A-1");
AtomicInteger bgCounterA1 = new AtomicInteger(0);
AtomicInteger bgCounterA2 = new AtomicInteger(0);
PersonIdent ident = serverIdent.get();
AccountsUpdate update = new AccountsUpdate(repoManager, gitReferenceUpdated, Optional.empty(), allUsers, externalIds, metaDataUpdateInternalFactory, new RetryHelper(cfg, retryMetrics, null, null, null, exceptionHooks, r -> r.withBlockStrategy(noSleepBlockStrategy)), extIdNotesFactory, ident, ident, Runnables.doNothing(), () -> {
try {
accountsUpdateProvider.get().update("Set Status", admin.id(), u -> u.setStatus("A-2"));
} catch (IOException | ConfigInvalidException | StorageException e) {
// Ignore, the expected exception is asserted later
}
});
assertThat(bgCounterA1.get()).isEqualTo(0);
assertThat(bgCounterA2.get()).isEqualTo(0);
assertThat(gApi.accounts().id(admin.id().get()).get().status).isEqualTo("A-1");
Optional<AccountState> updatedAccountState = update.update("Set Status", admin.id(), (a, u) -> {
if ("A-1".equals(a.account().status())) {
bgCounterA1.getAndIncrement();
u.setStatus("B-1");
}
if ("A-2".equals(a.account().status())) {
bgCounterA2.getAndIncrement();
u.setStatus("B-2");
}
});
assertThat(bgCounterA1.get()).isEqualTo(1);
assertThat(bgCounterA2.get()).isEqualTo(1);
assertThat(updatedAccountState).isPresent();
assertThat(updatedAccountState.get().account().status()).isEqualTo("B-2");
assertThat(accounts.get(admin.id()).get().account().status()).isEqualTo("B-2");
assertThat(gApi.accounts().id(admin.id().get()).get().status).isEqualTo("B-2");
}
use of com.google.gerrit.server.update.RetryHelper in project gerrit by GerritCodeReview.
the class MergeOp method integrateIntoHistory.
private void integrateIntoHistory(ChangeSet cs, SubmissionExecutor submissionExecutor) throws RestApiException, UpdateException {
checkArgument(!cs.furtherHiddenChanges(), "cannot integrate hidden changes into history");
logger.atFine().log("Beginning merge attempt on %s", cs);
Map<BranchNameKey, BranchBatch> toSubmit = new HashMap<>();
ListMultimap<BranchNameKey, ChangeData> cbb;
try {
cbb = cs.changesByBranch();
} catch (StorageException e) {
throw new StorageException("Error reading changes to submit", e);
}
Set<BranchNameKey> branches = cbb.keySet();
for (BranchNameKey branch : branches) {
OpenRepo or = openRepo(branch.project());
if (or != null) {
toSubmit.put(branch, validateChangeList(or, cbb.get(branch)));
}
}
// Done checks that don't involve running submit strategies.
commitStatus.maybeFailVerbose();
try {
SubscriptionGraph subscriptionGraph = subscriptionGraphFactory.compute(branches, orm);
SubmoduleCommits submoduleCommits = submoduleCommitsFactory.create(orm);
UpdateOrderCalculator updateOrderCalculator = new UpdateOrderCalculator(subscriptionGraph);
List<SubmitStrategy> strategies = getSubmitStrategies(toSubmit, updateOrderCalculator, submoduleCommits, subscriptionGraph, dryrun);
this.allProjects = updateOrderCalculator.getProjectsInOrder();
List<BatchUpdate> batchUpdates = orm.batchUpdates(allProjects);
// Group batch updates by project
Map<Project.NameKey, BatchUpdate> batchUpdatesByProject = batchUpdates.stream().collect(Collectors.toMap(b -> b.getProject(), Function.identity()));
for (Map.Entry<Change.Id, ChangeData> entry : cs.changesById().entrySet()) {
Project.NameKey project = entry.getValue().project();
Change.Id changeId = entry.getKey();
ChangeData cd = entry.getValue();
batchUpdatesByProject.get(project).addOp(changeId, storeSubmitRequirementsOpFactory.create(cd.submitRequirementsIncludingLegacy().values(), cd));
}
try {
submissionExecutor.setAdditionalBatchUpdateListeners(ImmutableList.of(new SubmitStrategyListener(submitInput, strategies, commitStatus)));
submissionExecutor.execute(batchUpdates);
} finally {
// If the BatchUpdate fails it can be that merging some of the changes was actually
// successful. This is why we must to collect the updated changes also when an
// exception was thrown.
strategies.forEach(s -> updatedChanges.putAll(s.getUpdatedChanges()));
// Do not leave executed BatchUpdates in the OpenRepos
if (!dryrun) {
orm.resetUpdates(ImmutableSet.copyOf(this.allProjects));
}
}
} catch (NoSuchProjectException e) {
throw new ResourceNotFoundException(e.getMessage());
} catch (IOException e) {
throw new StorageException(e);
} catch (SubmoduleConflictException e) {
throw new IntegrationConflictException(e.getMessage(), e);
} catch (UpdateException e) {
if (e.getCause() instanceof LockFailureException) {
// as to be unnoticeable, assuming RetryHelper is retrying sufficiently.
throw e;
}
// inner IntegrationConflictException to a ResourceConflictException.
if (e.getCause() instanceof IntegrationConflictException) {
throw (IntegrationConflictException) e.getCause();
}
throw new MergeUpdateException(genericMergeError(cs), e);
}
}
Aggregations