From 71bef0d65f309d8abca344cf681a043fedd94ac0 Mon Sep 17 00:00:00 2001 From: Jeremie Bresson Date: Thu, 17 Oct 2024 10:48:18 +0200 Subject: [PATCH] Add WorkItemEvent --- .../gitlab4j/api/webhook/AbstractEvent.java | 9 + .../java/org/gitlab4j/api/webhook/Event.java | 1 + .../org/gitlab4j/api/webhook/EventLabel.java | 3 +- .../gitlab4j/api/webhook/EventWorkItem.java | 285 ++++++++++++++++++ .../gitlab4j/api/webhook/IssueChanges.java | 9 + .../gitlab4j/api/webhook/WorkItemChanges.java | 24 ++ .../gitlab4j/api/webhook/WorkItemEvent.java | 84 ++++++ .../org/gitlab4j/api/TestGitLabApiEvents.java | 13 + .../org/gitlab4j/api/workitem-event.json | 83 +++++ 9 files changed, 510 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/gitlab4j/api/webhook/EventWorkItem.java create mode 100644 src/main/java/org/gitlab4j/api/webhook/WorkItemChanges.java create mode 100644 src/main/java/org/gitlab4j/api/webhook/WorkItemEvent.java create mode 100644 src/test/resources/org/gitlab4j/api/workitem-event.json diff --git a/src/main/java/org/gitlab4j/api/webhook/AbstractEvent.java b/src/main/java/org/gitlab4j/api/webhook/AbstractEvent.java index 97d170121..2c8f66194 100644 --- a/src/main/java/org/gitlab4j/api/webhook/AbstractEvent.java +++ b/src/main/java/org/gitlab4j/api/webhook/AbstractEvent.java @@ -5,10 +5,19 @@ public abstract class AbstractEvent implements Event { private static final long serialVersionUID = 1L; + private String eventType; private String requestUrl; private String requestQueryString; private String secretToken; + public String getEventType() { + return eventType; + } + + public void setEventType(String eventType) { + this.eventType = eventType; + } + @Override public void setRequestUrl(String requestUrl) { this.requestUrl = requestUrl; diff --git a/src/main/java/org/gitlab4j/api/webhook/Event.java b/src/main/java/org/gitlab4j/api/webhook/Event.java index 6c46f0642..7892039e2 100644 --- a/src/main/java/org/gitlab4j/api/webhook/Event.java +++ b/src/main/java/org/gitlab4j/api/webhook/Event.java @@ -10,6 +10,7 @@ @JsonSubTypes({ @JsonSubTypes.Type(value = BuildEvent.class, name = BuildEvent.OBJECT_KIND), @JsonSubTypes.Type(value = IssueEvent.class, name = IssueEvent.OBJECT_KIND), + @JsonSubTypes.Type(value = WorkItemEvent.class, name = WorkItemEvent.OBJECT_KIND), @JsonSubTypes.Type(value = JobEvent.class, name = JobEvent.OBJECT_KIND), @JsonSubTypes.Type(value = MergeRequestEvent.class, name = MergeRequestEvent.OBJECT_KIND), @JsonSubTypes.Type(value = NoteEvent.class, name = NoteEvent.OBJECT_KIND), diff --git a/src/main/java/org/gitlab4j/api/webhook/EventLabel.java b/src/main/java/org/gitlab4j/api/webhook/EventLabel.java index 3a0ed1913..7b29c7ee0 100644 --- a/src/main/java/org/gitlab4j/api/webhook/EventLabel.java +++ b/src/main/java/org/gitlab4j/api/webhook/EventLabel.java @@ -11,7 +11,8 @@ public class EventLabel { public enum LabelType { - PROJECT_LABEL; + PROJECT_LABEL, + GROUP_LABEL; private static JacksonJsonEnumHelper enumHelper = new JacksonJsonEnumHelper<>(LabelType.class, true, true); diff --git a/src/main/java/org/gitlab4j/api/webhook/EventWorkItem.java b/src/main/java/org/gitlab4j/api/webhook/EventWorkItem.java new file mode 100644 index 000000000..d542e06cf --- /dev/null +++ b/src/main/java/org/gitlab4j/api/webhook/EventWorkItem.java @@ -0,0 +1,285 @@ +package org.gitlab4j.api.webhook; + +import java.util.Date; +import java.util.List; + +import org.gitlab4j.api.utils.JacksonJson; + +public class EventWorkItem { + + private Long authorId; + private Date closedAt; + private Boolean confidential; + private Date createdAt; + private String description; + private Date dueDate; + private Long id; + private Long iid; + private Date lastEditedAt; + private Long lastEditedById; + private Long milestoneId; + private Long projectId; + private Long relativePosition; + private Long stateId; + private Integer timeEstimate; + private String title; + private Date updatedAt; + private Long updatedById; + private Integer weight; + private String healthStatus; + private String type; + private String url; + private Integer totalTimeSpent; + private Integer timeChange; + private List assigneeIds; + private Long assigneeId; + private List labels; + private String state; + private String severity; + private String action; + + public Long getAuthorId() { + return authorId; + } + + public void setAuthorId(Long authorId) { + this.authorId = authorId; + } + + public Date getClosedAt() { + return closedAt; + } + + public void setClosedAt(Date closedAt) { + this.closedAt = closedAt; + } + + public Boolean getConfidential() { + return confidential; + } + + public void setConfidential(Boolean confidential) { + this.confidential = confidential; + } + + public Date getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Date getDueDate() { + return dueDate; + } + + public void setDueDate(Date dueDate) { + this.dueDate = dueDate; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getIid() { + return iid; + } + + public void setIid(Long iid) { + this.iid = iid; + } + + public Date getLastEditedAt() { + return lastEditedAt; + } + + public void setLastEditedAt(Date lastEditedAt) { + this.lastEditedAt = lastEditedAt; + } + + public Long getLastEditedById() { + return lastEditedById; + } + + public void setLastEditedById(Long lastEditedById) { + this.lastEditedById = lastEditedById; + } + + public Long getMilestoneId() { + return milestoneId; + } + + public void setMilestoneId(Long milestoneId) { + this.milestoneId = milestoneId; + } + + public Long getProjectId() { + return projectId; + } + + public void setProjectId(Long projectId) { + this.projectId = projectId; + } + + public Long getRelativePosition() { + return relativePosition; + } + + public void setRelativePosition(Long relativePosition) { + this.relativePosition = relativePosition; + } + + public Long getStateId() { + return stateId; + } + + public void setStateId(Long stateId) { + this.stateId = stateId; + } + + public Integer getTimeEstimate() { + return timeEstimate; + } + + public void setTimeEstimate(Integer timeEstimate) { + this.timeEstimate = timeEstimate; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public Date getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Date updatedAt) { + this.updatedAt = updatedAt; + } + + public Long getUpdatedById() { + return updatedById; + } + + public void setUpdatedById(Long updatedById) { + this.updatedById = updatedById; + } + + public Integer getWeight() { + return weight; + } + + public void setWeight(Integer weight) { + this.weight = weight; + } + + public String getHealthStatus() { + return healthStatus; + } + + public void setHealthStatus(String healthStatus) { + this.healthStatus = healthStatus; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public Integer getTotalTimeSpent() { + return totalTimeSpent; + } + + public void setTotalTimeSpent(Integer totalTimeSpent) { + this.totalTimeSpent = totalTimeSpent; + } + + public Integer getTimeChange() { + return timeChange; + } + + public void setTimeChange(Integer timeChange) { + this.timeChange = timeChange; + } + + public List getAssigneeIds() { + return assigneeIds; + } + + public void setAssigneeIds(List assigneeIds) { + this.assigneeIds = assigneeIds; + } + + public Long getAssigneeId() { + return assigneeId; + } + + public void setAssigneeId(Long assigneeId) { + this.assigneeId = assigneeId; + } + + public List getLabels() { + return labels; + } + + public void setLabels(List labels) { + this.labels = labels; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public String getSeverity() { + return severity; + } + + public void setSeverity(String severity) { + this.severity = severity; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + @Override + public String toString() { + return (JacksonJson.toJsonString(this)); + } +} diff --git a/src/main/java/org/gitlab4j/api/webhook/IssueChanges.java b/src/main/java/org/gitlab4j/api/webhook/IssueChanges.java index f2ca2d425..9e52adec7 100644 --- a/src/main/java/org/gitlab4j/api/webhook/IssueChanges.java +++ b/src/main/java/org/gitlab4j/api/webhook/IssueChanges.java @@ -6,6 +6,7 @@ public class IssueChanges extends EventChanges { private ChangeContainer dueDate; private ChangeContainer confidential; + private ChangeContainer heathStatus; public ChangeContainer getDueDate() { return dueDate; @@ -22,4 +23,12 @@ public ChangeContainer getConfidential() { public void setConfidential(ChangeContainer confidential) { this.confidential = confidential; } + + public ChangeContainer getHeathStatus() { + return heathStatus; + } + + public void setHeathStatus(ChangeContainer heathStatus) { + this.heathStatus = heathStatus; + } } diff --git a/src/main/java/org/gitlab4j/api/webhook/WorkItemChanges.java b/src/main/java/org/gitlab4j/api/webhook/WorkItemChanges.java new file mode 100644 index 000000000..6bb3ac84f --- /dev/null +++ b/src/main/java/org/gitlab4j/api/webhook/WorkItemChanges.java @@ -0,0 +1,24 @@ +package org.gitlab4j.api.webhook; + +import java.util.Date; + +public class WorkItemChanges extends EventChanges { + private ChangeContainer heathStatus; + private ChangeContainer lastEditedAt; + + public ChangeContainer getHeathStatus() { + return heathStatus; + } + + public void setHeathStatus(ChangeContainer heathStatus) { + this.heathStatus = heathStatus; + } + + public ChangeContainer getLastEditedAt() { + return lastEditedAt; + } + + public void setLastEditedAt(ChangeContainer lastEditedAt) { + this.lastEditedAt = lastEditedAt; + } +} diff --git a/src/main/java/org/gitlab4j/api/webhook/WorkItemEvent.java b/src/main/java/org/gitlab4j/api/webhook/WorkItemEvent.java new file mode 100644 index 000000000..8d883d32d --- /dev/null +++ b/src/main/java/org/gitlab4j/api/webhook/WorkItemEvent.java @@ -0,0 +1,84 @@ +package org.gitlab4j.api.webhook; + +import java.util.List; + +import org.gitlab4j.api.models.User; +import org.gitlab4j.api.utils.JacksonJson; + +public class WorkItemEvent extends AbstractEvent { + private static final long serialVersionUID = 1L; + + public static final String X_GITLAB_EVENT = "Issue Hook"; + public static final String OBJECT_KIND = "work_item"; + + private User user; + private EventProject project; + private EventRepository repository; + private ObjectAttributes objectAttributes; + private List labels; + private WorkItemChanges changes; + + 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 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 List getLabels() { + return labels; + } + + public void setLabels(List labels) { + this.labels = labels; + } + + public WorkItemChanges getChanges() { + return changes; + } + + public void setChanges(WorkItemChanges changes) { + this.changes = changes; + } + + public ObjectAttributes getObjectAttributes() { + return this.objectAttributes; + } + + public void setObjectAttributes(ObjectAttributes objectAttributes) { + this.objectAttributes = objectAttributes; + } + + public static class ObjectAttributes extends EventWorkItem {} + + @Override + public String toString() { + return (JacksonJson.toJsonString(this)); + } +} diff --git a/src/test/java/org/gitlab4j/api/TestGitLabApiEvents.java b/src/test/java/org/gitlab4j/api/TestGitLabApiEvents.java index a349a8897..215fd7975 100644 --- a/src/test/java/org/gitlab4j/api/TestGitLabApiEvents.java +++ b/src/test/java/org/gitlab4j/api/TestGitLabApiEvents.java @@ -35,6 +35,7 @@ import org.gitlab4j.api.webhook.PushEvent; import org.gitlab4j.api.webhook.TagPushEvent; import org.gitlab4j.api.webhook.WikiPageEvent; +import org.gitlab4j.api.webhook.WorkItemEvent; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -76,6 +77,18 @@ public void testIssueEvent() throws Exception { assertEquals(456, (int) idChange.getCurrent()); } + @Test + public void testWorkItemEvent() throws Exception { + + WorkItemEvent workItemEvent = unmarshalResource(WorkItemEvent.class, "workitem-event.json"); + assertTrue(compareJson(workItemEvent, "workitem-event.json")); + + ChangeContainer change = workItemEvent.getChanges().get("health_status"); + assertNotNull(change); + assertEquals("on_track", change.getPrevious()); + assertEquals("needs_attention", change.getCurrent()); + } + @Test public void testIssueChanges() throws Exception { diff --git a/src/test/resources/org/gitlab4j/api/workitem-event.json b/src/test/resources/org/gitlab4j/api/workitem-event.json new file mode 100644 index 000000000..241559be7 --- /dev/null +++ b/src/test/resources/org/gitlab4j/api/workitem-event.json @@ -0,0 +1,83 @@ +{ + "object_kind": "work_item", + "event_type": "work_item", + "user": { + "id": 1245, + "name": "John Smith", + "username": "john.smith", + "avatar_url": "https://[REDACTED]/uploads/-/system/user/avatar/1245/avatar.png", + "email": "[REDACTED]" + }, + "object_attributes": { + "author_id": 1245, + "closed_at": "2024-09-20T16:53:38Z", + "confidential": false, + "created_at": "2024-09-20T16:53:38Z", + "description": "This is a test.\n\nThis is a test.", + "id": 93843, + "iid": 1, + "last_edited_at": "2024-10-17T06:47:37Z", + "last_edited_by_id": 1245, + "relative_position": 147, + "state_id": 1, + "time_estimate": 0, + "title": "Test Epic item", + "updated_at": "2024-10-17T06:47:37Z", + "updated_by_id": 1245, + "weight": 23, + "health_status": "on_track", + "type": "Epic", + "url": "https://[REDACTED]/groups/a-group/-/work_items/1", + "total_time_spent": 0, + "time_change": 0, + "assignee_ids": [], + "assignee_id": 345, + "labels": [ + { + "id": 15466, + "title": "status::RequirementsAndSpecification", + "color": "#808080", + "created_at": "2024-08-14T08:37:44Z", + "updated_at": "2024-08-14T08:37:44Z", + "template": false, + "description": "RequirementsAndSpecification", + "type": "GroupLabel", + "group_id": 91648 + } + ], + "state": "opened", + "severity": "unknown", + "action": "update" + }, + "labels": [ + { + "id": 15466, + "title": "status::RequirementsAndSpecification", + "color": "#808080", + "created_at": "2024-08-14T08:37:44Z", + "updated_at": "2024-08-14T08:37:44Z", + "template": false, + "description": "RequirementsAndSpecification", + "type": "GroupLabel", + "group_id": 91648 + } + ], + "changes": { + "description": { + "previous": "This is a test", + "current": "This is a test.\n\nThis is a test." + }, + "last_edited_at": { + "previous": "2024-09-20T16:53:38Z", + "current": "2024-10-17T06:47:37Z" + }, + "updated_at": { + "previous": "2024-09-24T08:54:43Z", + "current": "2024-10-17T06:47:37Z" + }, + "health_status": { + "previous":"on_track", + "current":"needs_attention" + } + } +} \ No newline at end of file