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

Added support for issue links (#419).

parent ec54b2a2
...@@ -35,12 +35,15 @@ import org.gitlab4j.api.GitLabApi.ApiVersion; ...@@ -35,12 +35,15 @@ import org.gitlab4j.api.GitLabApi.ApiVersion;
import org.gitlab4j.api.models.Duration; import org.gitlab4j.api.models.Duration;
import org.gitlab4j.api.models.Issue; import org.gitlab4j.api.models.Issue;
import org.gitlab4j.api.models.IssueFilter; import org.gitlab4j.api.models.IssueFilter;
import org.gitlab4j.api.models.IssueLink;
import org.gitlab4j.api.models.MergeRequest; import org.gitlab4j.api.models.MergeRequest;
import org.gitlab4j.api.models.TimeStats; import org.gitlab4j.api.models.TimeStats;
import org.gitlab4j.api.utils.DurationUtils; import org.gitlab4j.api.utils.DurationUtils;
/** /**
* This class provides an entry point to all the GitLab API Issue calls. * This class provides an entry point to all the GitLab API Issue calls.
* @see <a href="https://docs.gitlab.com/ce/api/issues.html">Issues API at GitLab</a>
* @see <a href="https://docs.gitlab.com/ce/api/issue_links.html">Issue Links API at GitLab</a>
*/ */
public class IssuesApi extends AbstractApi implements Constants { public class IssuesApi extends AbstractApi implements Constants {
...@@ -81,7 +84,7 @@ public class IssuesApi extends AbstractApi implements Constants { ...@@ -81,7 +84,7 @@ public class IssuesApi extends AbstractApi implements Constants {
* <pre><code>GitLab Endpoint: GET /issues</code></pre> * <pre><code>GitLab Endpoint: GET /issues</code></pre>
*r *r
* @param itemsPerPage the number of issues per page * @param itemsPerPage the number of issues per page
* @return the list of issues in the specified range * @return the Pager of issues in the specified range
* @throws GitLabApiException if any exception occurs * @throws GitLabApiException if any exception occurs
*/ */
public Pager<Issue> getIssues(int itemsPerPage) throws GitLabApiException { public Pager<Issue> getIssues(int itemsPerPage) throws GitLabApiException {
...@@ -101,7 +104,7 @@ public class IssuesApi extends AbstractApi implements Constants { ...@@ -101,7 +104,7 @@ public class IssuesApi extends AbstractApi implements Constants {
} }
/** /**
* Get a list of project's issues. Only returns the first page * Get a list of project's issues.
* *
* <pre><code>GitLab Endpoint: GET /projects/:id/issues</code></pre> * <pre><code>GitLab Endpoint: GET /projects/:id/issues</code></pre>
* *
...@@ -136,7 +139,7 @@ public class IssuesApi extends AbstractApi implements Constants { ...@@ -136,7 +139,7 @@ public class IssuesApi extends AbstractApi implements Constants {
* *
* @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance * @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
* @param itemsPerPage the number of issues per page * @param itemsPerPage the number of issues per page
* @return the list of issues in the specified range * @return the Pager of issues in the specified range
* @throws GitLabApiException if any exception occurs * @throws GitLabApiException if any exception occurs
*/ */
public Pager<Issue> getIssues(Object projectIdOrPath, int itemsPerPage) throws GitLabApiException { public Pager<Issue> getIssues(Object projectIdOrPath, int itemsPerPage) throws GitLabApiException {
...@@ -196,7 +199,7 @@ public class IssuesApi extends AbstractApi implements Constants { ...@@ -196,7 +199,7 @@ public class IssuesApi extends AbstractApi implements Constants {
* @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance * @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
* @param filter {@link IssueFilter} a IssueFilter instance with the filter settings. * @param filter {@link IssueFilter} a IssueFilter instance with the filter settings.
* @param itemsPerPage the number of Project instances that will be fetched per page. * @param itemsPerPage the number of Project instances that will be fetched per page.
* @return the list of issues in the specified range. * @return the Pager of issues in the specified range.
* @throws GitLabApiException if any exception occurs * @throws GitLabApiException if any exception occurs
*/ */
public Pager<Issue> getIssues(Object projectIdOrPath, IssueFilter filter, int itemsPerPage) throws GitLabApiException { public Pager<Issue> getIssues(Object projectIdOrPath, IssueFilter filter, int itemsPerPage) throws GitLabApiException {
...@@ -258,7 +261,7 @@ public class IssuesApi extends AbstractApi implements Constants { ...@@ -258,7 +261,7 @@ public class IssuesApi extends AbstractApi implements Constants {
* *
* @param filter {@link IssueFilter} a IssueFilter instance with the filter settings. * @param filter {@link IssueFilter} a IssueFilter instance with the filter settings.
* @param itemsPerPage the number of Project instances that will be fetched per page. * @param itemsPerPage the number of Project instances that will be fetched per page.
* @return the list of issues in the specified range. * @return the Pager of issues in the specified range.
* @throws GitLabApiException if any exception occurs * @throws GitLabApiException if any exception occurs
*/ */
public Pager<Issue> getIssues(IssueFilter filter, int itemsPerPage) throws GitLabApiException { public Pager<Issue> getIssues(IssueFilter filter, int itemsPerPage) throws GitLabApiException {
...@@ -273,7 +276,7 @@ public class IssuesApi extends AbstractApi implements Constants { ...@@ -273,7 +276,7 @@ public class IssuesApi extends AbstractApi implements Constants {
* <pre><code>GitLab Endpoint: GET /issues</code></pre> * <pre><code>GitLab Endpoint: GET /issues</code></pre>
* *
* @param filter {@link IssueFilter} a IssueFilter instance with the filter settings * @param filter {@link IssueFilter} a IssueFilter instance with the filter settings
* @return the list of issues in the specified range. * @return the Stream of issues in the specified range.
* @throws GitLabApiException if any exception occurs * @throws GitLabApiException if any exception occurs
*/ */
public Stream<Issue> getIssuesStream(IssueFilter filter) throws GitLabApiException { public Stream<Issue> getIssuesStream(IssueFilter filter) throws GitLabApiException {
...@@ -698,4 +701,102 @@ public class IssuesApi extends AbstractApi implements Constants { ...@@ -698,4 +701,102 @@ public class IssuesApi extends AbstractApi implements Constants {
public Stream<MergeRequest> getClosedByMergeRequestsStream(Object projectIdOrPath, Integer issueIid) throws GitLabApiException { public Stream<MergeRequest> getClosedByMergeRequestsStream(Object projectIdOrPath, Integer issueIid) throws GitLabApiException {
return (getClosedByMergeRequests(projectIdOrPath, issueIid, getDefaultPerPage()).stream()); return (getClosedByMergeRequests(projectIdOrPath, issueIid, getDefaultPerPage()).stream());
} }
/**
* Get a list of related issues of a given issue, sorted by the relationship creation datetime (ascending).
* Issues will be filtered according to the user authorizations.
*
* <p>NOTE: Only available in GitLab Starter, GitLab Bronze, and higher tiers.</p>
*
* <pre><code>GitLab Endpoint: GET /projects/:id/issues/:issue_iid/links</code></pre>
*
* @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
* @param issueIid the internal ID of a project's issue
* @return a list of related issues of a given issue, sorted by the relationship creation datetime (ascending)
* @throws GitLabApiException if any exception occurs
*/
public List<Issue> getIssueLinks(Object projectIdOrPath, Integer issueIid) throws GitLabApiException {
return (getIssueLinks(projectIdOrPath, issueIid, getDefaultPerPage()).all());
}
/**
* Get a Pager of related issues of a given issue, sorted by the relationship creation datetime (ascending).
* Issues will be filtered according to the user authorizations.
*
* <p>NOTE: Only available in GitLab Starter, GitLab Bronze, and higher tiers.</p>
*
* <pre><code>GitLab Endpoint: GET /projects/:id/issues/:issue_iid/links</code></pre>
*
* @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
* @param issueIid the internal ID of a project's issue
* @param itemsPerPage the number of issues per page
* @return a Pager of related issues of a given issue, sorted by the relationship creation datetime (ascending)
* @throws GitLabApiException if any exception occurs
*/
public Pager<Issue> getIssueLinks(Object projectIdOrPath, Integer issueIid, int itemsPerPage) throws GitLabApiException {
return (new Pager<Issue>(this, Issue.class, itemsPerPage, null,
"projects", getProjectIdOrPath(projectIdOrPath), "issues", issueIid, "links"));
}
/**
* Get a Stream of related issues of a given issue, sorted by the relationship creation datetime (ascending).
* Issues will be filtered according to the user authorizations.
*
* <p>NOTE: Only available in GitLab Starter, GitLab Bronze, and higher tiers.</p>
*
* <pre><code>GitLab Endpoint: GET /projects/:id/issues/:issue_iid/links</code></pre>
*
* @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
* @param issueIid the internal ID of a project's issue
* @return a Stream of related issues of a given issue, sorted by the relationship creation datetime (ascending)
* @throws GitLabApiException if any exception occurs
*/
public Stream<Issue> getIssueLinksStream(Object projectIdOrPath, Integer issueIid) throws GitLabApiException {
return (getIssueLinks(projectIdOrPath, issueIid, getDefaultPerPage()).stream());
}
/**
* Creates a two-way relation between two issues. User must be allowed to update both issues in order to succeed.
*
* <p>NOTE: Only available in GitLab Starter, GitLab Bronze, and higher tiers.</p>
*
* <pre><code>GitLab Endpoint: POST /projects/:id/issues/:issue_iid/links</code></pre>
*
* @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
* @param issueIid the internal ID of a project's issue
* @param targetProjectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance of the target project
* @param targetIssueIid the internal ID of a target project’s issue
* @return an instance of IssueLink holding the link relationship
* @throws GitLabApiException if any exception occurs
*/
public IssueLink createIssueLink(Object projectIdOrPath, Integer issueIid,
Object targetProjectIdOrPath, Integer targetIssueIid) throws GitLabApiException {
GitLabApiForm formData = new GitLabApiForm()
.withParam("target_project_id", getProjectIdOrPath(targetProjectIdOrPath), true)
.withParam("target_issue_iid", targetIssueIid, true);
Response response = post(Response.Status.OK, formData.asMap(),
"projects", getProjectIdOrPath(projectIdOrPath), "issues", issueIid, "links");
return (response.readEntity(IssueLink.class));
}
/**
* Deletes an issue link, thus removes the two-way relationship.
*
* <p>NOTE: Only available in GitLab Starter, GitLab Bronze, and higher tiers.</p>
*
* <pre><code>GitLab Endpoint: POST /projects/:id/issues/:issue_iid/links/:issue_link_id</code></pre>
*
* @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
* @param issueIid the internal ID of a project's issue, required
* @param issueLinkId the ID of an issue relationship, required
* @return an instance of IssueLink holding the deleted link relationship
* @throws GitLabApiException if any exception occurs
*/
public IssueLink deleteIssueLink(Object projectIdOrPath, Integer issueIid, Integer issueLinkId) throws GitLabApiException {
Response response = delete(Response.Status.OK, null,
"projects", getProjectIdOrPath(projectIdOrPath), "issues", issueIid, "links", issueLinkId);
return (response.readEntity(IssueLink.class));
}
} }
...@@ -21,6 +21,7 @@ public class Issue { ...@@ -21,6 +21,7 @@ public class Issue {
private Date dueDate; private Date dueDate;
private Integer id; private Integer id;
private Integer iid; private Integer iid;
private Integer issueLinkId;
private List<String> labels; private List<String> labels;
private Milestone milestone; private Milestone milestone;
private Integer projectId; private Integer projectId;
...@@ -105,6 +106,14 @@ public class Issue { ...@@ -105,6 +106,14 @@ public class Issue {
this.iid = iid; this.iid = iid;
} }
public Integer getIssueLinkId() {
return issueLinkId;
}
public void setIssueLinkId(Integer issueLinkId) {
this.issueLinkId = issueLinkId;
}
public List<String> getLabels() { public List<String> getLabels() {
return labels; return labels;
} }
......
...@@ -58,6 +58,7 @@ import org.gitlab4j.api.models.HealthCheckInfo; ...@@ -58,6 +58,7 @@ import org.gitlab4j.api.models.HealthCheckInfo;
import org.gitlab4j.api.models.ImpersonationToken; import org.gitlab4j.api.models.ImpersonationToken;
import org.gitlab4j.api.models.ImportStatus; import org.gitlab4j.api.models.ImportStatus;
import org.gitlab4j.api.models.Issue; import org.gitlab4j.api.models.Issue;
import org.gitlab4j.api.models.IssueLink;
import org.gitlab4j.api.models.Job; import org.gitlab4j.api.models.Job;
import org.gitlab4j.api.models.Key; import org.gitlab4j.api.models.Key;
import org.gitlab4j.api.models.Label; import org.gitlab4j.api.models.Label;
...@@ -231,6 +232,18 @@ public class TestGitLabApiBeans { ...@@ -231,6 +232,18 @@ public class TestGitLabApiBeans {
assertTrue(compareJson(issue, "issue.json")); assertTrue(compareJson(issue, "issue.json"));
} }
@Test
public void testIssueLink() throws Exception {
IssueLink issueLink = unmarshalResource(IssueLink.class, "issue-link.json");
assertTrue(compareJson(issueLink, "issue-link.json"));
}
@Test
public void testLinkedIssues() throws Exception {
List<Issue> linkedIssues = unmarshalResourceList(Issue.class, "linked-issues.json");
assertTrue(compareJson(linkedIssues, "linked-issues.json"));
}
@Test @Test
public void testCommitDiscussions() throws Exception { public void testCommitDiscussions() throws Exception {
List<Discussion> discussions = unmarshalResourceList(Discussion.class, "commit-discussions.json"); List<Discussion> discussions = unmarshalResourceList(Discussion.class, "commit-discussions.json");
......
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