|
|
|
@@ -18,13 +18,13 @@ import com.google.common.collect.ImmutableList;
|
|
|
|
import com.google.common.collect.ImmutableMap;
|
|
|
|
import com.google.common.collect.ImmutableMap;
|
|
|
|
import com.google.common.collect.Lists;
|
|
|
|
import com.google.common.collect.Lists;
|
|
|
|
import com.google.common.collect.Maps;
|
|
|
|
import com.google.common.collect.Maps;
|
|
|
|
import com.google.common.util.concurrent.CheckedFuture;
|
|
|
|
|
|
|
|
import com.google.gerrit.common.ChangeHooks;
|
|
|
|
import com.google.gerrit.common.ChangeHooks;
|
|
|
|
|
|
|
|
import com.google.gerrit.common.TimeUtil;
|
|
|
|
import com.google.gerrit.common.data.GroupDescription;
|
|
|
|
import com.google.gerrit.common.data.GroupDescription;
|
|
|
|
import com.google.gerrit.common.errors.NoSuchGroupException;
|
|
|
|
import com.google.gerrit.common.errors.NoSuchGroupException;
|
|
|
|
import com.google.gerrit.extensions.api.changes.AddReviewerInput;
|
|
|
|
import com.google.gerrit.extensions.api.changes.AddReviewerInput;
|
|
|
|
import com.google.gerrit.extensions.restapi.AuthException;
|
|
|
|
|
|
|
|
import com.google.gerrit.extensions.restapi.BadRequestException;
|
|
|
|
import com.google.gerrit.extensions.restapi.BadRequestException;
|
|
|
|
|
|
|
|
import com.google.gerrit.extensions.restapi.RestApiException;
|
|
|
|
import com.google.gerrit.extensions.restapi.RestModifyView;
|
|
|
|
import com.google.gerrit.extensions.restapi.RestModifyView;
|
|
|
|
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
|
|
|
|
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
|
|
|
|
import com.google.gerrit.reviewdb.client.Account;
|
|
|
|
import com.google.gerrit.reviewdb.client.Account;
|
|
|
|
@@ -34,7 +34,6 @@ import com.google.gerrit.reviewdb.client.PatchSet;
|
|
|
|
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
|
|
|
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
|
|
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
|
|
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
|
|
|
import com.google.gerrit.server.ApprovalsUtil;
|
|
|
|
import com.google.gerrit.server.ApprovalsUtil;
|
|
|
|
import com.google.gerrit.server.ChangeUtil;
|
|
|
|
|
|
|
|
import com.google.gerrit.server.IdentifiedUser;
|
|
|
|
import com.google.gerrit.server.IdentifiedUser;
|
|
|
|
import com.google.gerrit.server.PatchSetUtil;
|
|
|
|
import com.google.gerrit.server.PatchSetUtil;
|
|
|
|
import com.google.gerrit.server.account.AccountCache;
|
|
|
|
import com.google.gerrit.server.account.AccountCache;
|
|
|
|
@@ -44,11 +43,11 @@ import com.google.gerrit.server.account.GroupMembers;
|
|
|
|
import com.google.gerrit.server.change.ReviewerJson.PostResult;
|
|
|
|
import com.google.gerrit.server.change.ReviewerJson.PostResult;
|
|
|
|
import com.google.gerrit.server.change.ReviewerJson.ReviewerInfo;
|
|
|
|
import com.google.gerrit.server.change.ReviewerJson.ReviewerInfo;
|
|
|
|
import com.google.gerrit.server.config.GerritServerConfig;
|
|
|
|
import com.google.gerrit.server.config.GerritServerConfig;
|
|
|
|
|
|
|
|
import com.google.gerrit.server.git.BatchUpdate;
|
|
|
|
|
|
|
|
import com.google.gerrit.server.git.UpdateException;
|
|
|
|
import com.google.gerrit.server.group.GroupsCollection;
|
|
|
|
import com.google.gerrit.server.group.GroupsCollection;
|
|
|
|
import com.google.gerrit.server.group.SystemGroupBackend;
|
|
|
|
import com.google.gerrit.server.group.SystemGroupBackend;
|
|
|
|
import com.google.gerrit.server.index.ChangeIndexer;
|
|
|
|
|
|
|
|
import com.google.gerrit.server.mail.AddReviewerSender;
|
|
|
|
import com.google.gerrit.server.mail.AddReviewerSender;
|
|
|
|
import com.google.gerrit.server.notedb.ChangeUpdate;
|
|
|
|
|
|
|
|
import com.google.gerrit.server.project.ChangeControl;
|
|
|
|
import com.google.gerrit.server.project.ChangeControl;
|
|
|
|
import com.google.gerrit.server.project.NoSuchProjectException;
|
|
|
|
import com.google.gerrit.server.project.NoSuchProjectException;
|
|
|
|
import com.google.gwtorm.server.OrmException;
|
|
|
|
import com.google.gwtorm.server.OrmException;
|
|
|
|
@@ -83,14 +82,13 @@ public class PostReviewers implements RestModifyView<ChangeResource, AddReviewer
|
|
|
|
private final GroupMembers.Factory groupMembersFactory;
|
|
|
|
private final GroupMembers.Factory groupMembersFactory;
|
|
|
|
private final AccountLoader.Factory accountLoaderFactory;
|
|
|
|
private final AccountLoader.Factory accountLoaderFactory;
|
|
|
|
private final Provider<ReviewDb> dbProvider;
|
|
|
|
private final Provider<ReviewDb> dbProvider;
|
|
|
|
private final ChangeUpdate.Factory updateFactory;
|
|
|
|
private final BatchUpdate.Factory batchUpdateFactory;
|
|
|
|
private final Provider<IdentifiedUser> user;
|
|
|
|
private final Provider<IdentifiedUser> user;
|
|
|
|
private final IdentifiedUser.GenericFactory identifiedUserFactory;
|
|
|
|
private final IdentifiedUser.GenericFactory identifiedUserFactory;
|
|
|
|
private final Config cfg;
|
|
|
|
private final Config cfg;
|
|
|
|
private final ChangeHooks hooks;
|
|
|
|
private final ChangeHooks hooks;
|
|
|
|
private final AccountCache accountCache;
|
|
|
|
private final AccountCache accountCache;
|
|
|
|
private final ReviewerJson json;
|
|
|
|
private final ReviewerJson json;
|
|
|
|
private final ChangeIndexer indexer;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Inject
|
|
|
|
@Inject
|
|
|
|
PostReviewers(AccountsCollection accounts,
|
|
|
|
PostReviewers(AccountsCollection accounts,
|
|
|
|
@@ -102,14 +100,13 @@ public class PostReviewers implements RestModifyView<ChangeResource, AddReviewer
|
|
|
|
GroupMembers.Factory groupMembersFactory,
|
|
|
|
GroupMembers.Factory groupMembersFactory,
|
|
|
|
AccountLoader.Factory accountLoaderFactory,
|
|
|
|
AccountLoader.Factory accountLoaderFactory,
|
|
|
|
Provider<ReviewDb> db,
|
|
|
|
Provider<ReviewDb> db,
|
|
|
|
ChangeUpdate.Factory updateFactory,
|
|
|
|
BatchUpdate.Factory batchUpdateFactory,
|
|
|
|
Provider<IdentifiedUser> user,
|
|
|
|
Provider<IdentifiedUser> user,
|
|
|
|
IdentifiedUser.GenericFactory identifiedUserFactory,
|
|
|
|
IdentifiedUser.GenericFactory identifiedUserFactory,
|
|
|
|
@GerritServerConfig Config cfg,
|
|
|
|
@GerritServerConfig Config cfg,
|
|
|
|
ChangeHooks hooks,
|
|
|
|
ChangeHooks hooks,
|
|
|
|
AccountCache accountCache,
|
|
|
|
AccountCache accountCache,
|
|
|
|
ReviewerJson json,
|
|
|
|
ReviewerJson json) {
|
|
|
|
ChangeIndexer indexer) {
|
|
|
|
|
|
|
|
this.accounts = accounts;
|
|
|
|
this.accounts = accounts;
|
|
|
|
this.reviewerFactory = reviewerFactory;
|
|
|
|
this.reviewerFactory = reviewerFactory;
|
|
|
|
this.approvalsUtil = approvalsUtil;
|
|
|
|
this.approvalsUtil = approvalsUtil;
|
|
|
|
@@ -119,20 +116,18 @@ public class PostReviewers implements RestModifyView<ChangeResource, AddReviewer
|
|
|
|
this.groupMembersFactory = groupMembersFactory;
|
|
|
|
this.groupMembersFactory = groupMembersFactory;
|
|
|
|
this.accountLoaderFactory = accountLoaderFactory;
|
|
|
|
this.accountLoaderFactory = accountLoaderFactory;
|
|
|
|
this.dbProvider = db;
|
|
|
|
this.dbProvider = db;
|
|
|
|
this.updateFactory = updateFactory;
|
|
|
|
this.batchUpdateFactory = batchUpdateFactory;
|
|
|
|
this.user = user;
|
|
|
|
this.user = user;
|
|
|
|
this.identifiedUserFactory = identifiedUserFactory;
|
|
|
|
this.identifiedUserFactory = identifiedUserFactory;
|
|
|
|
this.cfg = cfg;
|
|
|
|
this.cfg = cfg;
|
|
|
|
this.hooks = hooks;
|
|
|
|
this.hooks = hooks;
|
|
|
|
this.accountCache = accountCache;
|
|
|
|
this.accountCache = accountCache;
|
|
|
|
this.json = json;
|
|
|
|
this.json = json;
|
|
|
|
this.indexer = indexer;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public PostResult apply(ChangeResource rsrc, AddReviewerInput input)
|
|
|
|
public PostResult apply(ChangeResource rsrc, AddReviewerInput input)
|
|
|
|
throws AuthException, BadRequestException, UnprocessableEntityException,
|
|
|
|
throws UpdateException, OrmException, RestApiException, IOException {
|
|
|
|
OrmException, IOException {
|
|
|
|
|
|
|
|
if (input.reviewer == null) {
|
|
|
|
if (input.reviewer == null) {
|
|
|
|
throw new BadRequestException("missing reviewer field");
|
|
|
|
throw new BadRequestException("missing reviewer field");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -151,8 +146,8 @@ public class PostReviewers implements RestModifyView<ChangeResource, AddReviewer
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private PostResult putAccount(ReviewerResource rsrc) throws OrmException,
|
|
|
|
private PostResult putAccount(ReviewerResource rsrc)
|
|
|
|
IOException {
|
|
|
|
throws OrmException, UpdateException, RestApiException {
|
|
|
|
Account member = rsrc.getReviewerUser().getAccount();
|
|
|
|
Account member = rsrc.getReviewerUser().getAccount();
|
|
|
|
ChangeControl control = rsrc.getReviewerControl();
|
|
|
|
ChangeControl control = rsrc.getReviewerControl();
|
|
|
|
PostResult result = new PostResult();
|
|
|
|
PostResult result = new PostResult();
|
|
|
|
@@ -164,8 +159,7 @@ public class PostReviewers implements RestModifyView<ChangeResource, AddReviewer
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private PostResult putGroup(ChangeResource rsrc, AddReviewerInput input)
|
|
|
|
private PostResult putGroup(ChangeResource rsrc, AddReviewerInput input)
|
|
|
|
throws BadRequestException,
|
|
|
|
throws UpdateException, RestApiException, OrmException, IOException {
|
|
|
|
UnprocessableEntityException, OrmException, IOException {
|
|
|
|
|
|
|
|
GroupDescription.Basic group = groupsCollection.parseInternal(input.reviewer);
|
|
|
|
GroupDescription.Basic group = groupsCollection.parseInternal(input.reviewer);
|
|
|
|
PostResult result = new PostResult();
|
|
|
|
PostResult result = new PostResult();
|
|
|
|
if (!isLegalReviewerGroup(group.getGroupUUID())) {
|
|
|
|
if (!isLegalReviewerGroup(group.getGroupUUID())) {
|
|
|
|
@@ -179,7 +173,7 @@ public class PostReviewers implements RestModifyView<ChangeResource, AddReviewer
|
|
|
|
Set<Account> members;
|
|
|
|
Set<Account> members;
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
members = groupMembersFactory.create(control.getUser()).listAccounts(
|
|
|
|
members = groupMembersFactory.create(control.getUser()).listAccounts(
|
|
|
|
group.getGroupUUID(), control.getProject().getNameKey());
|
|
|
|
group.getGroupUUID(), control.getProject().getNameKey());
|
|
|
|
} catch (NoSuchGroupException e) {
|
|
|
|
} catch (NoSuchGroupException e) {
|
|
|
|
throw new UnprocessableEntityException(e.getMessage());
|
|
|
|
throw new UnprocessableEntityException(e.getMessage());
|
|
|
|
} catch (NoSuchProjectException e) {
|
|
|
|
} catch (NoSuchProjectException e) {
|
|
|
|
@@ -229,42 +223,72 @@ public class PostReviewers implements RestModifyView<ChangeResource, AddReviewer
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void addReviewers(ChangeResource rsrc, PostResult result,
|
|
|
|
|
|
|
|
Map<Account.Id, ChangeControl> reviewers)
|
|
|
|
private void addReviewers(
|
|
|
|
throws OrmException, IOException {
|
|
|
|
ChangeResource rsrc, PostResult result, Map<Account.Id, ChangeControl> reviewers)
|
|
|
|
ReviewDb db = dbProvider.get();
|
|
|
|
throws OrmException, RestApiException, UpdateException {
|
|
|
|
ChangeUpdate update = updateFactory.create(rsrc.getControl());
|
|
|
|
try (BatchUpdate bu = batchUpdateFactory.create(
|
|
|
|
List<PatchSetApproval> added;
|
|
|
|
dbProvider.get(), rsrc.getProject(), rsrc.getUser(), TimeUtil.nowTs())) {
|
|
|
|
db.changes().beginTransaction(rsrc.getId());
|
|
|
|
Op op = new Op(rsrc, reviewers);
|
|
|
|
try {
|
|
|
|
Change.Id id = rsrc.getChange().getId();
|
|
|
|
ChangeUtil.bumpRowVersionNotLastUpdatedOn(rsrc.getId(), db);
|
|
|
|
bu.addOp(id, op);
|
|
|
|
added = approvalsUtil.addReviewers(db, rsrc.getNotes(), update,
|
|
|
|
bu.execute();
|
|
|
|
rsrc.getControl().getLabelTypes(), rsrc.getChange(),
|
|
|
|
|
|
|
|
reviewers.keySet());
|
|
|
|
result.reviewers = Lists.newArrayListWithCapacity(op.added.size());
|
|
|
|
db.commit();
|
|
|
|
for (PatchSetApproval psa : op.added) {
|
|
|
|
} finally {
|
|
|
|
// New reviewers have value 0, don't bother normalizing.
|
|
|
|
db.rollback();
|
|
|
|
result.reviewers.add(
|
|
|
|
|
|
|
|
json.format(new ReviewerInfo(
|
|
|
|
|
|
|
|
psa.getAccountId()), reviewers.get(psa.getAccountId()),
|
|
|
|
|
|
|
|
ImmutableList.of(psa)));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// We don't do this inside Op, since the accounts are in a different
|
|
|
|
|
|
|
|
// table.
|
|
|
|
|
|
|
|
accountLoaderFactory.create(true).fill(result.reviewers);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private class Op extends BatchUpdate.Op {
|
|
|
|
|
|
|
|
private final ChangeResource rsrc;
|
|
|
|
|
|
|
|
private final Map<Account.Id, ChangeControl> reviewers;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private List<PatchSetApproval> added;
|
|
|
|
|
|
|
|
private PatchSet patchSet;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Op(ChangeResource rsrc, Map<Account.Id, ChangeControl> reviewers) {
|
|
|
|
|
|
|
|
this.rsrc = rsrc;
|
|
|
|
|
|
|
|
this.reviewers = reviewers;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
update.commit();
|
|
|
|
@Override
|
|
|
|
CheckedFuture<?, IOException> indexFuture =
|
|
|
|
public boolean updateChange(BatchUpdate.ChangeContext ctx)
|
|
|
|
indexer.indexAsync(rsrc.getProject(), rsrc.getId());
|
|
|
|
throws RestApiException, OrmException, IOException {
|
|
|
|
result.reviewers = Lists.newArrayListWithCapacity(added.size());
|
|
|
|
added =
|
|
|
|
for (PatchSetApproval psa : added) {
|
|
|
|
approvalsUtil.addReviewers(
|
|
|
|
// New reviewers have value 0, don't bother normalizing.
|
|
|
|
ctx.getDb(),
|
|
|
|
result.reviewers.add(json.format(
|
|
|
|
ctx.getNotes(),
|
|
|
|
new ReviewerInfo(psa.getAccountId()),
|
|
|
|
ctx.getUpdate(ctx.getChange().currentPatchSetId()),
|
|
|
|
reviewers.get(psa.getAccountId()),
|
|
|
|
rsrc.getControl().getLabelTypes(),
|
|
|
|
ImmutableList.of(psa)));
|
|
|
|
rsrc.getChange(),
|
|
|
|
|
|
|
|
reviewers.keySet());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!added.isEmpty()) {
|
|
|
|
|
|
|
|
patchSet = psUtil.current(dbProvider.get(), rsrc.getNotes());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return !added.isEmpty();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
accountLoaderFactory.create(true).fill(result.reviewers);
|
|
|
|
|
|
|
|
indexFuture.checkedGet();
|
|
|
|
@Override
|
|
|
|
emailReviewers(rsrc.getChange(), added);
|
|
|
|
public void postUpdate(BatchUpdate.Context ctx) throws Exception {
|
|
|
|
if (!added.isEmpty()) {
|
|
|
|
emailReviewers(rsrc.getChange(), added);
|
|
|
|
PatchSet patchSet = psUtil.current(dbProvider.get(), rsrc.getNotes());
|
|
|
|
|
|
|
|
for (PatchSetApproval psa : added) {
|
|
|
|
if (!added.isEmpty()) {
|
|
|
|
Account account = accountCache.get(psa.getAccountId()).getAccount();
|
|
|
|
for (PatchSetApproval psa : added) {
|
|
|
|
hooks.doReviewerAddedHook(rsrc.getChange(), account, patchSet, dbProvider.get());
|
|
|
|
Account account = accountCache.get(psa.getAccountId()).getAccount();
|
|
|
|
|
|
|
|
hooks.doReviewerAddedHook(
|
|
|
|
|
|
|
|
rsrc.getChange(), account, patchSet, dbProvider.get());
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|