-
Notifications
You must be signed in to change notification settings - Fork 4
/
WebhookListener.java
107 lines (94 loc) · 3.96 KB
/
WebhookListener.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package com.sourcegraph.webhook;
import com.atlassian.bitbucket.build.status.RepositoryBuildStatusSetEvent;
import com.atlassian.bitbucket.event.ApplicationEvent;
import com.atlassian.bitbucket.event.pull.*;
import com.atlassian.bitbucket.event.repository.RepositoryPushEvent;
import com.atlassian.bitbucket.pull.PullRequestAction;
import com.atlassian.bitbucket.pull.PullRequestParticipantStatus;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.event.api.AsynchronousPreferred;
import com.atlassian.event.api.EventListener;
import com.sourcegraph.webhook.registry.Webhook;
import com.sourcegraph.webhook.registry.WebhookRegistry;
import javax.inject.Named;
import java.util.ArrayList;
import java.util.List;
@AsynchronousPreferred
@Named("WebhookListener")
public class WebhookListener {
// getTriggers enumerate all prefixes (or super/parent events) of event key.
// "pr:comment:added" -> ["pr", "pr:comment", "pr:comment:added"]
public List<String> getTriggers(String key) {
String[] split = key.split(":");
if (split.length == 0) {
return null;
}
List<String> prefixes = new ArrayList<>();
for (int i = 0, index = 0; i < split.length; i++) {
index += split[i].length();
prefixes.add(key.substring(0, index));
index++;
}
return prefixes;
}
@EventListener
public void onPullRequestEvent(PullRequestEvent event) {
String key = "pr:event";
// When review status changes, two events are fired in in all cases apart from
// when we move from Needs Work to Unapproved.
// 1. A PR Activity Event
// 2. A PR Participant Event
// We only want to forward the Activity events.
// However, when moving from Needs Works to Unapproved, no activity event is fired
// and so in this one case we want to forward the Participant Event
if (event instanceof PullRequestParticipantStatusUpdatedEvent) {
PullRequestAction action = event.getAction();
PullRequestParticipantStatus previousStatus = ((PullRequestParticipantStatusUpdatedEvent) event).getPreviousStatus();
if (action != PullRequestAction.UNAPPROVED) {
return;
}
if (previousStatus != PullRequestParticipantStatus.NEEDS_WORK) {
return;
}
key = "pr:participant:status";
}
if (event instanceof PullRequestActivityEvent) {
key = "pr:activity:event";
}
if (event instanceof PullRequestRescopeActivityEvent) {
key = "pr:activity:rescope";
} else if (event instanceof PullRequestMergeActivityEvent) {
key = "pr:activity:merge";
} else if (event instanceof PullRequestCommentActivityEvent) {
key = "pr:activity:comment";
} else if (event instanceof PullRequestReviewersUpdatedActivityEvent) {
key = "pr:activity:reviewers";
}
handle(event, key, event.getPullRequest().getToRef().getRepository());
}
@EventListener
public void onRepositoryBuildStatusSetEvent(RepositoryBuildStatusSetEvent event) {
handle(event, "repo:build_status");
}
@EventListener
public void onRepositoryPushEvent(RepositoryPushEvent event) {
handle(event, "repo:refs_changed");
}
public void handle(ApplicationEvent event, String key) {
handle(event, key, null);
}
private void handle(ApplicationEvent event, String key, Repository repository) {
List<String> triggers = getTriggers(key);
if (triggers == null || triggers.isEmpty()) {
return;
}
List<Webhook> hooks = WebhookRegistry.getWebhooks(triggers, repository);
if (hooks.isEmpty()) {
return;
}
hooks.forEach(hook -> {
EventSerializer serializer = new EventSerializer(key, event);
Dispatcher.dispatch(hook, serializer);
});
}
}