Send event and execute hooks when topic is changed

When the topic is changed via the web UI or the REST API, send
an event to the event stream and execute a hook.

Bug: Issue 1992
Change-Id: Iba55469d50762478478eb07d9e2d8b0222ee3fd5
This commit is contained in:
David Pursehouse 2013-07-12 14:48:51 +09:00
parent 68ba072e48
commit ba3e28d29d
8 changed files with 96 additions and 2 deletions

View File

@ -152,6 +152,15 @@ patchset:: link:json.html#patchSet[patchset attribute]
reviewer:: link:json.html#account[account attribute]
Topic Changed
^^^^^^^^^^^^^
type:: "topic-changed"
change:: link:json.html#change[change attribute]
changer:: link:json.html#account[account attribute]
oldTopic:: Topic name before it was changed.
SEE ALSO
--------

View File

@ -1441,6 +1441,11 @@ Optional filename for the ref updated hook, if not specified then
Optional filename for the reviewer added hook, if not specified then
`reviewer-added` will be used.
[[hooks.topicChangedHook]]hooks.topicChangedHook::
+
Optional filename for the topic changed hook, if not specified then
`topic-changed` will be used.
[[hooks.claSignedHook]]hooks.claSignedHook::
+
Optional filename for the CLA signed hook, if not specified then

View File

@ -120,6 +120,15 @@ Called whenever a reviewer is added to a change.
reviewer-added --change <change id> --change-url <change url> --project <project name> --branch <branch> --reviewer <reviewer>
====
topic-changed
~~~~~~~~~~~~~
Called whenever a change's topic is changed from the Web UI or via the REST API.
====
topic-changed --change <change id> --changer <changer> --old-topic <old topic> --new-topic <new topic>
====
cla-signed
~~~~~~~~~~

View File

@ -44,6 +44,7 @@ import com.google.gerrit.server.events.MergeFailedEvent;
import com.google.gerrit.server.events.PatchSetCreatedEvent;
import com.google.gerrit.server.events.RefUpdatedEvent;
import com.google.gerrit.server.events.ReviewerAddedEvent;
import com.google.gerrit.server.events.TopicChangedEvent;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.WorkQueue;
import com.google.gerrit.server.project.ProjectCache;
@ -186,6 +187,9 @@ public class ChangeHookRunner implements ChangeHooks, LifecycleListener {
/** Filename of the reviewer added hook. */
private final File reviewerAddedHook;
/** Filename of the topic changed hook. */
private final File topicChangedHook;
/** Filename of the cla signed hook. */
private final File claSignedHook;
@ -254,6 +258,7 @@ public class ChangeHookRunner implements ChangeHooks, LifecycleListener {
changeRestoredHook = sitePath.resolve(new File(hooksPath, getValue(config, "hooks", "changeRestoredHook", "change-restored")).getPath());
refUpdatedHook = sitePath.resolve(new File(hooksPath, getValue(config, "hooks", "refUpdatedHook", "ref-updated")).getPath());
reviewerAddedHook = sitePath.resolve(new File(hooksPath, getValue(config, "hooks", "reviewerAddedHook", "reviewer-added")).getPath());
topicChangedHook = sitePath.resolve(new File(hooksPath, getValue(config, "hooks", "topicChangedHook", "topic-changed")).getPath());
claSignedHook = sitePath.resolve(new File(hooksPath, getValue(config, "hooks", "claSignedHook", "cla-signed")).getPath());
refUpdateHook = sitePath.resolve(new File(hooksPath, getValue(config, "hooks", "refUpdateHook", "ref-update")).getPath());
syncHookTimeout = config.getInt("hooks", "syncHookTimeout", 30);
@ -560,6 +565,25 @@ public class ChangeHookRunner implements ChangeHooks, LifecycleListener {
runHook(change.getProject(), reviewerAddedHook, args);
}
public void doTopicChangedHook(final Change change, final Account account,
final String oldTopic, final ReviewDb db)
throws OrmException {
final TopicChangedEvent event = new TopicChangedEvent();
event.change = eventFactory.asChangeAttribute(change);
event.changer = eventFactory.asAccountAttribute(account);
event.oldTopic = oldTopic;
fireEvent(change, event, db);
final List<String> args = new ArrayList<String>();
addArg(args, "--change", event.change.id);
addArg(args, "--changer", getDisplayName(account));
addArg(args, "--old-topic", oldTopic);
addArg(args, "--new-topic", event.change.topic);
runHook(change.getProject(), topicChangedHook, args);
}
public void doClaSignupHook(Account account, ContributorAgreement cla) {
if (account != null) {
final List<String> args = new ArrayList<String>();

View File

@ -147,6 +147,16 @@ public interface ChangeHooks {
public void doReviewerAddedHook(Change change, Account account,
PatchSet patchSet, ReviewDb db) throws OrmException;
/**
* Fire the Topic Changed Hook
*
* @param change The change itself.
* @param account The gerrit user who changed the topic.
* @param oldTopic The old topic name.
*/
public void doTopicChangedHook(Change change, Account account,
String oldTopic, ReviewDb db) throws OrmException;
public void doClaSignupHook(Account account, ContributorAgreement cla);
/**

View File

@ -90,6 +90,11 @@ public final class DisabledChangeHooks implements ChangeHooks {
ReviewDb db) {
}
@Override
public void doTopicChangedHook(Change change, Account account, String oldTopic,
ReviewDb db) {
}
@Override
public void removeChangeListener(ChangeListener listener) {
}

View File

@ -15,6 +15,7 @@
package com.google.gerrit.server.change;
import com.google.common.base.Strings;
import com.google.gerrit.common.ChangeHooks;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.DefaultInput;
@ -38,6 +39,7 @@ import java.util.Collections;
class PutTopic implements RestModifyView<ChangeResource, Input> {
private final Provider<ReviewDb> dbProvider;
private final ChangeIndexer indexer;
private final ChangeHooks hooks;
static class Input {
@DefaultInput
@ -46,9 +48,11 @@ class PutTopic implements RestModifyView<ChangeResource, Input> {
}
@Inject
PutTopic(Provider<ReviewDb> dbProvider, ChangeIndexer indexer) {
PutTopic(Provider<ReviewDb> dbProvider, ChangeIndexer indexer,
ChangeHooks hooks) {
this.dbProvider = dbProvider;
this.indexer = indexer;
this.hooks = hooks;
}
@Override
@ -80,9 +84,10 @@ class PutTopic implements RestModifyView<ChangeResource, Input> {
oldTopicName, newTopicName);
}
IdentifiedUser currentUser = ((IdentifiedUser) control.getCurrentUser());
ChangeMessage cmsg = new ChangeMessage(
new ChangeMessage.Key(change.getId(), ChangeUtil.messageUUID(db)),
((IdentifiedUser) control.getCurrentUser()).getAccountId(),
currentUser.getAccountId(),
change.currentPatchSetId());
StringBuilder msgBuf = new StringBuilder(summary);
if (!Strings.isNullOrEmpty(input.message)) {
@ -101,6 +106,8 @@ class PutTopic implements RestModifyView<ChangeResource, Input> {
});
db.changeMessages().insert(Collections.singleton(cmsg));
indexer.index(change);
hooks.doTopicChangedHook(change, currentUser.getAccount(),
oldTopicName, db);
}
return Strings.isNullOrEmpty(newTopicName)
? Response.none()

View File

@ -0,0 +1,25 @@
// Copyright (C) 2013 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.events;
import com.google.gerrit.server.data.AccountAttribute;
import com.google.gerrit.server.data.ChangeAttribute;
public class TopicChangedEvent extends ChangeEvent {
public final String type = "topic-changed";
public ChangeAttribute change;
public AccountAttribute changer;
public String oldTopic;
}