Add ChangeMessagesUtil to assist with notedb migration
Like ApprovalsUtil, we added an abstraction layer to assist in the migration to notedb. This utility class helps to write to either the notedb or the reviewdb depending on the state of the NotesMigration instance. Additionally, in this change, I modified all callers of ChangeMessageAccess (which uses the ReviewDb) to instead use ChangeMessagesUtil. Change-Id: Id007ed8e01bd1318f70d804124e1f482a77234fd
This commit is contained in:
parent
9755152e9f
commit
086006ec35
@ -0,0 +1,76 @@
|
||||
// Copyright (C) 2014 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.server;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.gerrit.reviewdb.client.ChangeMessage;
|
||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.notedb.ChangeNotes;
|
||||
import com.google.gerrit.server.notedb.ChangeUpdate;
|
||||
import com.google.gerrit.server.notedb.NotesMigration;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Utility functions to manipulate ChangeMessages.
|
||||
* <p>
|
||||
* These methods either query for and update ChangeMessages in the NoteDb or
|
||||
* ReviewDb, depending on the state of the NotesMigration.
|
||||
*/
|
||||
@Singleton
|
||||
public class ChangeMessagesUtil {
|
||||
private static List<ChangeMessage> sortChangeMessages(
|
||||
Iterable<ChangeMessage> changeMessage) {
|
||||
return ChangeNotes.MESSAGE_BY_TIME.sortedCopy(changeMessage);
|
||||
}
|
||||
|
||||
private final NotesMigration migration;
|
||||
|
||||
@VisibleForTesting
|
||||
@Inject
|
||||
public ChangeMessagesUtil(NotesMigration migration) {
|
||||
this.migration = migration;
|
||||
}
|
||||
|
||||
public List<ChangeMessage> byChange(ReviewDb db, ChangeNotes notes) throws OrmException {
|
||||
if (!migration.readChangeMessages()) {
|
||||
return
|
||||
sortChangeMessages(db.changeMessages().byChange(notes.getChangeId()));
|
||||
} else {
|
||||
return sortChangeMessages(notes.load().getChangeMessages().values());
|
||||
}
|
||||
}
|
||||
|
||||
public List<ChangeMessage> byPatchSet(ReviewDb db, ChangeNotes notes,
|
||||
PatchSet.Id psId) throws OrmException {
|
||||
if (!migration.readChangeMessages()) {
|
||||
return sortChangeMessages(db.changeMessages().byPatchSet(psId));
|
||||
}
|
||||
return notes.load().getChangeMessages().get(psId);
|
||||
}
|
||||
|
||||
public void addChangeMessage(ReviewDb db, ChangeUpdate update,
|
||||
ChangeMessage changeMessage) throws OrmException {
|
||||
if (changeMessage != null) {
|
||||
update.setChangeMessage(changeMessage.getMessage());
|
||||
db.changeMessages().insert(Collections.singleton(changeMessage));
|
||||
}
|
||||
}
|
||||
}
|
@ -25,12 +25,14 @@ import com.google.gerrit.extensions.webui.UiAction;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.ChangeMessage;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.ChangeMessagesUtil;
|
||||
import com.google.gerrit.server.ChangeUtil;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.change.ChangeJson.ChangeInfo;
|
||||
import com.google.gerrit.server.index.ChangeIndexer;
|
||||
import com.google.gerrit.server.mail.AbandonedSender;
|
||||
import com.google.gerrit.server.mail.ReplyToChangeSender;
|
||||
import com.google.gerrit.server.notedb.ChangeUpdate;
|
||||
import com.google.gerrit.server.project.ChangeControl;
|
||||
import com.google.gwtorm.server.AtomicUpdate;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
@ -42,7 +44,6 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
|
||||
@Singleton
|
||||
public class Abandon implements RestModifyView<ChangeResource, AbandonInput>,
|
||||
@ -54,18 +55,24 @@ public class Abandon implements RestModifyView<ChangeResource, AbandonInput>,
|
||||
private final Provider<ReviewDb> dbProvider;
|
||||
private final ChangeJson json;
|
||||
private final ChangeIndexer indexer;
|
||||
private final ChangeUpdate.Factory updateFactory;
|
||||
private final ChangeMessagesUtil cmUtil;
|
||||
|
||||
@Inject
|
||||
Abandon(ChangeHooks hooks,
|
||||
AbandonedSender.Factory abandonedSenderFactory,
|
||||
Provider<ReviewDb> dbProvider,
|
||||
ChangeJson json,
|
||||
ChangeIndexer indexer) {
|
||||
ChangeIndexer indexer,
|
||||
ChangeUpdate.Factory updateFactory,
|
||||
ChangeMessagesUtil cmUtil) {
|
||||
this.hooks = hooks;
|
||||
this.abandonedSenderFactory = abandonedSenderFactory;
|
||||
this.dbProvider = dbProvider;
|
||||
this.json = json;
|
||||
this.indexer = indexer;
|
||||
this.updateFactory = updateFactory;
|
||||
this.cmUtil = cmUtil;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -84,6 +91,7 @@ public class Abandon implements RestModifyView<ChangeResource, AbandonInput>,
|
||||
}
|
||||
|
||||
ChangeMessage message;
|
||||
ChangeUpdate update;
|
||||
ReviewDb db = dbProvider.get();
|
||||
db.changes().beginTransaction(change.getId());
|
||||
try {
|
||||
@ -104,12 +112,16 @@ public class Abandon implements RestModifyView<ChangeResource, AbandonInput>,
|
||||
throw new ResourceConflictException("change is "
|
||||
+ status(db.changes().get(req.getChange().getId())));
|
||||
}
|
||||
|
||||
//TODO(yyonas): atomic update was not propagated
|
||||
update = updateFactory.create(control, change.getLastUpdatedOn());
|
||||
message = newMessage(input, caller, change);
|
||||
db.changeMessages().insert(Collections.singleton(message));
|
||||
cmUtil.addChangeMessage(db, update, message);
|
||||
db.commit();
|
||||
} finally {
|
||||
db.rollback();
|
||||
}
|
||||
update.commit();
|
||||
|
||||
CheckedFuture<?, IOException> indexFuture =
|
||||
indexer.indexAsync(change.getId());
|
||||
|
@ -27,6 +27,7 @@ import com.google.gerrit.reviewdb.client.PatchSetInfo;
|
||||
import com.google.gerrit.reviewdb.client.RevId;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.ApprovalsUtil;
|
||||
import com.google.gerrit.server.ChangeMessagesUtil;
|
||||
import com.google.gerrit.server.ChangeUtil;
|
||||
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
||||
import com.google.gerrit.server.mail.CreateChangeSender;
|
||||
@ -62,6 +63,7 @@ public class ChangeInserter {
|
||||
private final GitReferenceUpdated gitRefUpdated;
|
||||
private final ChangeHooks hooks;
|
||||
private final ApprovalsUtil approvalsUtil;
|
||||
private final ChangeMessagesUtil cmUtil;
|
||||
private final MergeabilityChecker mergeabilityChecker;
|
||||
private final CreateChangeSender.Factory createChangeSenderFactory;
|
||||
|
||||
@ -85,6 +87,7 @@ public class ChangeInserter {
|
||||
GitReferenceUpdated gitRefUpdated,
|
||||
ChangeHooks hooks,
|
||||
ApprovalsUtil approvalsUtil,
|
||||
ChangeMessagesUtil cmUtil,
|
||||
MergeabilityChecker mergeabilityChecker,
|
||||
CreateChangeSender.Factory createChangeSenderFactory,
|
||||
@Assisted RefControl refControl,
|
||||
@ -95,6 +98,7 @@ public class ChangeInserter {
|
||||
this.gitRefUpdated = gitRefUpdated;
|
||||
this.hooks = hooks;
|
||||
this.approvalsUtil = approvalsUtil;
|
||||
this.cmUtil = cmUtil;
|
||||
this.mergeabilityChecker = mergeabilityChecker;
|
||||
this.createChangeSenderFactory = createChangeSenderFactory;
|
||||
this.refControl = refControl;
|
||||
@ -181,20 +185,22 @@ public class ChangeInserter {
|
||||
approvalsUtil.addApprovals(db, update, labelTypes, patchSet, patchSetInfo,
|
||||
change, ctl, approvals);
|
||||
if (messageIsForChange()) {
|
||||
insertMessage(db);
|
||||
cmUtil.addChangeMessage(db, update, changeMessage);
|
||||
}
|
||||
db.commit();
|
||||
} finally {
|
||||
db.rollback();
|
||||
}
|
||||
|
||||
update.commit();
|
||||
if (messageIsForChange()) {
|
||||
update.commit();
|
||||
}
|
||||
CheckedFuture<?, IOException> f = mergeabilityChecker.newCheck()
|
||||
.addChange(change)
|
||||
.reindex()
|
||||
.runAsync();
|
||||
if (!messageIsForChange()) {
|
||||
insertMessage(db);
|
||||
|
||||
if(!messageIsForChange()) {
|
||||
commitMessageNotForChange();
|
||||
}
|
||||
gitRefUpdated.fire(change.getProject(), patchSet.getRefName(),
|
||||
ObjectId.zeroId(), commit);
|
||||
@ -220,14 +226,23 @@ public class ChangeInserter {
|
||||
return change;
|
||||
}
|
||||
|
||||
private void commitMessageNotForChange() throws OrmException,
|
||||
IOException {
|
||||
ReviewDb db = dbProvider.get();
|
||||
if (changeMessage != null) {
|
||||
Change otherChange =
|
||||
db.changes().get(changeMessage.getPatchSetId().getParentKey());
|
||||
ChangeControl otherControl =
|
||||
refControl.getProjectControl().controlFor(otherChange);
|
||||
ChangeUpdate updateForOtherChange =
|
||||
updateFactory.create(otherControl, change.getLastUpdatedOn());
|
||||
cmUtil.addChangeMessage(db, updateForOtherChange, changeMessage);
|
||||
updateForOtherChange.commit();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean messageIsForChange() {
|
||||
return changeMessage != null
|
||||
&& changeMessage.getKey().getParentKey().equals(change.getKey());
|
||||
}
|
||||
|
||||
private void insertMessage(ReviewDb db) throws OrmException {
|
||||
if (changeMessage != null) {
|
||||
db.changeMessages().insert(Collections.singleton(changeMessage));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,12 +74,14 @@ import com.google.gerrit.reviewdb.client.PatchSetInfo.ParentInfo;
|
||||
import com.google.gerrit.reviewdb.client.UserIdentity;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.AnonymousUser;
|
||||
import com.google.gerrit.server.ChangeMessagesUtil;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.WebLinks;
|
||||
import com.google.gerrit.server.account.AccountInfo;
|
||||
import com.google.gerrit.server.extensions.webui.UiActions;
|
||||
import com.google.gerrit.server.git.LabelNormalizer;
|
||||
import com.google.gerrit.server.notedb.ChangeNotes;
|
||||
import com.google.gerrit.server.patch.PatchListNotAvailableException;
|
||||
import com.google.gerrit.server.patch.PatchSetInfoFactory;
|
||||
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
|
||||
@ -88,7 +90,6 @@ import com.google.gerrit.server.project.ProjectControl;
|
||||
import com.google.gerrit.server.query.change.ChangeData;
|
||||
import com.google.gerrit.server.query.change.ChangeData.ChangedLines;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.gwtorm.server.ResultSet;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
@ -100,7 +101,6 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -108,22 +108,8 @@ import java.util.TreeMap;
|
||||
|
||||
public class ChangeJson {
|
||||
private static final Logger log = LoggerFactory.getLogger(ChangeJson.class);
|
||||
private static final ResultSet<ChangeMessage> NO_MESSAGES =
|
||||
new ResultSet<ChangeMessage>() {
|
||||
@Override
|
||||
public Iterator<ChangeMessage> iterator() {
|
||||
return toList().iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChangeMessage> toList() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
};
|
||||
private static final List<ChangeMessage> NO_MESSAGES =
|
||||
ImmutableList.of();
|
||||
|
||||
private final Provider<ReviewDb> db;
|
||||
private final LabelNormalizer labelNormalizer;
|
||||
@ -140,6 +126,7 @@ public class ChangeJson {
|
||||
private final Revisions revisions;
|
||||
private final Provider<WebLinks> webLinks;
|
||||
private final EnumSet<ListChangesOption> options;
|
||||
private final ChangeMessagesUtil cmUtil;
|
||||
|
||||
private AccountInfo.Loader accountLoader;
|
||||
|
||||
@ -159,7 +146,8 @@ public class ChangeJson {
|
||||
DynamicMap<DownloadCommand> downloadCommands,
|
||||
DynamicMap<RestView<ChangeResource>> changeViews,
|
||||
Revisions revisions,
|
||||
Provider<WebLinks> webLinks) {
|
||||
Provider<WebLinks> webLinks,
|
||||
ChangeMessagesUtil cmUtil) {
|
||||
this.db = db;
|
||||
this.labelNormalizer = ln;
|
||||
this.userProvider = user;
|
||||
@ -174,6 +162,7 @@ public class ChangeJson {
|
||||
this.changeViews = changeViews;
|
||||
this.revisions = revisions;
|
||||
this.webLinks = webLinks;
|
||||
this.cmUtil = cmUtil;
|
||||
options = EnumSet.noneOf(ListChangesOption.class);
|
||||
}
|
||||
|
||||
@ -642,8 +631,7 @@ public class ChangeJson {
|
||||
private Collection<ChangeMessageInfo> messages(ChangeControl ctl, ChangeData cd,
|
||||
Map<PatchSet.Id, PatchSet> map)
|
||||
throws OrmException {
|
||||
List<ChangeMessage> messages =
|
||||
db.get().changeMessages().byChange(cd.getId()).toList();
|
||||
List<ChangeMessage> messages = cmUtil.byChange(db.get(), cd.notes());
|
||||
if (messages.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@ -705,18 +693,18 @@ public class ChangeJson {
|
||||
if (userProvider.get().isIdentifiedUser()) {
|
||||
Account.Id self = ((IdentifiedUser) userProvider.get()).getAccountId();
|
||||
for (List<ChangeData> batch : Iterables.partition(all, 50)) {
|
||||
List<ResultSet<ChangeMessage>> m =
|
||||
List<List<ChangeMessage>> m =
|
||||
Lists.newArrayListWithCapacity(batch.size());
|
||||
for (ChangeData cd : batch) {
|
||||
PatchSet.Id ps = cd.change().currentPatchSetId();
|
||||
if (ps != null && cd.change().getStatus().isOpen()) {
|
||||
m.add(db.get().changeMessages().byPatchSet(ps));
|
||||
m.add(cmUtil.byPatchSet(db.get(), cd.notes(), ps));
|
||||
} else {
|
||||
m.add(NO_MESSAGES);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < m.size(); i++) {
|
||||
if (isChangeReviewed(self, batch.get(i), m.get(i).toList())) {
|
||||
if (isChangeReviewed(self, batch.get(i), m.get(i))) {
|
||||
reviewed.add(batch.get(i).getId());
|
||||
}
|
||||
}
|
||||
@ -728,12 +716,7 @@ public class ChangeJson {
|
||||
private boolean isChangeReviewed(Account.Id self, ChangeData cd,
|
||||
List<ChangeMessage> msgs) throws OrmException {
|
||||
// Sort messages to keep the most recent ones at the beginning.
|
||||
Collections.sort(msgs, new Comparator<ChangeMessage>() {
|
||||
@Override
|
||||
public int compare(ChangeMessage a, ChangeMessage b) {
|
||||
return b.getWrittenOn().compareTo(a.getWrittenOn());
|
||||
}
|
||||
});
|
||||
msgs = ChangeNotes.MESSAGE_BY_TIME.sortedCopy(msgs);
|
||||
|
||||
Account.Id changeOwnerId = cd.change().getOwner();
|
||||
for (ChangeMessage cm : msgs) {
|
||||
|
@ -27,6 +27,7 @@ import com.google.gerrit.reviewdb.client.ChangeMessage;
|
||||
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.ApprovalsUtil;
|
||||
import com.google.gerrit.server.ChangeMessagesUtil;
|
||||
import com.google.gerrit.server.ChangeUtil;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.change.DeleteReviewer.Input;
|
||||
@ -40,7 +41,6 @@ import com.google.inject.Provider;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
@ -51,6 +51,7 @@ public class DeleteReviewer implements RestModifyView<ReviewerResource, Input> {
|
||||
private final Provider<ReviewDb> dbProvider;
|
||||
private final ChangeUpdate.Factory updateFactory;
|
||||
private final ApprovalsUtil approvalsUtil;
|
||||
private final ChangeMessagesUtil cmUtil;
|
||||
private final ChangeIndexer indexer;
|
||||
private final IdentifiedUser.GenericFactory userFactory;
|
||||
|
||||
@ -58,11 +59,13 @@ public class DeleteReviewer implements RestModifyView<ReviewerResource, Input> {
|
||||
DeleteReviewer(Provider<ReviewDb> dbProvider,
|
||||
ChangeUpdate.Factory updateFactory,
|
||||
ApprovalsUtil approvalsUtil,
|
||||
ChangeMessagesUtil cmUtil,
|
||||
ChangeIndexer indexer,
|
||||
IdentifiedUser.GenericFactory userFactory) {
|
||||
this.dbProvider = dbProvider;
|
||||
this.updateFactory = updateFactory;
|
||||
this.approvalsUtil = approvalsUtil;
|
||||
this.cmUtil = cmUtil;
|
||||
this.indexer = indexer;
|
||||
this.userFactory = userFactory;
|
||||
}
|
||||
@ -111,7 +114,7 @@ public class DeleteReviewer implements RestModifyView<ReviewerResource, Input> {
|
||||
((IdentifiedUser) control.getCurrentUser()).getAccountId(),
|
||||
TimeUtil.nowTs(), rsrc.getChange().currentPatchSetId());
|
||||
changeMessage.setMessage(msg.toString());
|
||||
db.changeMessages().insert(Collections.singleton(changeMessage));
|
||||
cmUtil.addChangeMessage(db, update, changeMessage);
|
||||
}
|
||||
|
||||
db.commit();
|
||||
|
@ -29,6 +29,7 @@ import com.google.gerrit.reviewdb.client.RevId;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.ApprovalCopier;
|
||||
import com.google.gerrit.server.ApprovalsUtil;
|
||||
import com.google.gerrit.server.ChangeMessagesUtil;
|
||||
import com.google.gerrit.server.ChangeUtil;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.events.CommitReceivedEvent;
|
||||
@ -41,6 +42,7 @@ import com.google.gerrit.server.notedb.ReviewerState;
|
||||
import com.google.gerrit.server.patch.PatchSetInfoFactory;
|
||||
import com.google.gerrit.server.project.ChangeControl;
|
||||
import com.google.gerrit.server.project.InvalidChangeOperationException;
|
||||
import com.google.gerrit.server.project.NoSuchChangeException;
|
||||
import com.google.gerrit.server.ssh.NoSshInfo;
|
||||
import com.google.gerrit.server.ssh.SshInfo;
|
||||
import com.google.gerrit.server.util.TimeUtil;
|
||||
@ -83,12 +85,14 @@ public class PatchSetInserter {
|
||||
private final PatchSetInfoFactory patchSetInfoFactory;
|
||||
private final ReviewDb db;
|
||||
private final ChangeUpdate.Factory updateFactory;
|
||||
private final ChangeControl.GenericFactory ctlFactory;
|
||||
private final GitReferenceUpdated gitRefUpdated;
|
||||
private final CommitValidators.Factory commitValidatorsFactory;
|
||||
private final MergeabilityChecker mergeabilityChecker;
|
||||
private final ReplacePatchSetSender.Factory replacePatchSetFactory;
|
||||
private final ApprovalsUtil approvalsUtil;
|
||||
private final ApprovalCopier approvalCopier;
|
||||
private final ChangeMessagesUtil cmUtil;
|
||||
|
||||
private final Repository git;
|
||||
private final RevWalk revWalk;
|
||||
@ -110,8 +114,10 @@ public class PatchSetInserter {
|
||||
public PatchSetInserter(ChangeHooks hooks,
|
||||
ReviewDb db,
|
||||
ChangeUpdate.Factory updateFactory,
|
||||
ChangeControl.GenericFactory ctlFactory,
|
||||
ApprovalsUtil approvalsUtil,
|
||||
ApprovalCopier approvalCopier,
|
||||
ChangeMessagesUtil cmUtil,
|
||||
PatchSetInfoFactory patchSetInfoFactory,
|
||||
GitReferenceUpdated gitRefUpdated,
|
||||
CommitValidators.Factory commitValidatorsFactory,
|
||||
@ -127,8 +133,10 @@ public class PatchSetInserter {
|
||||
this.hooks = hooks;
|
||||
this.db = db;
|
||||
this.updateFactory = updateFactory;
|
||||
this.ctlFactory = ctlFactory;
|
||||
this.approvalsUtil = approvalsUtil;
|
||||
this.approvalCopier = approvalCopier;
|
||||
this.cmUtil = cmUtil;
|
||||
this.patchSetInfoFactory = patchSetInfoFactory;
|
||||
this.gitRefUpdated = gitRefUpdated;
|
||||
this.commitValidatorsFactory = commitValidatorsFactory;
|
||||
@ -212,7 +220,7 @@ public class PatchSetInserter {
|
||||
}
|
||||
|
||||
public Change insert() throws InvalidChangeOperationException, OrmException,
|
||||
IOException {
|
||||
IOException, NoSuchChangeException {
|
||||
init();
|
||||
validate();
|
||||
|
||||
@ -273,17 +281,19 @@ public class PatchSetInserter {
|
||||
}
|
||||
|
||||
if (messageIsForChange()) {
|
||||
insertMessage(db);
|
||||
cmUtil.addChangeMessage(db, update, changeMessage);
|
||||
}
|
||||
|
||||
if (copyLabels) {
|
||||
approvalCopier.copy(db, ctl, patchSet);
|
||||
}
|
||||
db.commit();
|
||||
update.commit();
|
||||
if (messageIsForChange()) {
|
||||
update.commit();
|
||||
}
|
||||
|
||||
if (!messageIsForChange()) {
|
||||
insertMessage(db);
|
||||
commitMessageNotForChange(updatedChange);
|
||||
}
|
||||
|
||||
if (sendMail) {
|
||||
@ -317,6 +327,20 @@ public class PatchSetInserter {
|
||||
return updatedChange;
|
||||
}
|
||||
|
||||
private void commitMessageNotForChange(Change updatedChange)
|
||||
throws OrmException, NoSuchChangeException, IOException {
|
||||
if (changeMessage != null) {
|
||||
Change otherChange =
|
||||
db.changes().get(changeMessage.getPatchSetId().getParentKey());
|
||||
ChangeControl otherControl =
|
||||
ctlFactory.controlFor(otherChange, user);
|
||||
ChangeUpdate updateForOtherChange =
|
||||
updateFactory.create(otherControl, updatedChange.getLastUpdatedOn());
|
||||
cmUtil.addChangeMessage(db, updateForOtherChange, changeMessage);
|
||||
updateForOtherChange.commit();
|
||||
}
|
||||
}
|
||||
|
||||
private void init() throws IOException {
|
||||
if (sshInfo == null) {
|
||||
sshInfo = new NoSshInfo();
|
||||
@ -368,12 +392,6 @@ public class PatchSetInserter {
|
||||
.equals(patchSet.getId().getParentKey());
|
||||
}
|
||||
|
||||
private void insertMessage(ReviewDb db) throws OrmException {
|
||||
if (changeMessage != null) {
|
||||
db.changeMessages().insert(Collections.singleton(changeMessage));
|
||||
}
|
||||
}
|
||||
|
||||
public class ChangeModifiedException extends InvalidChangeOperationException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
@ -46,6 +46,7 @@ import com.google.gerrit.reviewdb.client.PatchLineComment;
|
||||
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.ApprovalsUtil;
|
||||
import com.google.gerrit.server.ChangeMessagesUtil;
|
||||
import com.google.gerrit.server.ChangeUtil;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.account.AccountsCollection;
|
||||
@ -82,6 +83,7 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
|
||||
private final ChangeData.Factory changeDataFactory;
|
||||
private final ChangeUpdate.Factory updateFactory;
|
||||
private final ApprovalsUtil approvalsUtil;
|
||||
private final ChangeMessagesUtil cmUtil;
|
||||
private final ChangeIndexer indexer;
|
||||
private final AccountsCollection accounts;
|
||||
private final EmailReviewComments.Factory email;
|
||||
@ -100,6 +102,7 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
|
||||
ChangeData.Factory changeDataFactory,
|
||||
ChangeUpdate.Factory updateFactory,
|
||||
ApprovalsUtil approvalsUtil,
|
||||
ChangeMessagesUtil cmUtil,
|
||||
ChangeIndexer indexer,
|
||||
AccountsCollection accounts,
|
||||
EmailReviewComments.Factory email,
|
||||
@ -109,6 +112,7 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
|
||||
this.changeDataFactory = changeDataFactory;
|
||||
this.updateFactory = updateFactory;
|
||||
this.approvalsUtil = approvalsUtil;
|
||||
this.cmUtil = cmUtil;
|
||||
this.indexer = indexer;
|
||||
this.accounts = accounts;
|
||||
this.email = email;
|
||||
@ -144,7 +148,7 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
|
||||
update = updateFactory.create(revision.getControl(), timestamp);
|
||||
dirty |= insertComments(revision, input.comments, input.drafts);
|
||||
dirty |= updateLabels(revision, update, input.labels);
|
||||
dirty |= insertMessage(revision, input.message);
|
||||
dirty |= insertMessage(revision, input.message, update);
|
||||
if (dirty) {
|
||||
db.get().changes().update(Collections.singleton(change));
|
||||
db.get().commit();
|
||||
@ -505,8 +509,8 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
|
||||
labelDelta.add(new LabelVote(name, value).format());
|
||||
}
|
||||
|
||||
private boolean insertMessage(RevisionResource rsrc, String msg)
|
||||
throws OrmException {
|
||||
private boolean insertMessage(RevisionResource rsrc, String msg,
|
||||
ChangeUpdate update) throws OrmException {
|
||||
msg = Strings.nullToEmpty(msg).trim();
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
@ -534,7 +538,7 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
|
||||
"Patch Set %d:%s",
|
||||
rsrc.getPatchSet().getPatchSetId(),
|
||||
buf.toString()));
|
||||
db.get().changeMessages().insert(Collections.singleton(message));
|
||||
cmUtil.addChangeMessage(db.get(), update, message);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -25,10 +25,12 @@ import com.google.gerrit.extensions.webui.UiAction;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.ChangeMessage;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.ChangeMessagesUtil;
|
||||
import com.google.gerrit.server.ChangeUtil;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.change.PutTopic.Input;
|
||||
import com.google.gerrit.server.index.ChangeIndexer;
|
||||
import com.google.gerrit.server.notedb.ChangeUpdate;
|
||||
import com.google.gerrit.server.project.ChangeControl;
|
||||
import com.google.gerrit.server.util.TimeUtil;
|
||||
import com.google.gwtorm.server.AtomicUpdate;
|
||||
@ -38,7 +40,6 @@ import com.google.inject.Provider;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
|
||||
@Singleton
|
||||
class PutTopic implements RestModifyView<ChangeResource, Input>,
|
||||
@ -46,6 +47,8 @@ class PutTopic implements RestModifyView<ChangeResource, Input>,
|
||||
private final Provider<ReviewDb> dbProvider;
|
||||
private final ChangeIndexer indexer;
|
||||
private final ChangeHooks hooks;
|
||||
private final ChangeUpdate.Factory updateFactory;
|
||||
private final ChangeMessagesUtil cmUtil;
|
||||
|
||||
static class Input {
|
||||
@DefaultInput
|
||||
@ -54,10 +57,13 @@ class PutTopic implements RestModifyView<ChangeResource, Input>,
|
||||
|
||||
@Inject
|
||||
PutTopic(Provider<ReviewDb> dbProvider, ChangeIndexer indexer,
|
||||
ChangeHooks hooks) {
|
||||
ChangeHooks hooks, ChangeUpdate.Factory updateFactory,
|
||||
ChangeMessagesUtil cmUtil) {
|
||||
this.dbProvider = dbProvider;
|
||||
this.indexer = indexer;
|
||||
this.hooks = hooks;
|
||||
this.updateFactory = updateFactory;
|
||||
this.cmUtil = cmUtil;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -94,6 +100,7 @@ class PutTopic implements RestModifyView<ChangeResource, Input>,
|
||||
currentUser.getAccountId(), TimeUtil.nowTs(),
|
||||
change.currentPatchSetId());
|
||||
cmsg.setMessage(summary);
|
||||
ChangeUpdate update;
|
||||
|
||||
db.changes().beginTransaction(change.getId());
|
||||
try {
|
||||
@ -106,11 +113,16 @@ class PutTopic implements RestModifyView<ChangeResource, Input>,
|
||||
return change;
|
||||
}
|
||||
});
|
||||
db.changeMessages().insert(Collections.singleton(cmsg));
|
||||
|
||||
//TODO(yyonas): atomic update was not propagated
|
||||
update = updateFactory.create(control);
|
||||
cmUtil.addChangeMessage(db, update, cmsg);
|
||||
|
||||
db.commit();
|
||||
} finally {
|
||||
db.rollback();
|
||||
}
|
||||
update.commit();
|
||||
CheckedFuture<?, IOException> indexFuture =
|
||||
indexer.indexAsync(change.getId());
|
||||
hooks.doTopicChangedHook(change, currentUser.getAccount(),
|
||||
|
@ -26,11 +26,13 @@ import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.Change.Status;
|
||||
import com.google.gerrit.reviewdb.client.ChangeMessage;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.ChangeMessagesUtil;
|
||||
import com.google.gerrit.server.ChangeUtil;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.change.ChangeJson.ChangeInfo;
|
||||
import com.google.gerrit.server.mail.ReplyToChangeSender;
|
||||
import com.google.gerrit.server.mail.RestoredSender;
|
||||
import com.google.gerrit.server.notedb.ChangeUpdate;
|
||||
import com.google.gerrit.server.project.ChangeControl;
|
||||
import com.google.gwtorm.server.AtomicUpdate;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
@ -42,7 +44,6 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
|
||||
@Singleton
|
||||
public class Restore implements RestModifyView<ChangeResource, RestoreInput>,
|
||||
@ -54,18 +55,24 @@ public class Restore implements RestModifyView<ChangeResource, RestoreInput>,
|
||||
private final Provider<ReviewDb> dbProvider;
|
||||
private final ChangeJson json;
|
||||
private final MergeabilityChecker mergeabilityChecker;
|
||||
private final ChangeMessagesUtil cmUtil;
|
||||
private final ChangeUpdate.Factory updateFactory;
|
||||
|
||||
@Inject
|
||||
Restore(ChangeHooks hooks,
|
||||
RestoredSender.Factory restoredSenderFactory,
|
||||
Provider<ReviewDb> dbProvider,
|
||||
ChangeJson json,
|
||||
MergeabilityChecker mergeabilityChecker) {
|
||||
MergeabilityChecker mergeabilityChecker,
|
||||
ChangeMessagesUtil cmUtil,
|
||||
ChangeUpdate.Factory updateFactory) {
|
||||
this.hooks = hooks;
|
||||
this.restoredSenderFactory = restoredSenderFactory;
|
||||
this.dbProvider = dbProvider;
|
||||
this.json = json;
|
||||
this.mergeabilityChecker = mergeabilityChecker;
|
||||
this.cmUtil = cmUtil;
|
||||
this.updateFactory = updateFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -82,6 +89,7 @@ public class Restore implements RestModifyView<ChangeResource, RestoreInput>,
|
||||
}
|
||||
|
||||
ChangeMessage message;
|
||||
ChangeUpdate update;
|
||||
ReviewDb db = dbProvider.get();
|
||||
db.changes().beginTransaction(change.getId());
|
||||
try {
|
||||
@ -102,12 +110,16 @@ public class Restore implements RestModifyView<ChangeResource, RestoreInput>,
|
||||
throw new ResourceConflictException("change is "
|
||||
+ status(db.changes().get(req.getChange().getId())));
|
||||
}
|
||||
|
||||
//TODO(yyonas): atomic update was not propagated
|
||||
update = updateFactory.create(control);
|
||||
message = newMessage(input, caller, change);
|
||||
db.changeMessages().insert(Collections.singleton(message));
|
||||
cmUtil.addChangeMessage(db, update, message);
|
||||
db.commit();
|
||||
} finally {
|
||||
db.rollback();
|
||||
}
|
||||
update.commit();
|
||||
|
||||
CheckedFuture<?, IOException> f = mergeabilityChecker.newCheck()
|
||||
.addChange(change)
|
||||
|
@ -20,11 +20,11 @@ import com.google.common.base.Objects;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.collect.HashBasedTable;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Table;
|
||||
import com.google.gerrit.common.data.ParameterizedString;
|
||||
@ -44,6 +44,7 @@ import com.google.gerrit.reviewdb.client.PatchSetApproval.LabelId;
|
||||
import com.google.gerrit.reviewdb.client.RevId;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.ApprovalsUtil;
|
||||
import com.google.gerrit.server.ChangeMessagesUtil;
|
||||
import com.google.gerrit.server.ChangeUtil;
|
||||
import com.google.gerrit.server.GerritPersonIdent;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
@ -103,6 +104,7 @@ public class Submit implements RestModifyView<RevisionResource, SubmitInput>,
|
||||
private final IdentifiedUser.GenericFactory userFactory;
|
||||
private final ChangeUpdate.Factory updateFactory;
|
||||
private final ApprovalsUtil approvalsUtil;
|
||||
private final ChangeMessagesUtil cmUtil;
|
||||
private final MergeQueue mergeQueue;
|
||||
private final ChangeIndexer indexer;
|
||||
private final LabelNormalizer labelNormalizer;
|
||||
@ -118,6 +120,7 @@ public class Submit implements RestModifyView<RevisionResource, SubmitInput>,
|
||||
IdentifiedUser.GenericFactory userFactory,
|
||||
ChangeUpdate.Factory updateFactory,
|
||||
ApprovalsUtil approvalsUtil,
|
||||
ChangeMessagesUtil cmUtil,
|
||||
MergeQueue mergeQueue,
|
||||
AccountsCollection accounts,
|
||||
ChangesCollection changes,
|
||||
@ -130,6 +133,7 @@ public class Submit implements RestModifyView<RevisionResource, SubmitInput>,
|
||||
this.userFactory = userFactory;
|
||||
this.updateFactory = updateFactory;
|
||||
this.approvalsUtil = approvalsUtil;
|
||||
this.cmUtil = cmUtil;
|
||||
this.mergeQueue = mergeQueue;
|
||||
this.accounts = accounts;
|
||||
this.changes = changes;
|
||||
@ -226,16 +230,16 @@ public class Submit implements RestModifyView<RevisionResource, SubmitInput>,
|
||||
*/
|
||||
public ChangeMessage getConflictMessage(RevisionResource rsrc)
|
||||
throws OrmException {
|
||||
return Iterables.getFirst(Iterables.filter(
|
||||
Lists.reverse(dbProvider.get().changeMessages()
|
||||
.byChange(rsrc.getChange().getId())
|
||||
.toList()),
|
||||
new Predicate<ChangeMessage>() {
|
||||
@Override
|
||||
public boolean apply(ChangeMessage input) {
|
||||
return input.getAuthor() == null;
|
||||
}
|
||||
}), null);
|
||||
return FluentIterable.from(cmUtil.byPatchSet(dbProvider.get(), rsrc.getNotes(),
|
||||
rsrc.getPatchSet().getId()))
|
||||
.filter(new Predicate<ChangeMessage>() {
|
||||
@Override
|
||||
public boolean apply(ChangeMessage input) {
|
||||
return input.getAuthor() == null;
|
||||
}
|
||||
})
|
||||
.last()
|
||||
.orNull();
|
||||
}
|
||||
|
||||
public Change submit(RevisionResource rsrc, IdentifiedUser caller,
|
||||
|
@ -23,7 +23,6 @@ import com.google.gerrit.server.util.RequestScopePropagator;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import com.google.inject.name.Named;
|
||||
import com.google.inject.PrivateModule;
|
||||
import com.google.inject.Provides;
|
||||
|
@ -42,6 +42,7 @@ import com.google.gerrit.reviewdb.client.RefNames;
|
||||
import com.google.gerrit.reviewdb.client.RevId;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.ApprovalsUtil;
|
||||
import com.google.gerrit.server.ChangeMessagesUtil;
|
||||
import com.google.gerrit.server.ChangeUtil;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.account.AccountCache;
|
||||
@ -54,6 +55,7 @@ import com.google.gerrit.server.index.ChangeIndexer;
|
||||
import com.google.gerrit.server.mail.MergeFailSender;
|
||||
import com.google.gerrit.server.mail.MergedSender;
|
||||
import com.google.gerrit.server.notedb.ChangeNotes;
|
||||
import com.google.gerrit.server.notedb.ChangeUpdate;
|
||||
import com.google.gerrit.server.patch.PatchSetInfoFactory;
|
||||
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
|
||||
import com.google.gerrit.server.project.ChangeControl;
|
||||
@ -88,7 +90,6 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
@ -137,9 +138,11 @@ public class MergeOp {
|
||||
private final PatchSetInfoFactory patchSetInfoFactory;
|
||||
private final IdentifiedUser.GenericFactory identifiedUserFactory;
|
||||
private final ChangeControl.GenericFactory changeControlFactory;
|
||||
private final ChangeUpdate.Factory updateFactory;
|
||||
private final MergeQueue mergeQueue;
|
||||
private final MergeValidators.Factory mergeValidatorsFactory;
|
||||
private final ApprovalsUtil approvalsUtil;
|
||||
private final ChangeMessagesUtil cmUtil;
|
||||
|
||||
private final Branch.NameKey destBranch;
|
||||
private ProjectState destProject;
|
||||
@ -173,6 +176,7 @@ public class MergeOp {
|
||||
final MergeFailSender.Factory mfsf,
|
||||
final PatchSetInfoFactory psif, final IdentifiedUser.GenericFactory iuf,
|
||||
final ChangeControl.GenericFactory changeControlFactory,
|
||||
final ChangeUpdate.Factory updateFactory,
|
||||
final MergeQueue mergeQueue, @Assisted final Branch.NameKey branch,
|
||||
final ChangeHooks hooks, final AccountCache accountCache,
|
||||
final TagCache tagCache,
|
||||
@ -182,7 +186,8 @@ public class MergeOp {
|
||||
final RequestScopePropagator requestScopePropagator,
|
||||
final ChangeIndexer indexer,
|
||||
final MergeValidators.Factory mergeValidatorsFactory,
|
||||
final ApprovalsUtil approvalsUtil) {
|
||||
final ApprovalsUtil approvalsUtil,
|
||||
final ChangeMessagesUtil cmUtil) {
|
||||
repoManager = grm;
|
||||
schemaFactory = sf;
|
||||
notesFactory = nf;
|
||||
@ -193,6 +198,7 @@ public class MergeOp {
|
||||
patchSetInfoFactory = psif;
|
||||
identifiedUserFactory = iuf;
|
||||
this.changeControlFactory = changeControlFactory;
|
||||
this.updateFactory = updateFactory;
|
||||
this.mergeQueue = mergeQueue;
|
||||
this.hooks = hooks;
|
||||
this.accountCache = accountCache;
|
||||
@ -204,6 +210,7 @@ public class MergeOp {
|
||||
this.indexer = indexer;
|
||||
this.mergeValidatorsFactory = mergeValidatorsFactory;
|
||||
this.approvalsUtil = approvalsUtil;
|
||||
this.cmUtil = cmUtil;
|
||||
destBranch = branch;
|
||||
toMerge = ArrayListMultimap.create();
|
||||
potentiallyStillSubmittable = new ArrayList<>();
|
||||
@ -224,7 +231,7 @@ public class MergeOp {
|
||||
}
|
||||
}
|
||||
|
||||
public void merge() throws MergeException {
|
||||
public void merge() throws MergeException, NoSuchChangeException, IOException {
|
||||
setDestProject();
|
||||
try {
|
||||
openSchema();
|
||||
@ -395,7 +402,7 @@ public class MergeOp {
|
||||
inserter = repo.newObjectInserter();
|
||||
}
|
||||
|
||||
private RefUpdate openBranch() throws MergeException, OrmException {
|
||||
private RefUpdate openBranch() throws MergeException, OrmException, NoSuchChangeException {
|
||||
try {
|
||||
final RefUpdate branchUpdate = repo.updateRef(destBranch.get());
|
||||
if (branchUpdate.getOldObjectId() != null) {
|
||||
@ -442,7 +449,7 @@ public class MergeOp {
|
||||
}
|
||||
|
||||
private ListMultimap<SubmitType, Change> validateChangeList(
|
||||
final List<Change> submitted) throws MergeException {
|
||||
final List<Change> submitted) throws MergeException, NoSuchChangeException {
|
||||
final ListMultimap<SubmitType, Change> toSubmit =
|
||||
ArrayListMultimap.create();
|
||||
|
||||
@ -658,7 +665,7 @@ public class MergeOp {
|
||||
hooks.doRefUpdatedHook(destBranch, branchUpdate, account);
|
||||
}
|
||||
|
||||
private void updateChangeStatus(final List<Change> submitted) {
|
||||
private void updateChangeStatus(final List<Change> submitted) throws NoSuchChangeException {
|
||||
for (final Change c : submitted) {
|
||||
final CodeReviewCommit commit = commits.get(c.getId());
|
||||
final CommitMergeStatus s = commit != null ? commit.getStatusCode() : null;
|
||||
@ -824,7 +831,8 @@ public class MergeOp {
|
||||
}
|
||||
|
||||
private void setMerged(Change c, ChangeMessage msg)
|
||||
throws OrmException, IOException {
|
||||
throws OrmException, IOException, NoSuchChangeException {
|
||||
ChangeUpdate update = null;
|
||||
try {
|
||||
db.changes().beginTransaction(c.getId());
|
||||
|
||||
@ -835,8 +843,13 @@ public class MergeOp {
|
||||
c = setMergedPatchSet(c.getId(), merged);
|
||||
PatchSetApproval submitter =
|
||||
approvalsUtil.getSubmitter(db, commit.notes(), merged);
|
||||
addMergedMessage(submitter, msg);
|
||||
ChangeControl control = commit.getControl();
|
||||
update = updateFactory.create(control, c.getLastUpdatedOn());
|
||||
|
||||
// TODO(yyonas): we need to be able to change the author of the message
|
||||
// is not the person for whom the change was made. addMergedMessage
|
||||
// did this in the past.
|
||||
cmUtil.addChangeMessage(db, update, msg);
|
||||
db.commit();
|
||||
|
||||
sendMergedEmail(c, submitter);
|
||||
@ -853,6 +866,7 @@ public class MergeOp {
|
||||
db.rollback();
|
||||
}
|
||||
indexer.index(db, c);
|
||||
update.commit();
|
||||
}
|
||||
|
||||
private Change setMergedPatchSet(Change.Id changeId, final PatchSet.Id merged)
|
||||
@ -881,16 +895,6 @@ public class MergeOp {
|
||||
});
|
||||
}
|
||||
|
||||
private void addMergedMessage(PatchSetApproval submitter, ChangeMessage msg)
|
||||
throws OrmException {
|
||||
if (msg != null) {
|
||||
if (submitter != null && msg.getAuthor() == null) {
|
||||
msg.setAuthor(submitter.getAccountId());
|
||||
}
|
||||
db.changeMessages().insert(Collections.singleton(msg));
|
||||
}
|
||||
}
|
||||
|
||||
private void sendMergedEmail(final Change c, final PatchSetApproval from) {
|
||||
workQueue.getDefaultQueue()
|
||||
.submit(requestScopePropagator.wrap(new Runnable() {
|
||||
@ -933,11 +937,11 @@ public class MergeOp {
|
||||
c, identifiedUserFactory.create(c.getOwner()));
|
||||
}
|
||||
|
||||
private void setNew(CodeReviewCommit c, ChangeMessage msg) {
|
||||
private void setNew(CodeReviewCommit c, ChangeMessage msg) throws NoSuchChangeException, IOException {
|
||||
sendMergeFail(c.notes(), msg, true);
|
||||
}
|
||||
|
||||
private void setNew(Change c, ChangeMessage msg) throws OrmException {
|
||||
private void setNew(Change c, ChangeMessage msg) throws OrmException, NoSuchChangeException, IOException {
|
||||
sendMergeFail(notesFactory.create(c), msg, true);
|
||||
}
|
||||
|
||||
@ -947,7 +951,8 @@ public class MergeOp {
|
||||
|
||||
private RetryStatus getRetryStatus(
|
||||
@Nullable PatchSetApproval submitter,
|
||||
ChangeMessage msg) {
|
||||
ChangeMessage msg,
|
||||
ChangeNotes notes) {
|
||||
if (submitter != null
|
||||
&& TimeUtil.nowMs() - submitter.getGranted().getTime()
|
||||
> MAX_SUBMIT_WINDOW) {
|
||||
@ -955,8 +960,7 @@ public class MergeOp {
|
||||
}
|
||||
|
||||
try {
|
||||
ChangeMessage last = Iterables.getLast(db.changeMessages().byChange(
|
||||
msg.getPatchSetId().getParentKey()), null);
|
||||
ChangeMessage last = Iterables.getLast(cmUtil.byChange(db, notes));
|
||||
if (last != null) {
|
||||
if (Objects.equal(last.getAuthor(), msg.getAuthor())
|
||||
&& Objects.equal(last.getMessage(), msg.getMessage())) {
|
||||
@ -975,7 +979,7 @@ public class MergeOp {
|
||||
}
|
||||
|
||||
private void sendMergeFail(ChangeNotes notes, final ChangeMessage msg,
|
||||
boolean makeNew) {
|
||||
boolean makeNew) throws NoSuchChangeException, IOException {
|
||||
PatchSetApproval submitter = null;
|
||||
try {
|
||||
submitter = approvalsUtil.getSubmitter(
|
||||
@ -985,7 +989,7 @@ public class MergeOp {
|
||||
}
|
||||
|
||||
if (!makeNew) {
|
||||
RetryStatus retryStatus = getRetryStatus(submitter, msg);
|
||||
RetryStatus retryStatus = getRetryStatus(submitter, msg, notes);
|
||||
if (retryStatus == RetryStatus.RETRY_NO_MESSAGE) {
|
||||
return;
|
||||
} else if (retryStatus == RetryStatus.UNSUBMIT) {
|
||||
@ -996,6 +1000,7 @@ public class MergeOp {
|
||||
final boolean setStatusNew = makeNew;
|
||||
final Change c = notes.getChange();
|
||||
Change change = null;
|
||||
ChangeUpdate update = null;
|
||||
try {
|
||||
db.changes().beginTransaction(c.getId());
|
||||
try {
|
||||
@ -1013,7 +1018,11 @@ public class MergeOp {
|
||||
return c;
|
||||
}
|
||||
});
|
||||
db.changeMessages().insert(Collections.singleton(msg));
|
||||
ChangeControl control = changeControl(change);
|
||||
|
||||
//TODO(yyonas): atomic change is not propagated.
|
||||
update = updateFactory.create(control, c.getLastUpdatedOn());
|
||||
cmUtil.addChangeMessage(db, update, msg);
|
||||
db.commit();
|
||||
} finally {
|
||||
db.rollback();
|
||||
@ -1021,6 +1030,9 @@ public class MergeOp {
|
||||
} catch (OrmException err) {
|
||||
log.warn("Cannot record merge failure message", err);
|
||||
}
|
||||
if (update != null) {
|
||||
update.commit();
|
||||
}
|
||||
|
||||
CheckedFuture<?, IOException> indexFuture;
|
||||
if (change != null) {
|
||||
@ -1083,7 +1095,7 @@ public class MergeOp {
|
||||
}
|
||||
}
|
||||
|
||||
private void abandonAllOpenChanges() {
|
||||
private void abandonAllOpenChanges() throws NoSuchChangeException {
|
||||
Exception err = null;
|
||||
try {
|
||||
openSchema();
|
||||
@ -1105,8 +1117,13 @@ public class MergeOp {
|
||||
}
|
||||
|
||||
private void abandonOneChange(Change change) throws OrmException,
|
||||
IOException {
|
||||
NoSuchChangeException, IOException {
|
||||
db.changes().beginTransaction(change.getId());
|
||||
|
||||
//TODO(dborowitz): support InternalUser in ChangeUpdate
|
||||
ChangeControl control = changeControlFactory.controlFor(change,
|
||||
identifiedUserFactory.create(change.getOwner()));
|
||||
ChangeUpdate update = updateFactory.create(control);
|
||||
try {
|
||||
change = db.changes().atomicUpdate(
|
||||
change.getId(),
|
||||
@ -1120,6 +1137,7 @@ public class MergeOp {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
if (change != null) {
|
||||
ChangeMessage msg = new ChangeMessage(
|
||||
new ChangeMessage.Key(
|
||||
@ -1129,12 +1147,15 @@ public class MergeOp {
|
||||
change.getLastUpdatedOn(),
|
||||
change.currentPatchSetId());
|
||||
msg.setMessage("Project was deleted.");
|
||||
db.changeMessages().insert(Collections.singleton(msg));
|
||||
|
||||
//TODO(yyonas): atomic change is not propagated.
|
||||
cmUtil.addChangeMessage(db, update, msg);
|
||||
db.commit();
|
||||
indexer.index(db, change);
|
||||
}
|
||||
} finally {
|
||||
db.rollback();
|
||||
}
|
||||
update.commit();
|
||||
}
|
||||
}
|
||||
}
|
@ -69,6 +69,7 @@ import com.google.gerrit.reviewdb.client.RevId;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.ApprovalCopier;
|
||||
import com.google.gerrit.server.ApprovalsUtil;
|
||||
import com.google.gerrit.server.ChangeMessagesUtil;
|
||||
import com.google.gerrit.server.ChangeUtil;
|
||||
import com.google.gerrit.server.GerritPersonIdent;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
@ -97,6 +98,7 @@ import com.google.gerrit.server.mail.ReplacePatchSetSender;
|
||||
import com.google.gerrit.server.notedb.ChangeUpdate;
|
||||
import com.google.gerrit.server.patch.PatchSetInfoFactory;
|
||||
import com.google.gerrit.server.project.ChangeControl;
|
||||
import com.google.gerrit.server.project.NoSuchChangeException;
|
||||
import com.google.gerrit.server.project.ProjectCache;
|
||||
import com.google.gerrit.server.project.ProjectControl;
|
||||
import com.google.gerrit.server.project.ProjectState;
|
||||
@ -279,6 +281,7 @@ public class ReceiveCommits {
|
||||
private final ChangeHooks hooks;
|
||||
private final ApprovalsUtil approvalsUtil;
|
||||
private final ApprovalCopier approvalCopier;
|
||||
private final ChangeMessagesUtil cmUtil;
|
||||
private final GitRepositoryManager repoManager;
|
||||
private final ProjectCache projectCache;
|
||||
private final String canonicalWebUrl;
|
||||
@ -344,6 +347,7 @@ public class ReceiveCommits {
|
||||
final ChangeHooks hooks,
|
||||
final ApprovalsUtil approvalsUtil,
|
||||
final ApprovalCopier approvalCopier,
|
||||
final ChangeMessagesUtil cmUtil,
|
||||
final ProjectCache projectCache,
|
||||
final GitRepositoryManager repoManager,
|
||||
final TagCache tagCache,
|
||||
@ -383,6 +387,7 @@ public class ReceiveCommits {
|
||||
this.hooks = hooks;
|
||||
this.approvalsUtil = approvalsUtil;
|
||||
this.approvalCopier = approvalCopier;
|
||||
this.cmUtil = cmUtil;
|
||||
this.projectCache = projectCache;
|
||||
this.repoManager = repoManager;
|
||||
this.canonicalWebUrl = canonicalWebUrl;
|
||||
@ -576,54 +581,59 @@ public class ReceiveCommits {
|
||||
}
|
||||
|
||||
for (final ReceiveCommand c : commands) {
|
||||
if (c.getResult() == OK) {
|
||||
switch (c.getType()) {
|
||||
case CREATE:
|
||||
if (isHead(c) || isConfig(c)) {
|
||||
autoCloseChanges(c);
|
||||
if (c.getResult() == OK) {
|
||||
try {
|
||||
switch (c.getType()) {
|
||||
case CREATE:
|
||||
if (isHead(c) || isConfig(c)) {
|
||||
autoCloseChanges(c);
|
||||
}
|
||||
break;
|
||||
|
||||
case UPDATE: // otherwise known as a fast-forward
|
||||
tagCache.updateFastForward(project.getNameKey(),
|
||||
c.getRefName(),
|
||||
c.getOldId(),
|
||||
c.getNewId());
|
||||
if (isHead(c) || isConfig(c)) {
|
||||
autoCloseChanges(c);
|
||||
}
|
||||
break;
|
||||
|
||||
case UPDATE_NONFASTFORWARD:
|
||||
if (isHead(c) || isConfig(c)) {
|
||||
autoCloseChanges(c);
|
||||
}
|
||||
break;
|
||||
|
||||
case DELETE:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case UPDATE: // otherwise known as a fast-forward
|
||||
tagCache.updateFastForward(project.getNameKey(),
|
||||
c.getRefName(),
|
||||
c.getOldId(),
|
||||
c.getNewId());
|
||||
if (isHead(c) || isConfig(c)) {
|
||||
autoCloseChanges(c);
|
||||
if (isConfig(c)) {
|
||||
projectCache.evict(project);
|
||||
ProjectState ps = projectCache.get(project.getNameKey());
|
||||
repoManager.setProjectDescription(project.getNameKey(), //
|
||||
ps.getProject().getDescription());
|
||||
}
|
||||
break;
|
||||
|
||||
case UPDATE_NONFASTFORWARD:
|
||||
if (isHead(c) || isConfig(c)) {
|
||||
autoCloseChanges(c);
|
||||
if (!MagicBranch.isMagicBranch(c.getRefName())) {
|
||||
// We only fire gitRefUpdated for direct refs updates.
|
||||
// Events for change refs are fired when they are created.
|
||||
//
|
||||
gitRefUpdated.fire(project.getNameKey(), c.getRefName(),
|
||||
c.getOldId(), c.getNewId());
|
||||
hooks.doRefUpdatedHook(
|
||||
new Branch.NameKey(project.getNameKey(), c.getRefName()),
|
||||
c.getOldId(),
|
||||
c.getNewId(),
|
||||
currentUser.getAccount());
|
||||
}
|
||||
break;
|
||||
|
||||
case DELETE:
|
||||
break;
|
||||
} catch (NoSuchChangeException e) {
|
||||
c.setResult(REJECTED_OTHER_REASON,
|
||||
"No such change: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (isConfig(c)) {
|
||||
projectCache.evict(project);
|
||||
ProjectState ps = projectCache.get(project.getNameKey());
|
||||
repoManager.setProjectDescription(project.getNameKey(), //
|
||||
ps.getProject().getDescription());
|
||||
}
|
||||
|
||||
if (!MagicBranch.isMagicBranch(c.getRefName())) {
|
||||
// We only fire gitRefUpdated for direct refs updates.
|
||||
// Events for change refs are fired when they are created.
|
||||
//
|
||||
gitRefUpdated.fire(project.getNameKey(), c.getRefName(),
|
||||
c.getOldId(), c.getNewId());
|
||||
hooks.doRefUpdatedHook(
|
||||
new Branch.NameKey(project.getNameKey(), c.getRefName()),
|
||||
c.getOldId(),
|
||||
c.getNewId(),
|
||||
currentUser.getAccount());
|
||||
}
|
||||
}
|
||||
}
|
||||
closeProgress.end();
|
||||
commandProgress.end();
|
||||
@ -1928,7 +1938,7 @@ public class ReceiveCommits {
|
||||
ListenableFuture<PatchSet.Id> future = changeUpdateExector.submit(
|
||||
requestScopePropagator.wrap(new Callable<PatchSet.Id>() {
|
||||
@Override
|
||||
public PatchSet.Id call() throws OrmException, IOException {
|
||||
public PatchSet.Id call() throws OrmException, IOException, NoSuchChangeException {
|
||||
try {
|
||||
if (caller == Thread.currentThread()) {
|
||||
return insertPatchSet(db);
|
||||
@ -1993,7 +2003,7 @@ public class ReceiveCommits {
|
||||
new ChangeMessage(new ChangeMessage.Key(change.getId(), ChangeUtil
|
||||
.messageUUID(db)), me, newPatchSet.getCreatedOn(), newPatchSet.getId());
|
||||
msg.setMessage("Uploaded patch set " + newPatchSet.getPatchSetId() + ".");
|
||||
db.changeMessages().insert(Collections.singleton(msg));
|
||||
cmUtil.addChangeMessage(db, update, msg);
|
||||
|
||||
if (mergedIntoRef == null) {
|
||||
// Change should be new, so it can go through review again.
|
||||
@ -2049,7 +2059,7 @@ public class ReceiveCommits {
|
||||
if (mergedIntoRef != null) {
|
||||
// Change was already submitted to a branch, close it.
|
||||
//
|
||||
markChangeMergedByPush(db, this);
|
||||
markChangeMergedByPush(db, this, changeCtl);
|
||||
}
|
||||
|
||||
if (cmd.getResult() == NOT_ATTEMPTED) {
|
||||
@ -2256,7 +2266,7 @@ public class ReceiveCommits {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void autoCloseChanges(final ReceiveCommand cmd) {
|
||||
private void autoCloseChanges(final ReceiveCommand cmd) throws NoSuchChangeException {
|
||||
final RevWalk rw = rp.getRevWalk();
|
||||
try {
|
||||
rw.reset();
|
||||
@ -2355,7 +2365,7 @@ public class ReceiveCommits {
|
||||
result.newPatchSet = ps;
|
||||
result.info = patchSetInfoFactory.get(commit, psi);
|
||||
result.mergedIntoRef = refName;
|
||||
markChangeMergedByPush(db, result);
|
||||
markChangeMergedByPush(db, result, result.changeCtl);
|
||||
hooks.doChangeMergedHook(
|
||||
change, currentUser.getAccount(), result.newPatchSet, db);
|
||||
sendMergedEmail(result);
|
||||
@ -2383,11 +2393,13 @@ public class ReceiveCommits {
|
||||
return r;
|
||||
}
|
||||
|
||||
private void markChangeMergedByPush(ReviewDb db, final ReplaceRequest result)
|
||||
throws OrmException, IOException {
|
||||
private void markChangeMergedByPush(ReviewDb db, final ReplaceRequest result,
|
||||
ChangeControl control) throws OrmException, IOException {
|
||||
Change.Id id = result.change.getId();
|
||||
db.changes().beginTransaction(id);
|
||||
Change change;
|
||||
|
||||
ChangeUpdate update;
|
||||
try {
|
||||
change = db.changes().atomicUpdate(id, new AtomicUpdate<Change>() {
|
||||
@Override
|
||||
@ -2420,12 +2432,15 @@ public class ReceiveCommits {
|
||||
result.info.getKey());
|
||||
msg.setMessage(msgBuf.toString());
|
||||
|
||||
db.changeMessages().insert(Collections.singleton(msg));
|
||||
update = updateFactory.create(control, change.getLastUpdatedOn());
|
||||
|
||||
cmUtil.addChangeMessage(db, update, msg);
|
||||
db.commit();
|
||||
} finally {
|
||||
db.rollback();
|
||||
}
|
||||
indexer.index(db, change);
|
||||
update.commit();
|
||||
}
|
||||
|
||||
private void sendMergedEmail(final ReplaceRequest result) {
|
||||
|
@ -81,7 +81,7 @@ public class ChangeNotes extends VersionedMetaData {
|
||||
}
|
||||
});
|
||||
|
||||
private static final Ordering<ChangeMessage> MESSAGE_BY_TIME =
|
||||
public static final Ordering<ChangeMessage> MESSAGE_BY_TIME =
|
||||
Ordering.natural().onResultOf(
|
||||
new Function<ChangeMessage, Timestamp>() {
|
||||
@Override
|
||||
|
@ -35,17 +35,21 @@ public class NotesMigration {
|
||||
Config cfg = new Config();
|
||||
cfg.setBoolean("notedb", null, "write", true);
|
||||
cfg.setBoolean("notedb", "patchSetApprovals", "read", true);
|
||||
cfg.setBoolean("notedb", "changeMessages", "read", true);
|
||||
return new NotesMigration(cfg);
|
||||
}
|
||||
|
||||
private final boolean write;
|
||||
private final boolean readPatchSetApprovals;
|
||||
private final boolean readChangeMessages;
|
||||
|
||||
@Inject
|
||||
NotesMigration(@GerritServerConfig Config cfg) {
|
||||
write = cfg.getBoolean("notedb", null, "write", false);
|
||||
readPatchSetApprovals =
|
||||
cfg.getBoolean("notedb", "patchSetApprovals", "read", false);
|
||||
readChangeMessages =
|
||||
cfg.getBoolean("notedb", "changeMessages", "read", false);
|
||||
}
|
||||
|
||||
public boolean write() {
|
||||
@ -55,4 +59,8 @@ public class NotesMigration {
|
||||
public boolean readPatchSetApprovals() {
|
||||
return readPatchSetApprovals;
|
||||
}
|
||||
|
||||
public boolean readChangeMessages() {
|
||||
return readChangeMessages;
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.ApprovalsUtil;
|
||||
import com.google.gerrit.server.ChangeMessagesUtil;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
@ -152,7 +153,8 @@ public class ChangeData {
|
||||
* @return instance for testing.
|
||||
*/
|
||||
static ChangeData createForTest(Change.Id id, int currentPatchSetId) {
|
||||
ChangeData cd = new ChangeData(null, null, null, null, null, null, null, null, id);
|
||||
ChangeData cd = new ChangeData(null, null, null, null, null,
|
||||
null, null, null, null, id);
|
||||
cd.currentPatchSet = new PatchSet(new PatchSet.Id(id, currentPatchSetId));
|
||||
return cd;
|
||||
}
|
||||
@ -163,6 +165,7 @@ public class ChangeData {
|
||||
private final IdentifiedUser.GenericFactory userFactory;
|
||||
private final ChangeNotes.Factory notesFactory;
|
||||
private final ApprovalsUtil approvalsUtil;
|
||||
private final ChangeMessagesUtil cmUtil;
|
||||
private final PatchListCache patchListCache;
|
||||
private final NotesMigration notesMigration;
|
||||
private final Change.Id legacyId;
|
||||
@ -190,6 +193,7 @@ public class ChangeData {
|
||||
IdentifiedUser.GenericFactory userFactory,
|
||||
ChangeNotes.Factory notesFactory,
|
||||
ApprovalsUtil approvalsUtil,
|
||||
ChangeMessagesUtil cmUtil,
|
||||
PatchListCache patchListCache,
|
||||
NotesMigration notesMigration,
|
||||
@Assisted ReviewDb db,
|
||||
@ -200,6 +204,7 @@ public class ChangeData {
|
||||
this.userFactory = userFactory;
|
||||
this.notesFactory = notesFactory;
|
||||
this.approvalsUtil = approvalsUtil;
|
||||
this.cmUtil = cmUtil;
|
||||
this.patchListCache = patchListCache;
|
||||
this.notesMigration = notesMigration;
|
||||
legacyId = id;
|
||||
@ -212,6 +217,7 @@ public class ChangeData {
|
||||
IdentifiedUser.GenericFactory userFactory,
|
||||
ChangeNotes.Factory notesFactory,
|
||||
ApprovalsUtil approvalsUtil,
|
||||
ChangeMessagesUtil cmUtil,
|
||||
PatchListCache patchListCache,
|
||||
NotesMigration notesMigration,
|
||||
@Assisted ReviewDb db,
|
||||
@ -222,6 +228,7 @@ public class ChangeData {
|
||||
this.userFactory = userFactory;
|
||||
this.notesFactory = notesFactory;
|
||||
this.approvalsUtil = approvalsUtil;
|
||||
this.cmUtil = cmUtil;
|
||||
this.patchListCache = patchListCache;
|
||||
this.notesMigration = notesMigration;
|
||||
legacyId = c.getId();
|
||||
@ -235,6 +242,7 @@ public class ChangeData {
|
||||
IdentifiedUser.GenericFactory userFactory,
|
||||
ChangeNotes.Factory notesFactory,
|
||||
ApprovalsUtil approvalsUtil,
|
||||
ChangeMessagesUtil cmUtil,
|
||||
PatchListCache patchListCache,
|
||||
NotesMigration notesMigration,
|
||||
@Assisted ReviewDb db,
|
||||
@ -245,6 +253,7 @@ public class ChangeData {
|
||||
this.userFactory = userFactory;
|
||||
this.notesFactory = notesFactory;
|
||||
this.approvalsUtil = approvalsUtil;
|
||||
this.cmUtil = cmUtil;
|
||||
this.patchListCache = patchListCache;
|
||||
this.notesMigration = notesMigration;
|
||||
legacyId = c.getChange().getId();
|
||||
@ -521,7 +530,7 @@ public class ChangeData {
|
||||
public List<ChangeMessage> messages()
|
||||
throws OrmException {
|
||||
if (messages == null) {
|
||||
messages = db.changeMessages().byChange(legacyId).toList();
|
||||
messages = cmUtil.byChange(db, notes);
|
||||
}
|
||||
return messages;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user