Add support for Robot Comments

Extend the PostReview REST endpoint to support posting of robot
comments. For this ReviewInput got a new field that can contain a list
of robot comments. For reading robot comments new REST endpoints have
been added.

Robot comments are only supported with NoteDb, but not with ReviewDb.

Robot comments are always stored as JSON, even if notedb.writeJson is
set to false.

In NoteDb robot comments are not stored in the change meta ref but in
a separate refs/changes/XX/YYYY/robot-comments ref. By storing robot
comments in a separate ref we can delete robot comments without
rewriting the history of the change meta branch which is needed for
auditing and hence cannot be rewritten. Deletion of robot comments is
not implemented in this change, but we may want to support this later
as the amount and size of robot comments can be large.

Draft robot comments are not supported, but robot comments are always
published comments.

Change-Id: I2d8a5ca59e9a8b2c34863c54a3a9576599f69526
Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
Edwin Kempin
2016-09-19 15:35:10 +02:00
parent 76b1375aa8
commit 3fde7e4e75
46 changed files with 1713 additions and 232 deletions

View File

@@ -34,6 +34,7 @@ public class ReviewInput {
public Map<String, Short> labels;
public Map<String, List<CommentInput>> comments;
public Map<String, List<RobotCommentInput>> robotComments;
/**
* If true require all labels to be within the user's permitted ranges based
@@ -94,6 +95,12 @@ public class ReviewInput {
public static class CommentInput extends Comment {
}
public static class RobotCommentInput extends CommentInput {
public String robotId;
public String robotRunId;
public String url;
}
public ReviewInput message(String msg) {
message = msg != null && !msg.isEmpty() ? msg : null;
return this;

View File

@@ -20,6 +20,7 @@ import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.common.CommitInfo;
import com.google.gerrit.extensions.common.FileInfo;
import com.google.gerrit.extensions.common.MergeableInfo;
import com.google.gerrit.extensions.common.RobotCommentInfo;
import com.google.gerrit.extensions.common.TestSubmitRuleInput;
import com.google.gerrit.extensions.restapi.BinaryResult;
import com.google.gerrit.extensions.restapi.NotImplementedException;
@@ -54,15 +55,18 @@ public interface RevisionApi {
MergeableInfo mergeableOtherBranches() throws RestApiException;
Map<String, List<CommentInfo>> comments() throws RestApiException;
Map<String, List<RobotCommentInfo>> robotComments() throws RestApiException;
Map<String, List<CommentInfo>> drafts() throws RestApiException;
List<CommentInfo> commentsAsList() throws RestApiException;
List<CommentInfo> draftsAsList() throws RestApiException;
List<RobotCommentInfo> robotCommentsAsList() throws RestApiException;
DraftApi createDraft(DraftInput in) throws RestApiException;
DraftApi draft(String id) throws RestApiException;
CommentApi comment(String id) throws RestApiException;
RobotCommentApi robotComment(String id) throws RestApiException;
/**
* Returns patch of revision.
@@ -196,6 +200,12 @@ public interface RevisionApi {
throw new NotImplementedException();
}
@Override
public Map<String, List<RobotCommentInfo>> robotComments()
throws RestApiException {
throw new NotImplementedException();
}
@Override
public List<CommentInfo> commentsAsList() throws RestApiException {
throw new NotImplementedException();
@@ -206,6 +216,12 @@ public interface RevisionApi {
throw new NotImplementedException();
}
@Override
public List<RobotCommentInfo> robotCommentsAsList()
throws RestApiException {
throw new NotImplementedException();
}
@Override
public Map<String, List<CommentInfo>> drafts() throws RestApiException {
throw new NotImplementedException();
@@ -226,6 +242,11 @@ public interface RevisionApi {
throw new NotImplementedException();
}
@Override
public RobotCommentApi robotComment(String id) throws RestApiException {
throw new NotImplementedException();
}
@Override
public BinaryResult patch() throws RestApiException {
throw new NotImplementedException();

View File

@@ -0,0 +1,35 @@
// Copyright (C) 2016 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.google.gerrit.extensions.api.changes;
import com.google.gerrit.extensions.common.RobotCommentInfo;
import com.google.gerrit.extensions.restapi.NotImplementedException;
import com.google.gerrit.extensions.restapi.RestApiException;
public interface RobotCommentApi {
RobotCommentInfo get() throws RestApiException;
/**
* A default implementation which allows source compatibility
* when adding new methods to the interface.
**/
class NotImplemented implements RobotCommentApi {
@Override
public RobotCommentInfo get() throws RestApiException {
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,21 @@
// Copyright (C) 2016 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.google.gerrit.extensions.common;
public class RobotCommentInfo extends CommentInfo {
public String robotId;
public String robotRunId;
public String url;
}