Search in sources :

Example 26 with ChangeNotes

use of com.google.gerrit.server.notedb.ChangeNotes in project gerrit by GerritCodeReview.

the class PublishCommentUtil method publish.

public void publish(ChangeContext ctx, ChangeUpdate changeUpdate, Collection<HumanComment> draftComments, @Nullable String tag) {
    ChangeNotes notes = ctx.getNotes();
    checkArgument(notes != null);
    if (draftComments.isEmpty()) {
        return;
    }
    Map<PatchSet.Id, PatchSet> patchSets = psUtil.getAsMap(notes, draftComments.stream().map(d -> psId(notes, d)).collect(toSet()));
    Set<HumanComment> commentsToPublish = new HashSet<>();
    for (HumanComment draftComment : draftComments) {
        PatchSet.Id psIdOfDraftComment = psId(notes, draftComment);
        PatchSet ps = patchSets.get(psIdOfDraftComment);
        if (ps == null) {
            // This can happen if changes with the same numeric ID exist:
            // - change 12345 has 3 patch sets in repo X
            // - another change 12345 has 7 patch sets in repo Y
            // - the user saves a draft comment on patch set 6 of the change in repo Y
            // - this draft comment gets stored in:
            // AllUsers -> refs/draft-comments/45/12345/<account-id>
            // - when posting a review with draft handling PUBLISH_ALL_REVISIONS on the change in
            // repo X, the draft comments are loaded from
            // AllUsers -> refs/draft-comments/45/12345/<account-id>, including the draft
            // comment that was saved for patch set 6 of the change in repo Y
            // - patch set 6 does not exist for the change in repo x, hence we get null for the patch
            // set here
            // Instead of failing hard (and returning an Internal Server Error) to the caller,
            // just ignore that comment.
            // Gerrit ensures that numeric change IDs are unique, but you can get duplicates if
            // change refs of one repo are copied/pushed to another repo on the same host (this
            // should never be done, but we know it happens).
            logger.atWarning().log("Ignoring draft comment %s on non existing patch set %s (repo = %s)", draftComment, psIdOfDraftComment, notes.getProjectName());
            continue;
        }
        draftComment.writtenOn = Timestamp.from(ctx.getWhen());
        draftComment.tag = tag;
        // Draft may have been created by a different real user; copy the current real user. (Only
        // applies to X-Gerrit-RunAs, since modifying drafts via on_behalf_of is not allowed.)
        ctx.getUser().updateRealAccountId(draftComment::setRealAuthor);
        commentsUtil.setCommentCommitId(draftComment, notes.getChange(), ps);
        commentsToPublish.add(draftComment);
    }
    commentsUtil.putHumanComments(changeUpdate, HumanComment.Status.PUBLISHED, commentsToPublish);
}
Also used : PatchSet(com.google.gerrit.entities.PatchSet) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) HumanComment(com.google.gerrit.entities.HumanComment) HashSet(java.util.HashSet)

Example 27 with ChangeNotes

use of com.google.gerrit.server.notedb.ChangeNotes in project gerrit by GerritCodeReview.

the class GroupCollector method create.

/**
 * Returns a new {@link GroupCollector} instance.
 *
 * @see GroupCollector for what this class does.
 */
public static GroupCollector create(ReceivePackRefCache receivePackRefCache, PatchSetUtil psUtil, ChangeNotes.Factory notesFactory, Project.NameKey project) {
    return new GroupCollector(receivePackRefCache, psId -> {
        // TODO(dborowitz): Reuse open repository from caller.
        ChangeNotes notes = notesFactory.createChecked(project, psId.changeId());
        PatchSet ps = psUtil.get(notes, psId);
        return ps != null ? ps.groups() : null;
    });
}
Also used : PatchSet(com.google.gerrit.entities.PatchSet) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes)

Example 28 with ChangeNotes

use of com.google.gerrit.server.notedb.ChangeNotes in project gerrit by GerritCodeReview.

the class CommentPorter method port.

private ImmutableList<HumanComment> port(ChangeNotes notes, PatchSet targetPatchset, List<HumanComment> comments) {
    Map<Integer, ImmutableList<HumanComment>> commentsPerPatchset = comments.stream().collect(groupingBy(comment -> comment.key.patchSetId, toImmutableList()));
    ImmutableList.Builder<HumanComment> portedComments = ImmutableList.builderWithExpectedSize(comments.size());
    for (Integer originalPatchsetId : commentsPerPatchset.keySet()) {
        ImmutableList<HumanComment> patchsetComments = commentsPerPatchset.get(originalPatchsetId);
        PatchSet originalPatchset = notes.getPatchSets().get(PatchSet.id(notes.getChangeId(), originalPatchsetId));
        if (originalPatchset != null) {
            portedComments.addAll(portSamePatchset(notes.getProjectName(), notes.getChange(), originalPatchset, targetPatchset, patchsetComments));
        } else {
            logger.atWarning().log("Some comments which should be ported refer to the non-existent patchset %s of" + " change %d. Omitting %d affected comments.", originalPatchsetId, notes.getChangeId().get(), patchsetComments.size());
        }
    }
    return portedComments.build();
}
Also used : Patch(com.google.gerrit.entities.Patch) Inject(com.google.inject.Inject) Collectors.groupingBy(java.util.stream.Collectors.groupingBy) Mapping(com.google.gerrit.server.patch.GitPositionTransformer.Mapping) HumanComment(com.google.gerrit.entities.HumanComment) CommentsUtil(com.google.gerrit.server.CommentsUtil) Position(com.google.gerrit.server.patch.GitPositionTransformer.Position) TraceTimer(com.google.gerrit.server.logging.TraceContext.TraceTimer) Function(java.util.function.Function) BestPositionOnConflict(com.google.gerrit.server.patch.GitPositionTransformer.BestPositionOnConflict) DiffNotAvailableException(com.google.gerrit.server.patch.DiffNotAvailableException) ImmutableList(com.google.common.collect.ImmutableList) FileDiffOutput(com.google.gerrit.server.patch.filediff.FileDiffOutput) Description(com.google.gerrit.metrics.Description) Map(java.util.Map) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) Change(com.google.gerrit.entities.Change) PatchSet(com.google.gerrit.entities.PatchSet) Metadata(com.google.gerrit.server.logging.Metadata) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableMap(com.google.common.collect.ImmutableMap) TraceContext(com.google.gerrit.server.logging.TraceContext) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) DiffMappings(com.google.gerrit.server.patch.DiffMappings) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) ObjectId(org.eclipse.jgit.lib.ObjectId) DiffOptions(com.google.gerrit.server.patch.DiffOptions) TaggedEdit(com.google.gerrit.server.patch.filediff.TaggedEdit) List(java.util.List) FileEdits(com.google.gerrit.server.patch.filediff.FileEdits) Stream(java.util.stream.Stream) GitPositionTransformer(com.google.gerrit.server.patch.GitPositionTransformer) DiffOperations(com.google.gerrit.server.patch.DiffOperations) FileMapping(com.google.gerrit.server.patch.GitPositionTransformer.FileMapping) Project(com.google.gerrit.entities.Project) PositionedEntity(com.google.gerrit.server.patch.GitPositionTransformer.PositionedEntity) Optional(java.util.Optional) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Counter0(com.google.gerrit.metrics.Counter0) MetricMaker(com.google.gerrit.metrics.MetricMaker) FluentLogger(com.google.common.flogger.FluentLogger) Range(com.google.gerrit.entities.Comment.Range) Singleton(com.google.inject.Singleton) ImmutableList(com.google.common.collect.ImmutableList) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) PatchSet(com.google.gerrit.entities.PatchSet) HumanComment(com.google.gerrit.entities.HumanComment)

Example 29 with ChangeNotes

use of com.google.gerrit.server.notedb.ChangeNotes in project gerrit by GerritCodeReview.

the class ChangesCollection method parse.

@Override
public ChangeResource parse(TopLevelResource root, IdString id) throws RestApiException, PermissionBackendException, IOException {
    List<ChangeNotes> notes = changeFinder.find(id.encoded(), 2);
    if (notes.isEmpty()) {
        throw new ResourceNotFoundException(id);
    } else if (notes.size() != 1) {
        throw new ResourceNotFoundException("Multiple changes found for " + id);
    }
    ChangeNotes change = notes.get(0);
    if (!canRead(change)) {
        throw new ResourceNotFoundException(id);
    }
    checkProjectStatePermitsRead(change.getProjectName());
    return changeResourceFactory.create(change, user.get());
}
Also used : ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException)

Example 30 with ChangeNotes

use of com.google.gerrit.server.notedb.ChangeNotes in project gerrit by GerritCodeReview.

the class DeleteComment method apply.

@Override
public Response<CommentInfo> apply(HumanCommentResource rsrc, DeleteCommentInput input) throws RestApiException, IOException, ConfigInvalidException, PermissionBackendException, UpdateException {
    CurrentUser user = userProvider.get();
    permissionBackend.user(user).check(GlobalPermission.ADMINISTRATE_SERVER);
    if (input == null) {
        input = new DeleteCommentInput();
    }
    String newMessage = getCommentNewMessage(user.asIdentifiedUser().getName(), input.reason);
    DeleteCommentOp deleteCommentOp = new DeleteCommentOp(rsrc, newMessage);
    try (BatchUpdate batchUpdate = updateFactory.create(rsrc.getRevisionResource().getProject(), user, TimeUtil.now())) {
        batchUpdate.addOp(rsrc.getRevisionResource().getChange().getId(), deleteCommentOp).execute();
    }
    ChangeNotes updatedNotes = notesFactory.createChecked(rsrc.getRevisionResource().getProject(), rsrc.getRevisionResource().getChangeResource().getId());
    List<HumanComment> changeComments = commentsUtil.publishedHumanCommentsByChange(updatedNotes);
    Optional<HumanComment> updatedComment = changeComments.stream().filter(c -> c.key.equals(rsrc.getComment().key)).findFirst();
    if (!updatedComment.isPresent()) {
        // This should not happen as this endpoint should not remove the whole comment.
        throw new ResourceNotFoundException("comment not found: " + rsrc.getComment().key);
    }
    return Response.ok(commentJson.get().newHumanCommentFormatter().format(updatedComment.get()));
}
Also used : ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) PermissionBackendException(com.google.gerrit.server.permissions.PermissionBackendException) ConfigInvalidException(org.eclipse.jgit.errors.ConfigInvalidException) CommentInfo(com.google.gerrit.extensions.common.CommentInfo) Inject(com.google.inject.Inject) HumanComment(com.google.gerrit.entities.HumanComment) CommentsUtil(com.google.gerrit.server.CommentsUtil) Response(com.google.gerrit.extensions.restapi.Response) PermissionBackend(com.google.gerrit.server.permissions.PermissionBackend) UpdateException(com.google.gerrit.server.update.UpdateException) RestModifyView(com.google.gerrit.extensions.restapi.RestModifyView) Strings(com.google.common.base.Strings) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) PatchSet(com.google.gerrit.entities.PatchSet) RestApiException(com.google.gerrit.extensions.restapi.RestApiException) ChangeContext(com.google.gerrit.server.update.ChangeContext) GlobalPermission(com.google.gerrit.server.permissions.GlobalPermission) CurrentUser(com.google.gerrit.server.CurrentUser) DeleteCommentInput(com.google.gerrit.extensions.api.changes.DeleteCommentInput) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) IOException(java.io.IOException) Provider(com.google.inject.Provider) List(java.util.List) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) Optional(java.util.Optional) TimeUtil(com.google.gerrit.server.util.time.TimeUtil) BatchUpdateOp(com.google.gerrit.server.update.BatchUpdateOp) HumanCommentResource(com.google.gerrit.server.change.HumanCommentResource) Singleton(com.google.inject.Singleton) CurrentUser(com.google.gerrit.server.CurrentUser) DeleteCommentInput(com.google.gerrit.extensions.api.changes.DeleteCommentInput) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) HumanComment(com.google.gerrit.entities.HumanComment) BatchUpdate(com.google.gerrit.server.update.BatchUpdate)

Aggregations

ChangeNotes (com.google.gerrit.server.notedb.ChangeNotes)134 Test (org.junit.Test)54 Change (com.google.gerrit.entities.Change)47 AbstractDaemonTest (com.google.gerrit.acceptance.AbstractDaemonTest)43 PatchSet (com.google.gerrit.entities.PatchSet)42 ObjectId (org.eclipse.jgit.lib.ObjectId)33 StorageException (com.google.gerrit.exceptions.StorageException)22 Change (com.google.gerrit.reviewdb.client.Change)21 Project (com.google.gerrit.entities.Project)17 PushOneCommit (com.google.gerrit.acceptance.PushOneCommit)16 FixInput (com.google.gerrit.extensions.api.changes.FixInput)16 ResourceNotFoundException (com.google.gerrit.extensions.restapi.ResourceNotFoundException)14 HumanComment (com.google.gerrit.entities.HumanComment)13 TestChanges.newPatchSet (com.google.gerrit.testing.TestChanges.newPatchSet)12 IOException (java.io.IOException)12 RevCommit (org.eclipse.jgit.revwalk.RevCommit)12 ResourceConflictException (com.google.gerrit.extensions.restapi.ResourceConflictException)11 PatchSet (com.google.gerrit.reviewdb.client.PatchSet)10 PermissionBackendException (com.google.gerrit.server.permissions.PermissionBackendException)10 AuthException (com.google.gerrit.extensions.restapi.AuthException)9