Commit e9f806a4 authored by Greg Messner's avatar Greg Messner
Browse files

Initial check-in to support webhook handling.

parent ae103920
package org.gitlab4j.api.utils;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Enumeration;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
public class HttpRequestUtils {
/**
* Build a String containing a very short multi-line dump of an HTTP request.
*
* @param fromMethod the method that this method was called from
* @param request the HTTP request build the request dump from
* @return a String containing a very short multi-line dump of the HTTP request
*/
public static String getShortRequestDump(String fromMethod, HttpServletRequest request) {
return (getShortRequestDump(fromMethod, false, request));
}
/**
* Build a String containing a short multi-line dump of an HTTP request.
*
* @param fromMethod the method that this method was called from
* @param request the HTTP request build the request dump from
* @param includeHeaders if true will include the HTTP headers in the dump
* @return a String containing a short multi-line dump of the HTTP request
*/
public static String getShortRequestDump(String fromMethod, boolean includeHeaders, HttpServletRequest request) {
StringBuilder dump = new StringBuilder();
dump.append("Timestamp : ").append(ISO8601.getTimestamp()).append("\n");
dump.append("fromMethod : ").append(fromMethod).append("\n");
dump.append("Method : ").append(request.getMethod()).append('\n');
dump.append("Scheme : ").append(request.getScheme()).append('\n');
dump.append("URI : ").append(request.getRequestURI()).append('\n');
dump.append("Query-String : ").append(request.getQueryString()).append('\n');
dump.append("Auth-Type : ").append(request.getAuthType()).append('\n');
dump.append("Remote-Addr : ").append(request.getRemoteAddr()).append('\n');
dump.append("Scheme : ").append(request.getScheme()).append('\n');
dump.append("Content-Type : ").append(request.getContentType()).append('\n');
dump.append("Content-Length: ").append(request.getContentLength()).append('\n');
if (includeHeaders) {
dump.append("Headers :\n");
Enumeration<String> headers = request.getHeaderNames();
while (headers.hasMoreElements()) {
String header = headers.nextElement();
dump.append("\t").append(header).append(": ").append(request.getHeader(header)).append('\n');
}
}
return (dump.toString());
}
/**
* Build a String containing a multi-line dump of an HTTP request.
*
* @param fromMethod the method that this method was called from
* @param request the HTTP request build the request dump from
* @param includePostData if true will include the POST data in the dump
* @return a String containing a multi-line dump of the HTTP request, If an error occurs,
* the message from the exception will be returned
*/
public static String getRequestDump(String fromMethod, HttpServletRequest request, boolean includePostData) {
String shortDump = getShortRequestDump(fromMethod, request);
StringBuilder buf = new StringBuilder(shortDump);
try {
buf.append("\nAttributes:\n");
Enumeration<String> attrs = request.getAttributeNames();
while (attrs.hasMoreElements()) {
String attr = attrs.nextElement();
buf.append("\t").append(attr).append(": ").append(request.getAttribute(attr)).append('\n');
}
buf.append("\nHeaders:\n");
Enumeration<String> headers = request.getHeaderNames();
while (headers.hasMoreElements()) {
String header = headers.nextElement();
buf.append("\t").append(header).append(": ").append(request.getHeader(header)).append('\n');
}
buf.append("\nParameters:\n");
Enumeration<String> params = request.getParameterNames();
while (params.hasMoreElements()) {
String param = params.nextElement();
buf.append("\t").append(param).append(": ").append(request.getParameter(param)).append('\n');
}
buf.append("\nCookies:\n");
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
String cstr = "\t" + cookie.getDomain() + "." + cookie.getPath() + "." + cookie.getName() + ": " + cookie.getValue() + "\n";
buf.append(cstr);
}
}
if (includePostData) {
buf.append(getPostDataAsString(request)).append("\n");
}
return (buf.toString());
} catch (IOException e) {
return e.getMessage();
}
}
/**
* Reads the POST data from a request into a String and returns it.
*
* @param request the HTTP request containing the POST data
* @return the POST data as a String instance
* @throws IOException if any error occurs while reading the POST data
*/
public static String getPostDataAsString(HttpServletRequest request) throws IOException {
try (InputStreamReader reader = new InputStreamReader(request.getInputStream(), "UTF-8")) {
return (getReaderContentAsString(reader));
}
}
/**
* Reads the content of a Reader instance and returns it as a String.
*
* @param reader the Reader instance to read the data from
* @return the content of a Reader instance as a String
* @throws IOException if any error occurs while reading the POST data
*/
public static String getReaderContentAsString(Reader reader) throws IOException {
int count;
final char[] buffer = new char[2048];
final StringBuilder out = new StringBuilder();
while ((count = reader.read(buffer, 0, buffer.length)) >= 0) {
out.append(buffer, 0, count);
}
return (out.toString());
}
}
\ No newline at end of file
package org.gitlab4j.api.webhook;
import java.util.Date;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@XmlAccessorType(XmlAccessType.FIELD)
public class EventIssue {
private Integer assigneeId;
private Integer authorId;
private String branchName;
private Date createdAt;
private String description;
private Integer id;
private Integer iid;
private String milestoneId;
private Integer position;
private Integer projectId;
private String state;
private String title;
private Date updatedAt;
private String url;
private String action;
public Integer getAssigneeId() {
return this.assigneeId;
}
public void setAssigneeId(Integer assigneeId) {
this.assigneeId = assigneeId;
}
public Integer getAuthorId() {
return this.authorId;
}
public void setAuthorId(Integer authorId) {
this.authorId = authorId;
}
public String getBranchName() {
return this.branchName;
}
public void setBranchName(String branchName) {
this.branchName = branchName;
}
public Date getCreatedAt() {
return this.createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getIid() {
return this.iid;
}
public void setIid(Integer iid) {
this.iid = iid;
}
public String getMilestoneId() {
return this.milestoneId;
}
public void setMilestoneId(String milestoneId) {
this.milestoneId = milestoneId;
}
public Integer getPosition() {
return this.position;
}
public void setPosition(Integer position) {
this.position = position;
}
public Integer getProjectId() {
return this.projectId;
}
public void setProjectId(Integer projectId) {
this.projectId = projectId;
}
public String getState() {
return this.state;
}
public void setState(String state) {
this.state = state;
}
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
public Date getUpdatedAt() {
return this.updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
}
package org.gitlab4j.api.webhook;
import java.util.Date;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import org.gitlab4j.api.models.Assignee;
@XmlAccessorType(XmlAccessType.FIELD)
public class EventMergeRequest {
private Integer assigneeId;
private Integer authorId;
private String branchName;
private Date createdAt;
private String description;
private Integer id;
private Integer iid;
private String mergeStatus;
private Integer milestoneId;
private Integer position;
private Date lockedAt;
private Integer projectId;
private String sourceBranch;
private Integer sourceProjectId;
private String stCommits;
private String stDiffs;
private String state;
private String targetBranch;
private Integer targetProjectId;
private String title;
private Date updatedAt;
private EventProject source;
private EventProject target;
private EventCommit lastCommit;
private Boolean workInProgress;
private String url;
private String action;
private Assignee assignee;
public Integer getAssigneeId() {
return this.assigneeId;
}
public void setAssigneeId(Integer assigneeId) {
this.assigneeId = assigneeId;
}
public Integer getAuthorId() {
return this.authorId;
}
public void setAuthorId(Integer authorId) {
this.authorId = authorId;
}
public String getBranchName() {
return this.branchName;
}
public void setBranchName(String branchName) {
this.branchName = branchName;
}
public Date getCreatedAt() {
return this.createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getIid() {
return this.iid;
}
public void setIid(Integer iid) {
this.iid = iid;
}
public String getMergeStatus() {
return this.mergeStatus;
}
public void setMergeStatus(String mergeStatus) {
this.mergeStatus = mergeStatus;
}
public Integer getMilestoneId() {
return this.milestoneId;
}
public void setMilestoneId(Integer milestoneId) {
this.milestoneId = milestoneId;
}
public Integer getPosition() {
return this.position;
}
public void setPosition(Integer position) {
this.position = position;
}
public Date getLockedAt() {
return lockedAt;
}
public void setLockedAt(Date lockedAt) {
this.lockedAt = lockedAt;
}
public Integer getProjectId() {
return this.projectId;
}
public void setProjectId(Integer projectId) {
this.projectId = projectId;
}
public String getSourceBranch() {
return this.sourceBranch;
}
public void setSourceBranch(String sourceBranch) {
this.sourceBranch = sourceBranch;
}
public Integer getSourceProjectId() {
return this.sourceProjectId;
}
public void setSourceProjectId(Integer sourceProjectId) {
this.sourceProjectId = sourceProjectId;
}
public String getStCommits() {
return this.stCommits;
}
public void setStCommits(String stCommits) {
this.stCommits = stCommits;
}
public String getStDiffs() {
return this.stDiffs;
}
public void setStDiffs(String stDiffs) {
this.stDiffs = stDiffs;
}
public String getState() {
return this.state;
}
public void setState(String state) {
this.state = state;
}
public String getTargetBranch() {
return this.targetBranch;
}
public void setTargetBranch(String targetBranch) {
this.targetBranch = targetBranch;
}
public Integer getTargetProjectId() {
return this.targetProjectId;
}
public void setTargetProjectId(Integer targetProjectId) {
this.targetProjectId = targetProjectId;
}
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
public Date getUpdatedAt() {
return this.updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
public EventProject getSource() {
return source;
}
public void setSource(EventProject source) {
this.source = source;
}
public EventProject getTarget() {
return target;
}
public void setTarget(EventProject target) {
this.target = target;
}
public EventCommit getLastCommit() {
return lastCommit;
}
public void setLastCommit(EventCommit lastCommit) {
this.lastCommit = lastCommit;
}
public Boolean getWorkInProgress() {
return workInProgress;
}
public void setWorkInProgress(Boolean workInProgress) {
this.workInProgress = workInProgress;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public Assignee getAssignee() {
return assignee;
}
public void setAssignee(Assignee assignee) {
this.assignee = assignee;
}
}
\ No newline at end of file
package org.gitlab4j.api.webhook;
import java.util.Date;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import org.gitlab4j.api.models.AccessLevel;
@XmlAccessorType(XmlAccessType.FIELD)
public class EventSnippet {
private Integer id;
private String title;
private String content;
private Integer authorId;
private Integer projectId;
private Date createdAt;
private Date updatedAt;
private String fileName;
private Date expiresAt;
private String type;
private AccessLevel visibilityLevel;
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return this.content;
}
public void setContent(String content) {
this.content = content;
}
public Integer getAuthorId() {
return this.authorId;
}
public void setAuthorId(Integer authorId) {
this.authorId = authorId;
}
public Integer getProjectId() {
return this.projectId;
}
public void setProjectId(Integer projectId) {
this.projectId = projectId;
}
public Date getCreatedAt() {
return this.createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getUpdatedAt() {
return this.updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public Date getExpiresAt() {
return expiresAt;
}
public void setExpiresAt(Date expiresAt) {
this.expiresAt = expiresAt;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public AccessLevel getVisibilityLevel() {
return visibilityLevel;
}
public void setVisibilityLevel(AccessLevel visibilityLevel) {
this.visibilityLevel = visibilityLevel;
}
}
package org.gitlab4j.api.webhook;
import java.util.Date;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import org.gitlab4j.api.models.Diff;
import org.gitlab4j.api.models.User;
@XmlAccessorType(XmlAccessType.FIELD)
public class NoteEvent implements Event {
public static final String X_GITLAB_EVENT = "Note Hook";
public static final String OBJECT_KIND = "note";
private User user;
private Integer projectId;
private EventProject project;
private EventRepository repository;
private ObjectAttributes objectAttributes;
private EventCommit commit;
private EventIssue issue;
private EventMergeRequest mergeRequest;
private EventSnippet snippet;
public String getObjectKind() {
return (OBJECT_KIND);
}
public void setObjectKind(String objectKind) {
if (!OBJECT_KIND.equals(objectKind))
throw new RuntimeException("Invalid object_kind (" + objectKind + "), must be '" + OBJECT_KIND + "'");
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Integer getProjectId() {
return this.projectId;
}
public void setProjectId(Integer projectId) {
this.projectId = projectId;
}
public EventProject getProject() {
return project;
}
public void setProject(EventProject project) {
this.project = project;
}
public EventRepository getRepository() {
return repository;
}
public void setRepository(EventRepository repository) {
this.repository = repository;
}
public ObjectAttributes getObjectAttributes() {
return this.objectAttributes;
}
public void setObjectAttributes(ObjectAttributes objectAttributes) {
this.objectAttributes = objectAttributes;
}
public EventCommit getCommit() {
return commit;
}
public void setCommit(EventCommit commit) {
this.commit = commit;
}
public EventIssue getIssue() {
return issue;
}
public void setIssue(EventIssue issue) {
this.issue = issue;
}
public EventMergeRequest getMergeRequest() {
return mergeRequest;
}
public void setMergeRequest(EventMergeRequest mergeRequest) {
this.mergeRequest = mergeRequest;
}
public EventSnippet getSnippet() {
return snippet;
}
public void setSnippet(EventSnippet snippet) {
this.snippet = snippet;
}
public enum NoteableType {
COMMIT("Commit"),
ISSUE("Issue"),
MERGE_REQUEST("MergeRequest"),
SNIPPET("Snippet");
private String name;
NoteableType(String name) {
this.name = name;
}
@Override
public String toString() {
return (name);
}
}
@XmlAccessorType(XmlAccessType.FIELD)
public static class ObjectAttributes {
private Integer id;
private String note;
private NoteableType notableType;
private Integer authorId;
private Date createdAt;
private Date updatedAt;
private Integer projectId;
private String attachment;
private String lineCode;
private String commitId;
private Integer noteableId;
private Boolean system;
private Diff stDiff;
private String url;
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public NoteableType getNoteableType() {
return notableType;
}
public void setNoteableType(NoteableType notableType) {
this.notableType = notableType;
}
public Integer getAuthorId() {
return this.authorId;
}
public void setAuthorId(Integer authorId) {
this.authorId = authorId;
}
public Date getCreatedAt() {
return this.createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getUpdatedAt() {
return this.updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
public Integer getProjectId() {
return this.projectId;
}
public void setProjectId(Integer projectId) {
this.projectId = projectId;
}
public String getAttachment() {
return attachment;
}
public void setAttachment(String attachment) {
this.attachment = attachment;
}
public String getLineCode() {
return lineCode;
}
public void setLineCode(String lineCode) {
this.lineCode = lineCode;
}
public String getCommitId() {
return commitId;
}
public void setCommitId(String commitId) {
this.commitId = commitId;
}
public Integer getNoteableId() {
return noteableId;
}
public void setNoteableId(Integer noteableId) {
this.noteableId = noteableId;
}
public Boolean getSystem() {
return system;
}
public void setSystem(Boolean system) {
this.system = system;
}
public Diff getStDiff() {
return stDiff;
}
public void setStDiff(Diff stDiff) {
this.stDiff = stDiff;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
}
package org.gitlab4j.api.webhook;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@XmlAccessorType(XmlAccessType.FIELD)
public class TagPushEvent extends AbstractPushEvent {
public static final String X_GITLAB_EVENT = "Tag Push Hook";
public static final String OBJECT_KIND = "tag_push";
public String getObjectKind() {
return (OBJECT_KIND);
}
public void setObjectKind(String objectKind) {
if (!OBJECT_KIND.equals(objectKind))
throw new RuntimeException("Invalid object_kind (" + objectKind + "), must be '" + OBJECT_KIND + "'");
}
}
package org.gitlab4j.api.webhook;
import org.gitlab4j.api.webhook.IssueEvent;
import org.gitlab4j.api.webhook.MergeRequestEvent;
import org.gitlab4j.api.webhook.PushEvent;
/**
* This class defines an event listener for the event fired when
* a WebHook notification has been received from a GitLab server.
*/
public interface WebHookListener extends java.util.EventListener {
/**
* This method is called when a WebHook issue event has been received.
*
* @param event the EventObject instance containing info on the issue
*/
public void onIssueEvent(IssueEvent event);
/**
* This method is called when a WebHook merge request event has been received
*
* @param event the EventObject instance containing info on the merge request
*/
public void onMergeRequestEvent(MergeRequestEvent event);
/**
* This method is called when a WebHook push event has been received.
*
* @param pushEvent the PushEvent instance
*/
public void onPushEvent(PushEvent pushEvent);
/**
* This method is called when a WebHook tag push event has been received.
*
* @param tagPushEvent the TagPushEvent instance
*/
public void onTagPushEvent(TagPushEvent tagPushEvent);
/**
* This method is called when a WebHook note event has been received.
*
* @param noteEvent theNoteEvent instance
*/
public void onNoteEvent(NoteEvent noteEvent);
/**
* This method is called when a WebHook tag push event has been received.
*
* @param pushEvent the PushEvent instance
*/
public void onJobEvent(PushEvent pushEvent);
/**
* This method is called when a WebHook pipeline event has been received.
*
* @param pushEvent the PushEvent instance
*/
public void onPipelineEvent(PushEvent pushEvent);
/**
* This method is called when a WebHook wiki event has been received.
*
* @param pushEvent the PushEvent instance
*/
public void onWikiEvent(PushEvent pushEvent);
}
package org.gitlab4j.api.webhook;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import org.gitlab4j.api.GitLabApiException;
import org.gitlab4j.api.utils.HttpRequestUtils;
import org.gitlab4j.api.utils.JacksonJson;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
/**
* This class provides a handler for processing GitLab WebHook callouts.
*/
public class WebHookManager {
private final static Logger LOG = Logger.getLogger(WebHookManager.class.getName());
private final JacksonJson jacksonJson = new JacksonJson();
private String secretToken;
// Collection of objects listening for WebHook events.
private final List<WebHookListener> webhookListeners = new CopyOnWriteArrayList<WebHookListener>();
/**
* Create a WebHookManager to handle GitLab webhook events.
*/
public WebHookManager() {
this.secretToken = null;
}
/**
* Create a WebHookManager to handle GitLab webhook events which will be verified
* against the specified secretToken.
*
* @param secretToken the secret token to verify against
*/
public WebHookManager(String secretToken) {
this.secretToken = secretToken;
}
/**
* Set the secret token that received webhook events should be validated against.
*
* @param secretToken the secret token to verify against
*/
public void setSecretToken(String secretToken) {
this.secretToken = secretToken;
}
/**
* Validate the provided secret token against the reference secret token. Returns true if
* the secret token is valid or there is no reference secret token to validate against,
* otherwise returns false.
*
* @param secretToken the token to validate
* @return true if the secret token is valid or there is no reference secret token to validate against
*/
public boolean isValidSecretToken(String secretToken) {
return (this.secretToken == null || this.secretToken.equals(secretToken) ? true : false);
}
/**
* Validate the provided secret token found in the HTTP header against the reference secret token.
* Returns true if the secret token is valid or there is no reference secret token to validate
* against, otherwise returns false.
*
* @param request the HTTP request to verify the secret token
* @return true if the secret token is valid or there is no reference secret token to validate against
*/
public boolean isValidSecretToken(HttpServletRequest request) {
if (this.secretToken != null) {
String secretToken = request.getHeader("X-Gitlab-Token");
return (isValidSecretToken(secretToken));
}
return (true);
}
/**
* Parses and verifies an Event instance from the HTTP request and
* fires it off to the registered listeners.
*
* @param request the HttpServletRequest to read the Event instance from
* @throws GitLabApiException if the parsed event is not supported
*/
public void handleEvent(HttpServletRequest request) throws GitLabApiException {
if (!isValidSecretToken(request)) {
String message = "X-Gitlab-Token mismatch!";
LOG.warning(message);
throw new GitLabApiException(message);
}
String eventName = request.getHeader("X-Gitlab-Event");
LOG.info("handleEvent: X-Gitlab-Event=" + eventName);
switch (eventName) {
case IssueEvent.X_GITLAB_EVENT:
case MergeRequestEvent.X_GITLAB_EVENT:
case NoteEvent.X_GITLAB_EVENT:
case PushEvent.X_GITLAB_EVENT:
case TagPushEvent.X_GITLAB_EVENT:
break;
default:
String message = "Unsupported X-Gitlab-Event, event Name=" + eventName;
LOG.warning(message);
throw new GitLabApiException(message);
}
String errorMessage = null;
try {
Event event;
if (LOG.isLoggable(Level.FINE)) {
LOG.fine(HttpRequestUtils.getShortRequestDump(eventName + " webhook", true, request));
String postData = HttpRequestUtils.getPostDataAsString(request);
LOG.fine("Raw POST data:\n" + postData);
event = jacksonJson.unmarshal(Event.class, postData);
LOG.fine(event.getObjectKind() + " event:\n" + jacksonJson.marshal(event) + "\n");
} else {
InputStreamReader reader = new InputStreamReader(request.getInputStream());
event = jacksonJson.unmarshal(Event.class, reader);
}
fireEvent(event);
} catch (JsonParseException jpe) {
errorMessage = jpe.getMessage();
LOG.warning("Error parsing JSON data, error=" + errorMessage);
} catch (JsonMappingException jme) {
errorMessage = jme.getMessage();
LOG.warning("Error mapping JSON data, error=" + errorMessage);
} catch (IOException ioe) {
errorMessage = ioe.getMessage();
LOG.warning("Error reading JSON data, error=" + errorMessage);
} catch (Exception e) {
errorMessage = e.getMessage();
LOG.warning("Unexpected error reading JSON data, error=" + errorMessage);
}
if (errorMessage != null)
throw new GitLabApiException(errorMessage);
}
/**
* Verifies the provided Event and fires it off to the registered listeners.
*
* @param event the Event instance to handle
* @throws GitLabApiException if the event is not supported
*/
public void handleEvent(Event event) throws GitLabApiException {
LOG.info("handleEvent: object_kind=" + event.getObjectKind());
switch (event.getObjectKind()) {
case IssueEvent.OBJECT_KIND:
case MergeRequestEvent.OBJECT_KIND:
case NoteEvent.OBJECT_KIND:
case PushEvent.OBJECT_KIND:
case TagPushEvent.OBJECT_KIND:
break;
default:
String message = "Unsupported event object_kind, object_kind=" + event.getObjectKind();
LOG.warning(message);
throw new GitLabApiException(message);
}
fireEvent(event);
}
/**
* Adds a WebHook event listener.
*
* @param listener the WebHookListener to add
*/
public void addListener(WebHookListener listener) {
if (!webhookListeners.contains(listener)) {
webhookListeners.add(listener);
}
}
/**
* Removes a WebHook event listener.
*
* @param listener the WebHookListener to remove
*/
public void removeListener(WebHookListener listener) {
webhookListeners.remove(listener);
}
/**
* Fire the event to the registered listeners.
*
* @param event the Event instance to fire to the registered event listeners
* @throws GitLabApiException if the event is not supported
*/
public void fireEvent(Event event) throws GitLabApiException {
switch (event.getObjectKind()) {
case IssueEvent.OBJECT_KIND:
fireIssueEvent((IssueEvent) event);
break;
case MergeRequestEvent.OBJECT_KIND:
fireMergeRequestEvent((MergeRequestEvent) event);
break;
case NoteEvent.OBJECT_KIND:
fireNoteEvent((NoteEvent) event);
break;
case PushEvent.OBJECT_KIND:
firePushEvent((PushEvent) event);
break;
case TagPushEvent.OBJECT_KIND:
fireTagPushEvent((TagPushEvent) event);
break;
default:
String message = "Unsupported event object_kind, object_kind=" + event.getObjectKind();
LOG.warning(message);
throw new GitLabApiException(message);
}
}
protected void fireIssueEvent(IssueEvent issueEvent) {
for (WebHookListener listener : webhookListeners) {
listener.onIssueEvent(issueEvent);
}
}
protected void fireMergeRequestEvent(MergeRequestEvent mergeRequestEvent) {
for (WebHookListener listener : webhookListeners) {
listener.onMergeRequestEvent(mergeRequestEvent);
}
}
protected void fireNoteEvent(NoteEvent noteEvent) {
for (WebHookListener listener : webhookListeners) {
listener.onNoteEvent(noteEvent);
}
}
protected void firePushEvent(PushEvent pushEvent) {
for (WebHookListener listener : webhookListeners) {
listener.onPushEvent(pushEvent);
}
}
protected void fireTagPushEvent(TagPushEvent tagPushEvent) {
for (WebHookListener listener : webhookListeners) {
listener.onTagPushEvent(tagPushEvent);
}
}
}
{
"object_kind": "note",
"user": {
"name": "Administrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
},
"project_id": 5,
"project":{
"name":"Gitlab Test",
"description":"Aut reprehenderit ut est.",
"web_url":"http://example.com/gitlabhq/gitlab-test",
"git_ssh_url":"git@example.com:gitlabhq/gitlab-test.git",
"git_http_url":"http://example.com/gitlabhq/gitlab-test.git",
"namespace":"GitlabHQ",
"visibility_level":20,
"path_with_namespace":"gitlabhq/gitlab-test",
"default_branch":"master",
"homepage":"http://example.com/gitlabhq/gitlab-test",
"url":"http://example.com/gitlabhq/gitlab-test.git",
"ssh_url":"git@example.com:gitlabhq/gitlab-test.git",
"http_url":"http://example.com/gitlabhq/gitlab-test.git"
},
"repository":{
"name": "Gitlab Test",
"url": "http://example.com/gitlab-org/gitlab-test.git",
"description": "Aut reprehenderit ut est.",
"homepage": "http://example.com/gitlab-org/gitlab-test"
},
"object_attributes": {
"id": 1243,
"note": "This is a commit comment. How does this work?",
"noteable_type": "Commit",
"author_id": 1,
"created_at": "2015-05-17T18:08:09Z",
"updated_at": "2015-05-17T18:08:09Z",
"project_id": 5,
"line_code": "bec9703f7a456cd2b4ab5fb3220ae016e3e394e3_0_1",
"commit_id": "cfe32cf61b73a0d5e9f13e774abde7ff789b1660",
"system": false,
"st_diff": {
"diff": "--- /dev/null\n+++ b/six\n@@ -0,0 +1 @@\n+Subproject commit 409f37c4f05865e4fb208c771485f211a22c4c2d\n",
"new_path": "six",
"old_path": "six",
"a_mode": "0",
"b_mode": "160000",
"new_file": true,
"renamed_file": false,
"deleted_file": false
},
"url": "http://example.com/gitlab-org/gitlab-test/commit/cfe32cf61b73a0d5e9f13e774abde7ff789b1660#note_1243"
},
"commit": {
"id": "cfe32cf61b73a0d5e9f13e774abde7ff789b1660",
"message": "Add submodule\n\nSigned-off-by: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n",
"timestamp": "2014-02-27T10:06:20Z",
"url": "http://example.com/gitlab-org/gitlab-test/commit/cfe32cf61b73a0d5e9f13e774abde7ff789b1660",
"author": {
"name": "Dmitriy Zaporozhets",
"email": "dmitriy.zaporozhets@gmail.com"
}
}
}
\ No newline at end of file
{
"object_kind": "note",
"user": {
"name": "Administrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
},
"project_id": 5,
"project":{
"name":"Gitlab Test",
"description":"Aut reprehenderit ut est.",
"web_url":"http://example.com/gitlab-org/gitlab-test",
"git_ssh_url":"git@example.com:gitlab-org/gitlab-test.git",
"git_http_url":"http://example.com/gitlab-org/gitlab-test.git",
"namespace":"Gitlab Org",
"visibility_level":10,
"path_with_namespace":"gitlab-org/gitlab-test",
"default_branch":"master",
"homepage":"http://example.com/gitlab-org/gitlab-test",
"url":"http://example.com/gitlab-org/gitlab-test.git",
"ssh_url":"git@example.com:gitlab-org/gitlab-test.git",
"http_url":"http://example.com/gitlab-org/gitlab-test.git"
},
"repository":{
"name":"diaspora",
"url":"git@example.com:mike/diaspora.git",
"homepage":"http://example.com/mike/diaspora"
},
"object_attributes": {
"id": 1241,
"note": "Hello world",
"noteable_type": "Issue",
"author_id": 1,
"created_at": "2015-05-17T17:06:40Z",
"updated_at": "2015-05-17T17:06:40Z",
"project_id": 5,
"noteable_id": 92,
"system": false,
"url": "http://example.com/gitlab-org/gitlab-test/issues/17#note_1241"
},
"issue": {
"id": 92,
"title": "test",
"author_id": 1,
"project_id": 5,
"created_at": "2015-04-12T14:53:17Z",
"updated_at": "2015-04-26T08:28:42Z",
"position": 0,
"description": "test",
"state": "closed",
"iid": 17
}
}
\ No newline at end of file
{
"object_kind": "note",
"user": {
"name": "Administrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
},
"project_id": 5,
"project":{
"name":"Gitlab Test",
"description":"Aut reprehenderit ut est.",
"web_url":"http://example.com/gitlab-org/gitlab-test",
"git_ssh_url":"git@example.com:gitlab-org/gitlab-test.git",
"git_http_url":"http://example.com/gitlab-org/gitlab-test.git",
"namespace":"Gitlab Org",
"visibility_level":10,
"path_with_namespace":"gitlab-org/gitlab-test",
"default_branch":"master",
"homepage":"http://example.com/gitlab-org/gitlab-test",
"url":"http://example.com/gitlab-org/gitlab-test.git",
"ssh_url":"git@example.com:gitlab-org/gitlab-test.git",
"http_url":"http://example.com/gitlab-org/gitlab-test.git"
},
"repository":{
"name": "Gitlab Test",
"url": "http://localhost/gitlab-org/gitlab-test.git",
"description": "Aut reprehenderit ut est.",
"homepage": "http://example.com/gitlab-org/gitlab-test"
},
"object_attributes": {
"id": 1244,
"note": "This MR needs work.",
"noteable_type": "MergeRequest",
"author_id": 1,
"created_at": "2015-05-17T18:21:36Z",
"updated_at": "2015-05-17T18:21:36Z",
"project_id": 5,
"commit_id": "",
"noteable_id": 7,
"system": false,
"url": "http://example.com/gitlab-org/gitlab-test/merge_requests/1#note_1244"
},
"merge_request": {
"id": 7,
"target_branch": "markdown",
"source_branch": "master",
"source_project_id": 5,
"author_id": 8,
"assignee_id": 28,
"title": "Tempora et eos debitis quae laborum et.",
"created_at": "2015-03-01T20:12:53Z",
"updated_at": "2015-03-21T18:27:27Z",
"milestone_id": 11,
"state": "opened",
"merge_status": "cannot_be_merged",
"target_project_id": 5,
"iid": 1,
"description": "Et voluptas corrupti assumenda temporibus. Architecto cum animi eveniet amet asperiores. Vitae numquam voluptate est natus sit et ad id.",
"position": 0,
"source":{
"name":"Gitlab Test",
"description":"Aut reprehenderit ut est.",
"web_url":"http://example.com/gitlab-org/gitlab-test",
"git_ssh_url":"git@example.com:gitlab-org/gitlab-test.git",
"git_http_url":"http://example.com/gitlab-org/gitlab-test.git",
"namespace":"Gitlab Org",
"visibility_level":10,
"path_with_namespace":"gitlab-org/gitlab-test",
"default_branch":"master",
"homepage":"http://example.com/gitlab-org/gitlab-test",
"url":"http://example.com/gitlab-org/gitlab-test.git",
"ssh_url":"git@example.com:gitlab-org/gitlab-test.git",
"http_url":"http://example.com/gitlab-org/gitlab-test.git"
},
"target": {
"name":"Gitlab Test",
"description":"Aut reprehenderit ut est.",
"web_url":"http://example.com/gitlab-org/gitlab-test",
"git_ssh_url":"git@example.com:gitlab-org/gitlab-test.git",
"git_http_url":"http://example.com/gitlab-org/gitlab-test.git",
"namespace":"Gitlab Org",
"visibility_level":10,
"path_with_namespace":"gitlab-org/gitlab-test",
"default_branch":"master",
"homepage":"http://example.com/gitlab-org/gitlab-test",
"url":"http://example.com/gitlab-org/gitlab-test.git",
"ssh_url":"git@example.com:gitlab-org/gitlab-test.git",
"http_url":"http://example.com/gitlab-org/gitlab-test.git"
},
"last_commit": {
"id": "562e173be03b8ff2efb05345d12df18815438a4b",
"message": "Merge branch 'another-branch' into 'master'\n\nCheck in this test\n",
"timestamp": "2015-04-08T21:00:25Z",
"url": "http://example.com/gitlab-org/gitlab-test/commit/562e173be03b8ff2efb05345d12df18815438a4b",
"author": {
"name": "John Smith",
"email": "john@example.com"
}
},
"work_in_progress": false,
"assignee": {
"name": "User1",
"username": "user1",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
}
}
}
\ No newline at end of file
{
"object_kind": "note",
"user": {
"name": "Administrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
},
"project_id": 5,
"project":{
"name":"Gitlab Test",
"description":"Aut reprehenderit ut est.",
"web_url":"http://example.com/gitlab-org/gitlab-test",
"git_ssh_url":"git@example.com:gitlab-org/gitlab-test.git",
"git_http_url":"http://example.com/gitlab-org/gitlab-test.git",
"namespace":"Gitlab Org",
"visibility_level":10,
"path_with_namespace":"gitlab-org/gitlab-test",
"default_branch":"master",
"homepage":"http://example.com/gitlab-org/gitlab-test",
"url":"http://example.com/gitlab-org/gitlab-test.git",
"ssh_url":"git@example.com:gitlab-org/gitlab-test.git",
"http_url":"http://example.com/gitlab-org/gitlab-test.git"
},
"repository":{
"name":"Gitlab Test",
"url":"http://example.com/gitlab-org/gitlab-test.git",
"description":"Aut reprehenderit ut est.",
"homepage":"http://example.com/gitlab-org/gitlab-test"
},
"object_attributes": {
"id": 1245,
"note": "Is this snippet doing what it's supposed to be doing?",
"noteable_type": "Snippet",
"author_id": 1,
"created_at": "2015-05-17T18:35:50Z",
"updated_at": "2015-05-17T18:35:50Z",
"project_id": 5,
"commit_id": "",
"noteable_id": 53,
"system": false,
"url": "http://example.com/gitlab-org/gitlab-test/snippets/53#note_1245"
},
"snippet": {
"id": 53,
"title": "test",
"content": "puts 'Hello world'",
"author_id": 1,
"project_id": 5,
"created_at": "2015-04-09T02:40:38Z",
"updated_at": "2015-04-09T02:40:38Z",
"file_name": "test.rb",
"type": "ProjectSnippet",
"visibility_level": 0
}
}
\ No newline at end of file
{
"object_kind": "tag_push",
"before": "0000000000000000000000000000000000000000",
"after": "82b3d5ae55f7080f1e6022629cdb57bfae7cccc7",
"ref": "refs/tags/v1.0.0",
"checkout_sha": "82b3d5ae55f7080f1e6022629cdb57bfae7cccc7",
"user_id": 1,
"user_name": "John Smith",
"user_avatar": "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80",
"project_id": 1,
"project":{
"name":"Example",
"description":"",
"web_url":"http://example.com/jsmith/example",
"git_ssh_url":"git@example.com:jsmith/example.git",
"git_http_url":"http://example.com/jsmith/example.git",
"namespace":"Jsmith",
"visibility_level":0,
"path_with_namespace":"jsmith/example",
"default_branch":"master",
"homepage":"http://example.com/jsmith/example",
"url":"git@example.com:jsmith/example.git",
"ssh_url":"git@example.com:jsmith/example.git",
"http_url":"http://example.com/jsmith/example.git"
},
"repository":{
"name": "Example",
"url": "ssh://git@example.com/jsmith/example.git",
"description": "",
"homepage": "http://example.com/jsmith/example",
"git_http_url":"http://example.com/jsmith/example.git",
"git_ssh_url":"git@example.com:jsmith/example.git",
"visibility_level":0
},
"commits": [],
"total_commits_count": 0
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment