Skip to content

Commit

Permalink
feat: GitHub connector List cancelled case - MEED-2441 - Meeds-io/MIP…
Browse files Browse the repository at this point in the history
…s#64 (#92)

This PR add some canceler events that can cancel actions already done by user
  • Loading branch information
AzmiTouil authored Sep 8, 2023
1 parent 09a9962 commit d93d8c1
Show file tree
Hide file tree
Showing 15 changed files with 358 additions and 221 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,45 @@
*/
package org.exoplatform.gamification.github.listener;

import java.util.HashMap;
import java.util.Map;

import org.exoplatform.gamification.github.services.WebhookService;
import org.exoplatform.services.listener.Event;
import org.exoplatform.services.listener.Listener;
import org.exoplatform.services.listener.ListenerService;

import static org.exoplatform.gamification.github.utils.Utils.GITHUB_ACTION_EVENT;
import static org.exoplatform.gamification.github.utils.Utils.GITHUB_CANCEL_ACTION_EVENT;

public class GithubEventsListener extends Listener<Map<String, String>, String> {

private final WebhookService webhookService;
public static final String GAMIFICATION_GENERIC_EVENT = "exo.gamification.generic.action";

public static final String GAMIFICATION_CANCEL_EVENT = "gamification.cancel.event.action";

private final ListenerService listenerService;

public GithubEventsListener(WebhookService webhookService) {
this.webhookService = webhookService;
public GithubEventsListener(ListenerService listenerService) {
this.listenerService = listenerService;
}

@Override
public void onEvent(Event<Map<String, String>, String> event) {
String ruleTitle = event.getSource().get("ruleTitle");
String senderId = event.getSource().get("senderId");
String receiverId = event.getSource().get("receiverId");
String object = event.getSource().get("object");
webhookService.createGamificationHistory(ruleTitle, senderId, receiverId, object);
public void onEvent(Event<Map<String, String>, String> event) throws Exception {
Map<String, String> gam = new HashMap<>();
gam.put("objectId", event.getSource().get("objectId"));
gam.put("objectType", event.getSource().get("objectType"));
gam.put("ruleTitle", event.getSource().get("ruleTitle"));
gam.put("senderId", event.getSource().get("senderId"));
gam.put("receiverId", event.getSource().get("receiverId"));

listenerService.broadcast(getGamificationEventName(event.getEventName()), gam, "");
}

private String getGamificationEventName(String eventName) {
return switch (eventName) {
case GITHUB_ACTION_EVENT -> GAMIFICATION_GENERIC_EVENT;
case GITHUB_CANCEL_ACTION_EVENT -> GAMIFICATION_CANCEL_EVENT;
default -> throw new IllegalArgumentException("Unexpected listener event name: " + eventName);
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,7 @@ public class Event {

String receiver;

String object;
String objectId;

String objectType;
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ public List<Event> getEvents(Map<String, Object> payload) {
return Collections.singletonList(new Event(PULL_REQUEST_REVIEW_COMMENT_EVENT_NAME,
null,
extractSubItem(payload, COMMENT, USER, LOGIN),
extractSubItem(payload, COMMENT, LINKS, HTML, HREF)));
extractSubItem(payload, COMMENT, LINKS, HTML, HREF),
REVIEW_COMMENT_TYPE));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,26 @@ public class CommentTriggerPlugin extends GithubTriggerPlugin {

@Override
public List<Event> getEvents(Map<String, Object> payload) {

String pullRequest = extractSubItem(payload, ISSUE, PULL_REQUEST);
String action = extractSubItem(payload, ACTION);
String comment = extractSubItem(payload, COMMENT, HTML_URL);
String userId = extractSubItem(payload, SENDER, LOGIN);
if (StringUtils.isNotBlank(pullRequest)) {
return Collections.singletonList(new Event(COMMENT_PULL_REQUEST_EVENT_NAME, null, userId, pullRequest));
} else {
return Collections.singletonList(new Event(COMMENT_ISSUE_EVENT_NAME,
null,
userId,
extractSubItem(payload, ISSUE, HTML_URL)));
String eventName;
String eventType = StringUtils.isBlank(pullRequest) ? COMMENT_ISSUE_TYPE : COMMENT_PR_TYPE;
if (action != null) {
switch (action) {
case CREATED:
eventName = StringUtils.isBlank(pullRequest) ? COMMENT_ISSUE_EVENT_NAME : COMMENT_PULL_REQUEST_EVENT_NAME;
break;
case DELETED:
eventName = StringUtils.isBlank(pullRequest) ? DELETE_ISSUE_COMMENT_EVENT_NAME : DELETE_PULL_REQUEST_COMMENT_EVENT_NAME;
break;
default:
return Collections.emptyList();
}
return Collections.singletonList(new Event(eventName, null, userId, comment, eventType));
}
return Collections.emptyList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,21 @@ public class IssueTriggerPlugin extends GithubTriggerPlugin {
@Override
public List<Event> getEvents(Map<String, Object> payload) {
String issueState = extractSubItem(payload, ACTION);
String object = extractSubItem(payload, ISSUE, HTML_URL);
String objectId = extractSubItem(payload, ISSUE, HTML_URL);
String userId = extractSubItem(payload, SENDER, LOGIN);
if (Objects.equals(issueState, OPENED)) {
return Collections.singletonList(new Event(CREATE_ISSUE_EVENT_NAME, userId, userId, object));

return Collections.singletonList(new Event(CREATE_ISSUE_EVENT_NAME, userId, userId, objectId, ISSUE_TYPE));
} else if (Objects.equals(issueState, CLOSED)) {
if (Objects.equals(extractSubItem(payload, ISSUE, STATE_REASON), NOT_PLANNED)) {
return Collections.singletonList(new Event(CLOSE_ISSUE_EVENT_NAME, userId, userId, objectId, ISSUE_TYPE));
}
return Collections.emptyList();
} else if (Objects.equals(issueState, LABELED)) {
return Collections.singletonList(new Event(ADD_ISSUE_LABEL_EVENT_NAME, userId, userId, object));
objectId = objectId + "?label=" + extractSubItem(payload, LABEL, NAME);
return Collections.singletonList(new Event(ADD_ISSUE_LABEL_EVENT_NAME, userId, userId, objectId, ISSUE_TYPE));
} else if (Objects.equals(issueState, UNLABELED)) {
objectId = objectId + "?label=" + extractSubItem(payload, LABEL, NAME);
return Collections.singletonList(new Event(DELETE_ISSUE_LABEL_EVENT_NAME, userId, userId, objectId, ISSUE_TYPE));
}
return Collections.emptyList();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,19 @@ public List<Event> getEvents(Map<String, Object> payload) {
return Collections.singletonList(new Event(REVIEW_PULL_REQUEST_EVENT_NAME,
extractSubItem(payload, PULL_REQUEST_REVIEW, USER, LOGIN),
extractSubItem(payload, PULL_REQUEST_REVIEW, USER, LOGIN),
extractSubItem(payload, PULL_REQUEST_REVIEW, HTML_URL)));
extractSubItem(payload, PULL_REQUEST_REVIEW, HTML_URL),
PR_TYPE));
} else if (pullState != null && pullState.equals(PULL_REQUEST_VALIDATED)) {
return Arrays.asList(new Event(PULL_REQUEST_VALIDATED_EVENT_NAME,
extractSubItem(payload, PULL_REQUEST_REVIEW, USER, LOGIN),
extractSubItem(payload, PULL_REQUEST, USER, LOGIN),
extractSubItem(payload, PULL_REQUEST_REVIEW, HTML_URL)),
extractSubItem(payload, PULL_REQUEST, USER, LOGIN),
extractSubItem(payload, PULL_REQUEST_REVIEW, HTML_URL),
PR_TYPE),
new Event(VALIDATE_PULL_REQUEST_EVENT_NAME,
extractSubItem(payload, PULL_REQUEST_REVIEW, USER, LOGIN),
extractSubItem(payload, PULL_REQUEST_REVIEW, USER, LOGIN),
extractSubItem(payload, PULL_REQUEST_REVIEW, HTML_URL)));
extractSubItem(payload, PULL_REQUEST_REVIEW, HTML_URL),
PR_TYPE));
}
return Collections.emptyList();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,19 @@ public class PullRequestTriggerPlugin extends GithubTriggerPlugin {
@Override
public List<Event> getEvents(Map<String, Object> payload) {
String userId = extractSubItem(payload, SENDER, LOGIN);
String object = extractSubItem(payload, PULL_REQUEST, HTML_URL);
String objectId = extractSubItem(payload, PULL_REQUEST, HTML_URL);
if (Objects.equals(extractSubItem(payload, ACTION), OPENED)) {
return Collections.singletonList(new Event(CREATE_PULL_REQUEST_EVENT_NAME, null, userId, object));
return Collections.singletonList(new Event(CREATE_PULL_REQUEST_EVENT_NAME, null, userId, objectId, PR_TYPE));
} else if (Objects.equals(extractSubItem(payload, ACTION), CLOSED)) {
return Collections.singletonList(new Event(CLOSE_PULL_REQUEST_EVENT_NAME, null, userId, objectId, PR_TYPE));
} else if (Objects.equals(extractSubItem(payload, ACTION), REVIEW_REQUESTED)) {
return Collections.singletonList(new Event(REQUEST_REVIEW_FOR_PULL_REQUEST_EVENT_NAME, null, userId, object));
String requestedReviewer = extractSubItem(payload, REQUESTED_REVIEWER, LOGIN);
objectId = objectId + "?requestedReviewer=" + requestedReviewer;
return Collections.singletonList(new Event(REQUEST_REVIEW_FOR_PULL_REQUEST_EVENT_NAME, null, userId, objectId, PR_TYPE));
} else if (Objects.equals(extractSubItem(payload, ACTION), REVIEW_REQUEST_REMOVED)) {
String requestedReviewer = extractSubItem(payload, REQUESTED_REVIEWER, LOGIN);
objectId = objectId + "?requestedReviewer=" + requestedReviewer;
return Collections.singletonList(new Event(REVIEW_REQUEST_REMOVED_EVENT_NAME, null, userId, objectId, PR_TYPE));
}
return Collections.emptyList();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public List<Event> getEvents(Map<String, Object> payload) {
return Collections.singletonList(new Event(PUSH_CODE_EVENT_NAME,
null,
extractSubItem(payload, PUSHER, NAME),
extractSubItem(payload, HEAD_COMMIT, URL)));
extractSubItem(payload, HEAD_COMMIT, URL),
null));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -187,14 +187,4 @@ List<RemoteRepository> retrieveOrganizationRepos(long organizationRemoteId,
int countOrganizationRepos(long organizationRemoteId, String currentUser) throws IllegalAccessException,
ObjectNotFoundException;

/**
* create gamification history
*
* @param ruleTitle Rule title
* @param senderId sender username
* @param receiverId receiver username
* @param object Object link
*/
void createGamificationHistory(String ruleTitle, String senderId, String receiverId, String object);

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
package org.exoplatform.gamification.github.services.impl;

import io.meeds.gamification.model.EventDTO;
import io.meeds.gamification.model.filter.EventFilter;
import io.meeds.gamification.service.ConnectorService;
import io.meeds.gamification.service.EventService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.exoplatform.commons.api.persistence.ExoTransactional;
Expand All @@ -38,6 +40,7 @@
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

import static org.exoplatform.gamification.github.utils.Utils.*;

Expand Down Expand Up @@ -124,7 +127,10 @@ private void processEvents(List<Event> events, String trigger, String organizati

private boolean isEventEnabled(String eventName, String trigger, String organizationId) {
EventDTO eventDTO = eventService.getEventByTitleAndTrigger(eventName, trigger);
return eventDTO != null && isOrganizationEventEnabled(eventDTO, organizationId);
if (eventDTO != null) {
return isOrganizationEventEnabled(eventDTO, organizationId);
}
return true;
}

private boolean isOrganizationEventEnabled(EventDTO eventDTO, String organizationId) {
Expand All @@ -147,7 +153,7 @@ private void processEvent(Event event) {
if (StringUtils.isNotBlank(senderId)) {
Identity socialIdentity = identityManager.getOrCreateUserIdentity(senderId);
if (socialIdentity != null) {
broadcastGithubEvent(event.getName(), senderId, receiverId, event.getObject());
broadcastGithubEvent(event.getName(), senderId, receiverId, event.getObjectId(), event.getObjectType());
}
}
}
Expand All @@ -156,14 +162,30 @@ public String[] getTriggers() {
return triggerPlugins.values().stream().map(GithubTriggerPlugin::getName).toArray(String[]::new);
}

private void broadcastGithubEvent(String ruleTitle, String senderId, String receiverId, String object) {
private void broadcastGithubEvent(String ruleTitle, String senderId, String receiverId, String objectId, String objectType) {
try {
Map<String, String> gam = new HashMap<>();
gam.put("ruleTitle", ruleTitle);
gam.put("senderId", senderId);
gam.put("receiverId", receiverId);
gam.put("object", object);
listenerService.broadcast("exo.github.event", gam, "");
gam.put("objectId", objectId);
gam.put("objectType", objectType);
EventDTO eventDTO = eventService.getEventByTypeAndTitle("github", ruleTitle);
if (eventDTO != null) {
gam.put("ruleTitle", eventDTO.getTitle());
listenerService.broadcast(GITHUB_ACTION_EVENT, gam, "");
} else {
List<EventDTO> events = eventService.getEvents(new EventFilter("github", null), 0, 0);
List<EventDTO> eventsToCancel = events.stream()
.filter(event -> event.getCancellerEvents() != null
&& event.getCancellerEvents().contains(ruleTitle))
.toList();
if (CollectionUtils.isNotEmpty(eventsToCancel)) {
for (EventDTO eventToCancel : eventsToCancel) {
gam.put("ruleTitle", eventToCancel.getTitle());
listenerService.broadcast(GITHUB_CANCEL_ACTION_EVENT, gam, "");
}
}
}
LOG.info("Github action {} broadcasted for user {}", ruleTitle, senderId);
} catch (Exception e) {
LOG.error("Cannot broadcast github event", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,16 @@
import org.exoplatform.gamification.github.storage.WebHookStorage;
import org.json.JSONObject;

import org.exoplatform.services.listener.ListenerService;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;

import static org.exoplatform.gamification.github.utils.Utils.*;

public class WebhookServiceImpl implements WebhookService {

private static final Log LOG = ExoLogger.getLogger(WebhookServiceImpl.class);

private static final Context GITHUB_WEBHOOK_CONTEXT = Context.GLOBAL.id("githubWebhook");

private static final Scope WATCH_LIMITED_SCOPE = Scope.APPLICATION.id("watchLimited");

private static final Scope DISABLED_REPOS_SCOPE = Scope.APPLICATION.id("disabledRepos");

private final ListenerService listenerService;

private final SettingService settingService;

private final WebHookStorage webHookStorage;
Expand All @@ -65,12 +57,10 @@ public class WebhookServiceImpl implements WebhookService {

private final GithubConsumerService githubServiceConsumer;

public WebhookServiceImpl(ListenerService listenerService,
SettingService settingService,
public WebhookServiceImpl(SettingService settingService,
GithubTriggerService githubTriggerService,
WebHookStorage webHookStorage,
GithubConsumerService githubServiceConsumer) {
this.listenerService = listenerService;
this.settingService = settingService;
this.githubTriggerService = githubTriggerService;
this.webHookStorage = webHookStorage;
Expand Down Expand Up @@ -305,22 +295,4 @@ private void forceUpdateWebhook(WebHook webHook) {
}
}
}

public void createGamificationHistory(String ruleTitle, String senderId, String receiverId, String object) {
try {
Map<String, String> gam = new HashMap<>();
gam.put("ruleTitle", ruleTitle);
gam.put("senderId", senderId);
gam.put("receiverId", receiverId);
gam.put("object", object);
listenerService.broadcast("exo.gamification.generic.action", gam, "");
LOG.info("Github action {} gamified for user {} {} {}",
ruleTitle,
senderId,
(ruleTitle.equals("pullRequestValidated")) ? "from" : "to",
receiverId);
} catch (Exception e) {
LOG.error("Cannot broadcast gamification event", e);
}
}
}
Loading

0 comments on commit d93d8c1

Please sign in to comment.