use of com.google.gerrit.server.update.UpdateException in project gerrit by GerritCodeReview.
the class ConsistencyChecker method deletePatchSets.
private void deletePatchSets(List<DeletePatchSetFromDbOp> ops) {
try (BatchUpdate bu = newBatchUpdate()) {
bu.setRepository(repo, rw, oi);
for (DeletePatchSetFromDbOp op : ops) {
checkArgument(op.psId.changeId().equals(notes.getChangeId()));
bu.addOp(notes.getChangeId(), op);
}
bu.addOp(notes.getChangeId(), new UpdateCurrentPatchSetOp(ops));
bu.execute();
} catch (NoPatchSetsWouldRemainException e) {
for (DeletePatchSetFromDbOp op : ops) {
op.p.status = Status.FIX_FAILED;
op.p.outcome = e.getMessage();
}
} catch (UpdateException | RestApiException e) {
String msg = "Error deleting patch set";
logger.atWarning().withCause(e).log("%s of change %s", msg, ops.get(0).psId.changeId());
for (DeletePatchSetFromDbOp op : ops) {
// Overwrite existing statuses that were set before the transaction was
// rolled back.
op.p.status = Status.FIX_FAILED;
op.p.outcome = msg;
}
}
}
use of com.google.gerrit.server.update.UpdateException in project gerrit by GerritCodeReview.
the class ConsistencyChecker method fixMerged.
private void fixMerged(ProblemInfo p) {
try (BatchUpdate bu = newBatchUpdate()) {
bu.setRepository(repo, rw, oi);
bu.addOp(notes.getChangeId(), new FixMergedOp(p));
bu.execute();
} catch (UpdateException | RestApiException e) {
logger.atWarning().withCause(e).log("Error marking %s as merged", notes.getChangeId());
p.status = Status.FIX_FAILED;
p.outcome = "Error updating status to merged";
}
}
use of com.google.gerrit.server.update.UpdateException in project gerrit by GerritCodeReview.
the class ConsistencyChecker method insertMergedPatchSet.
private void insertMergedPatchSet(final RevCommit commit, @Nullable PatchSet.Id psIdToDelete, boolean reuseOldPsId) {
ProblemInfo notFound = problem("No patch set found for merged commit " + commit.name());
if (!user.get().isIdentifiedUser()) {
notFound.status = Status.FIX_FAILED;
notFound.outcome = "Must be called by an identified user to insert new patch set";
return;
}
ProblemInfo insertPatchSetProblem;
ProblemInfo deleteOldPatchSetProblem;
if (psIdToDelete == null) {
insertPatchSetProblem = problem(String.format("Expected merged commit %s has no associated patch set", commit.name()));
deleteOldPatchSetProblem = null;
} else {
String msg = String.format("Expected merge commit %s corresponds to patch set %s," + " not the current patch set %s", commit.name(), psIdToDelete.get(), change().currentPatchSetId().get());
// Maybe an identical problem, but different fix.
deleteOldPatchSetProblem = reuseOldPsId ? null : problem(msg);
insertPatchSetProblem = problem(msg);
}
List<ProblemInfo> currProblems = new ArrayList<>(3);
currProblems.add(notFound);
if (deleteOldPatchSetProblem != null) {
currProblems.add(deleteOldPatchSetProblem);
}
currProblems.add(insertPatchSetProblem);
try {
PatchSet.Id psId = (psIdToDelete != null && reuseOldPsId) ? psIdToDelete : ChangeUtil.nextPatchSetId(repo, change().currentPatchSetId());
PatchSetInserter inserter = patchSetInserterFactory.create(notes, psId, commit);
try (BatchUpdate bu = newBatchUpdate()) {
bu.setRepository(repo, rw, oi);
if (psIdToDelete != null) {
// Delete the given patch set ref. If reuseOldPsId is true,
// PatchSetInserter will reinsert the same ref, making it a no-op.
bu.addOp(notes.getChangeId(), new BatchUpdateOp() {
@Override
public void updateRepo(RepoContext ctx) throws IOException {
ctx.addRefUpdate(commit, ObjectId.zeroId(), psIdToDelete.toRefName());
}
});
if (!reuseOldPsId) {
bu.addOp(notes.getChangeId(), new DeletePatchSetFromDbOp(requireNonNull(deleteOldPatchSetProblem), psIdToDelete));
}
}
bu.setNotify(NotifyResolver.Result.none());
bu.addOp(notes.getChangeId(), inserter.setValidate(false).setFireRevisionCreated(false).setAllowClosed(true).setMessage("Patch set for merged commit inserted by consistency checker"));
bu.addOp(notes.getChangeId(), new FixMergedOp(notFound));
bu.execute();
}
notes = notesFactory.createChecked(inserter.getChange());
insertPatchSetProblem.status = Status.FIXED;
insertPatchSetProblem.outcome = "Inserted as patch set " + psId.get();
} catch (StorageException | IOException | UpdateException | RestApiException e) {
logger.atWarning().withCause(e).log("Error in consistency check of change %s", notes.getChangeId());
for (ProblemInfo pi : currProblems) {
pi.status = Status.FIX_FAILED;
pi.outcome = "Error inserting merged patch set";
}
return;
}
}
use of com.google.gerrit.server.update.UpdateException in project gerrit by GerritCodeReview.
the class MailReceiver method dispatchMailProcessor.
protected void dispatchMailProcessor(List<MailMessage> messages, boolean async) {
for (MailMessage m : messages) {
if (async) {
@SuppressWarnings("unused") Future<?> possiblyIgnoredError = workQueue.getDefaultQueue().submit(() -> {
try {
mailProcessor.process(m);
requestDeletion(m.id());
} catch (RestApiException | UpdateException e) {
logger.atSevere().withCause(e).log("Mail: Can't process message %s . Won't delete.", m.id());
}
});
} else {
// Synchronous processing is used only in tests.
try {
mailProcessor.process(m);
requestDeletion(m.id());
} catch (RestApiException | UpdateException e) {
logger.atSevere().withCause(e).log("Mail: Can't process messages. Won't delete.");
}
}
}
}
use of com.google.gerrit.server.update.UpdateException in project gerrit by GerritCodeReview.
the class MailProcessor method persistComments.
private void persistComments(BatchUpdate.Factory buf, MailMessage message, MailMetadata metadata, Account.Id sender) throws UpdateException, RestApiException {
try (ManualRequestContext ctx = oneOffRequestContext.openAs(sender)) {
List<ChangeData> changeDataList = queryProvider.get().enforceVisibility(true).byLegacyChangeId(Change.id(metadata.changeNumber));
if (changeDataList.isEmpty()) {
sendRejectionEmail(message, InboundEmailError.CHANGE_NOT_FOUND);
return;
}
if (changeDataList.size() != 1) {
logger.atSevere().log("Message %s references unique change %s," + " but there are %d matching changes in the index." + " Will delete message.", message.id(), metadata.changeNumber, changeDataList.size());
sendRejectionEmail(message, InboundEmailError.INTERNAL_EXCEPTION);
return;
}
ChangeData cd = Iterables.getOnlyElement(changeDataList);
if (existingMessageIds(cd).contains(message.id())) {
logger.atInfo().log("Message %s was already processed. Will delete message.", message.id());
return;
}
// Get all comments; filter and sort them to get the original list of
// comments from the outbound email.
// TODO(hiesel) Also filter by original comment author.
Collection<HumanComment> comments = cd.publishedComments().stream().filter(c -> (c.writtenOn.getTime() / 1000) == (metadata.timestamp.getTime() / 1000)).sorted(CommentsUtil.COMMENT_ORDER).collect(toList());
Project.NameKey project = cd.project();
// If URL is not defined, we won't be able to parse line comments. We still attempt to get the
// other ones.
String changeUrl = urlFormatter.get().getChangeViewUrl(cd.project(), cd.getId()).orElse("http://gerrit.invalid/");
List<MailComment> parsedComments;
if (useHtmlParser(message)) {
parsedComments = HtmlParser.parse(message, comments, changeUrl);
} else {
parsedComments = TextParser.parse(message, comments, changeUrl);
}
if (parsedComments.isEmpty()) {
logger.atWarning().log("Could not parse any comments from %s. Will delete message.", message.id());
sendRejectionEmail(message, InboundEmailError.PARSING_ERROR);
return;
}
ImmutableList<CommentForValidation> parsedCommentsForValidation = parsedComments.stream().map(comment -> CommentForValidation.create(CommentForValidation.CommentSource.HUMAN, MAIL_COMMENT_TYPE_TO_VALIDATION_TYPE.get(comment.getType()), comment.getMessage(), comment.getMessage().length())).collect(ImmutableList.toImmutableList());
CommentValidationContext commentValidationCtx = CommentValidationContext.create(cd.change().getChangeId(), cd.change().getProject().get(), cd.change().getDest().branch());
ImmutableList<CommentValidationFailure> commentValidationFailures = PublishCommentUtil.findInvalidComments(commentValidationCtx, commentValidators, parsedCommentsForValidation);
if (!commentValidationFailures.isEmpty()) {
sendRejectionEmail(message, InboundEmailError.COMMENT_REJECTED);
return;
}
Op o = new Op(PatchSet.id(cd.getId(), metadata.patchSet), parsedComments, message.id());
BatchUpdate batchUpdate = buf.create(project, ctx.getUser(), TimeUtil.now());
batchUpdate.addOp(cd.getId(), o);
batchUpdate.execute();
}
}
Aggregations