Define API to invoke the REST API from within extensions and plugins

The REST API available over HTTP is planned to be supported for a long
time in the future.  It is very well documented and has fairly clean
resource semantics.  Extension and plugin authors want to use this API
from within the server itself to access resources, shielding them from
any internal changes.

GerritApi is a simple API exposed to plugins as an interface. The
API mirrors the REST API resource tree. Posting a review on a commit
is similar:

  @Inject
  private GerritApi api;
  [...]

  ReviewInput input = new ReviewInput();
  input.message = "Looks good!";
  input.labels = new HashMap<String, Short>();
  input.labels.put("Code-Review", (short) 2);

  api.changes().id(12345).revision("c0ffee....").review(input);

In this commit we provide only the basic skeleton and a single API
call for posting review comments.

An alternative approach is to use reflection to generate a proxy
implementation of the interfaces and bind everything dynamically at
runtime similar to the way RestApiServlet is implemented.  The hand
coded implementation offered here provides some compile-time
assurances the server has each API implemented and the API accepts the
correct input type.

Change-Id: Ic25c69c0660e2796d090a4a37445820726e543d2
This commit is contained in:
Shawn Pearce
2013-08-10 15:48:53 -07:00
parent 4dbf281d67
commit db99f5415f
20 changed files with 483 additions and 87 deletions

View File

@@ -18,10 +18,10 @@ import static org.junit.Assert.assertTrue;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.server.change.ChangeInserter;
import com.google.gerrit.server.change.ChangeResource;
import com.google.gerrit.server.change.PostReview;
import com.google.gerrit.server.change.RevisionResource;
import com.google.gerrit.server.project.ChangeControl;
@@ -70,13 +70,13 @@ public abstract class AbstractIndexQueryChangesTest
Change change = ins.insert();
ChangeControl ctl = changeControlFactory.controlFor(change, user);
PostReview.Input input = new PostReview.Input();
ReviewInput input = new ReviewInput();
input.message = "toplevel";
PostReview.Comment comment = new PostReview.Comment();
ReviewInput.Comment comment = new ReviewInput.Comment();
comment.line = 1;
comment.message = "inline";
input.comments = ImmutableMap.<String, List<PostReview.Comment>> of(
"Foo.java", ImmutableList.<PostReview.Comment> of(comment));
input.comments = ImmutableMap.<String, List<ReviewInput.Comment>> of(
"Foo.java", ImmutableList.<ReviewInput.Comment> of(comment));
postReview.apply(new RevisionResource(
new ChangeResource(ctl), ins.getPatchSet()), input);

View File

@@ -26,6 +26,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.hash.Hashing;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.restapi.TopLevelResource;
import com.google.gerrit.lifecycle.LifecycleManager;
import com.google.gerrit.reviewdb.client.Account;
@@ -359,7 +360,7 @@ public abstract class AbstractQueryChangesTest {
Change change = ins.insert();
ChangeControl ctl = changeControlFactory.controlFor(change, user);
PostReview.Input input = new PostReview.Input();
ReviewInput input = new ReviewInput();
input.message = "toplevel";
input.labels = ImmutableMap.<String, Short> of("Code-Review", (short) 1);
postReview.apply(new RevisionResource(
@@ -476,7 +477,7 @@ public abstract class AbstractQueryChangesTest {
assertResultEquals(change2, results.get(0));
assertResultEquals(change1, results.get(1));
PostReview.Input input = new PostReview.Input();
ReviewInput input = new ReviewInput();
input.message = "toplevel";
postReview.apply(new RevisionResource(
new ChangeResource(ctl1), ins1.getPatchSet()), input);
@@ -509,7 +510,7 @@ public abstract class AbstractQueryChangesTest {
assertResultEquals(change2, results.get(0));
assertResultEquals(change1, results.get(1));
PostReview.Input input = new PostReview.Input();
ReviewInput input = new ReviewInput();
input.message = "toplevel";
postReview.apply(new RevisionResource(
new ChangeResource(ctl1), ins1.getPatchSet()), input);