diff --git a/src/main/java/org/gitlab4j/api/PipelineApi.java b/src/main/java/org/gitlab4j/api/PipelineApi.java index 491c00cc8..6210da85e 100644 --- a/src/main/java/org/gitlab4j/api/PipelineApi.java +++ b/src/main/java/org/gitlab4j/api/PipelineApi.java @@ -1,12 +1,14 @@ package org.gitlab4j.api; import java.util.List; +import java.util.Optional; import java.util.stream.Stream; import javax.ws.rs.core.GenericType; import javax.ws.rs.core.Response; import org.gitlab4j.api.models.Pipeline; +import org.gitlab4j.api.models.PipelineSchedule; import org.gitlab4j.api.models.PipelineStatus; /** @@ -271,4 +273,167 @@ public Pipeline cancelPipelineJobs(Object projectIdOrPath, int pipelineId) throw Response response = post(Response.Status.OK, formData, "projects", getProjectIdOrPath(projectIdOrPath), "pipelines", pipelineId, "cancel"); return (response.readEntity(Pipeline.class)); } + + /** + * Get a list of the project pipeline_schedules for the specified project. + * + *
GET /projects/:id/pipeline_schedules
+ * + * @param projectIdOrPath projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance, required + * @return a list of pipeline schedules for the specified project + * @throws GitLabApiException if any exception occurs + */ + public List getPipelineSchedules(Object projectIdOrPath) throws GitLabApiException { + return (getPipelineSchedules(projectIdOrPath, getDefaultPerPage()).all()); + } + /** + * Get list of project pipeline schedules in the specified page range. + * + *
GET /projects/:id/pipeline_schedules
+ * + * @param projectIdOrPath projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance, required + * @param page the page to get + * @param perPage the number of ProjectHook instances per page + * @return a list of project pipeline_schedules for the specified project in the specified page range + * @throws GitLabApiException if any exception occurs + */ + public List getPipelineSchedules(Object projectIdOrPath, int page, int perPage) throws GitLabApiException { + Response response = get(Response.Status.OK, getPageQueryParams(page, perPage), "projects", getProjectIdOrPath(projectIdOrPath), "pipeline_schedules"); + return (response.readEntity(new GenericType>() {})); + } + /** + * Get Pager of project pipeline schedule. + * + *
GET /projects/:id/pipeline_schedule
+ * + * @param projectIdOrPath projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance, required + * @param itemsPerPage the number of Project instances that will be fetched per page + * @return a Pager of project pipeline_schedules for the specified project + * @throws GitLabApiException if any exception occurs + */ + public Pager getPipelineSchedules(Object projectIdOrPath, int itemsPerPage) throws GitLabApiException { + return (new Pager(this, PipelineSchedule.class, itemsPerPage, null, "projects", getProjectIdOrPath(projectIdOrPath), "pipeline_schedules")); + } + + /** + * Get a Stream of the project pipeline schedule for the specified project. + * + *
GET /projects/:id/pipeline_schedule
+ * + * @param projectIdOrPath projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance, required + * @return a Stream of project pipeline schedules for the specified project + * @throws GitLabApiException if any exception occurs + */ + public Stream getPipelineSchedulesStream(Object projectIdOrPath) throws GitLabApiException { + return (getPipelineSchedules(projectIdOrPath, getDefaultPerPage()).stream()); + } + + + /** + * Get a specific pipeline schedule for project. + * + *
GET /projects/:id/pipeline_schedules/:pipeline_schedule_id
+ * + * @param projectIdOrPath projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance, required + * @param pipelineScheduleId the ID of the hook to get + * @return the project hook for the specified project ID/hook ID pair + * @throws GitLabApiException if any exception occurs + */ + public PipelineSchedule getPipelineSchedule(Object projectIdOrPath, Integer pipelineScheduleId) throws GitLabApiException { + Response response = get(Response.Status.OK, null, "projects", getProjectIdOrPath(projectIdOrPath), "pipeline_schedules", pipelineScheduleId); + return (response.readEntity(PipelineSchedule.class)); + } + + /** + * Get a specific pipeline schedule for project as an Optional instance. + * + *
GET /projects/:id/pipeline_schedules/:pipeline_schedule_id
+ * + * @param projectIdOrPath projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance, required + * @param pipelineScheduleId the ID of the hook to get + * @return the project hook for the specified project ID/hook ID pair as an Optional instance + */ + public Optional getOptionalPipelineSchedule (Object projectIdOrPath, Integer pipelineScheduleId) { + try { + return (Optional.ofNullable(getPipelineSchedule(projectIdOrPath, pipelineScheduleId))); + } catch (GitLabApiException glae) { + return (GitLabApi.createOptionalFromException(glae)); + } + } + + /** + * create a pipeline schedule for a project. + * + *
POST /projects/:id/pipeline_schedules
+ * + * @param projectIdOrPath projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance, required + * @param pipelineSchedule a PipelineSchedule instance to create + * @return the added PipelineSchedule instance + * @throws GitLabApiException if any exception occurs + */ + public PipelineSchedule createPipelineSchedule(Object projectIdOrPath, PipelineSchedule pipelineSchedule) + throws GitLabApiException { + + GitLabApiForm formData = new GitLabApiForm() + .withParam("description", pipelineSchedule.getDescription(), true) + .withParam("ref", pipelineSchedule.getRef(), true) + .withParam("cron", pipelineSchedule.getCron(), true) + .withParam("cron_timezone", pipelineSchedule.getCronTimezone(), false) + .withParam("active", pipelineSchedule.getActive(), false); + Response response = post(Response.Status.CREATED, formData, "projects", getProjectIdOrPath(projectIdOrPath), "pipeline_schedules"); + return (response.readEntity(PipelineSchedule.class)); + } + + /** + * Deletes a pipeline schedule from the project. + * + *
DELETE /projects/:id/pipeline_schedules/:pipeline_schedule_id
+ * + * @param projectIdOrPath projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance, required + * @param pipelineScheduleId the project schedule ID to delete + * @throws GitLabApiException if any exception occurs + */ + public void deletePipelineSchedule(Object projectIdOrPath, Integer pipelineScheduleId) throws GitLabApiException { + Response.Status expectedStatus = (isApiVersion(GitLabApi.ApiVersion.V3) ? Response.Status.OK : Response.Status.NO_CONTENT); + delete(expectedStatus, null, "projects", getProjectIdOrPath(projectIdOrPath), "pipeline_schedules", pipelineScheduleId); + } + + /** + * Modifies a pipeline schedule for project. + * + *
PUT /projects/:id/pipeline_schedules/:pipeline_schedule_id
+ * + * @param projectIdOrPath projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance, required + * @param pipelineSchedule the pipelineSchedule instance that contains the pipelineSchedule info to modify + * @return the modified project schedule + * @throws GitLabApiException if any exception occurs + */ + public PipelineSchedule modifyPipelineSchedule(Object projectIdOrPath,PipelineSchedule pipelineSchedule) throws GitLabApiException { + + GitLabApiForm formData = new GitLabApiForm() + .withParam("description", pipelineSchedule.getDescription(), false) + .withParam("ref", pipelineSchedule.getRef(), false) + .withParam("cron", pipelineSchedule.getCron(), false) + .withParam("cron_timezone", pipelineSchedule.getCronTimezone(), false) + .withParam("active", pipelineSchedule.getActive(), false); + + Response response = put(Response.Status.OK, formData.asMap(), "projects", getProjectIdOrPath(projectIdOrPath), "pipeline_schedules", pipelineSchedule.getId()); + return (response.readEntity(PipelineSchedule.class)); + } + + /** + * Update the owner of the pipeline schedule of a project. + * + *
POST /projects/:id/pipeline_schedules/:pipeline_schedule_id/take_ownership
+ * + * @param projectIdOrPath projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance, required + * @param pipelineScheduleId the pipelineSchedule instance id that ownership has to be taken of + * @return the modified project schedule + * @throws GitLabApiException if any exception occurs + */ + public PipelineSchedule takeOwnershipPipelineSchedule(Object projectIdOrPath, Integer pipelineScheduleId) throws GitLabApiException { + + Response response = post(Response.Status.OK, "", "projects", getProjectIdOrPath(projectIdOrPath), "pipeline_schedules", pipelineScheduleId, "take_ownership"); + return (response.readEntity(PipelineSchedule.class)); + } } diff --git a/src/main/java/org/gitlab4j/api/models/PipelineSchedule.java b/src/main/java/org/gitlab4j/api/models/PipelineSchedule.java new file mode 100644 index 000000000..354576e1f --- /dev/null +++ b/src/main/java/org/gitlab4j/api/models/PipelineSchedule.java @@ -0,0 +1,119 @@ +package org.gitlab4j.api.models; + +import org.gitlab4j.api.utils.JacksonJson; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.Date; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class PipelineSchedule { + + private Integer id; + private String description; + private String ref; + private String cron; + private String cronTimezone; + private Date nextRunAt; + private Date createdAt; + private Date updatedAt; + private Boolean active; + private Pipeline lastPipeline; + private Owner owner; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getRef() { + return ref; + } + + public void setRef(String ref) { + this.ref = ref; + } + + public String getCron() { + return cron; + } + + public void setCron(String cron) { + this.cron = cron; + } + + public String getCronTimezone() { + return cronTimezone; + } + + public void setCronTimezone(String cronTimezone) { + this.cronTimezone = cronTimezone; + } + + public Date getNextRunAt() { + return nextRunAt; + } + + public void setNextRunAt(Date nextRunAt) { + this.nextRunAt = nextRunAt; + } + + public Date getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + + public Date getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Date updatedAt) { + this.updatedAt = updatedAt; + } + + public Boolean getActive() { + return active; + } + + public void setActive(Boolean active) { + this.active = active; + } + + public Pipeline getLastPipeline() { + return lastPipeline; + } + + public void setLastPipeline(Pipeline lastPipeline) { + this.lastPipeline = lastPipeline; + } + + public Owner getOwner() { + return owner; + } + + public void setOwner(Owner owner) { + this.owner = owner; + } + + @Override + public String toString() { + return (JacksonJson.toJsonString(this)); + } +} + diff --git a/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java b/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java index c4aadb161..579c396db 100644 --- a/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java +++ b/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java @@ -61,6 +61,7 @@ import org.gitlab4j.api.models.NotificationSettings; import org.gitlab4j.api.models.OauthTokenResponse; import org.gitlab4j.api.models.Pipeline; +import org.gitlab4j.api.models.PipelineSchedule; import org.gitlab4j.api.models.Project; import org.gitlab4j.api.models.ProjectHook; import org.gitlab4j.api.models.ProjectUser; @@ -215,6 +216,12 @@ public void testPipeline() throws Exception { assertTrue(compareJson(pipeline, "pipeline.json")); } + @Test + public void testPipelineSchedule() throws Exception { + PipelineSchedule pipelineSchedule = unmarshalResource(PipelineSchedule.class, "pipeline-schedule.json"); + assertTrue(compareJson(pipelineSchedule, "pipeline-schedule.json")); + } + @Test public void testJob() throws Exception { Job job = unmarshalResource(Job.class, "job.json"); diff --git a/src/test/java/org/gitlab4j/api/TestPipelineApi.java b/src/test/java/org/gitlab4j/api/TestPipelineApi.java new file mode 100644 index 000000000..2fed29943 --- /dev/null +++ b/src/test/java/org/gitlab4j/api/TestPipelineApi.java @@ -0,0 +1,117 @@ +package org.gitlab4j.api; + +import org.gitlab4j.api.models.PipelineSchedule; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import java.util.List; + +import static org.junit.Assert.*; +import static org.junit.Assume.assumeTrue; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestPipelineApi { + // The following needs to be set to your test repository + private static final String TEST_NAMESPACE; + private static final String TEST_PROJECT_NAME; + private static final String TEST_HOST_URL; + private static final String TEST_PRIVATE_TOKEN; + + static { + TEST_NAMESPACE = TestUtils.getProperty("TEST_NAMESPACE"); + TEST_PROJECT_NAME = TestUtils.getProperty("TEST_PROJECT_NAME"); + TEST_HOST_URL = TestUtils.getProperty("TEST_HOST_URL"); + TEST_PRIVATE_TOKEN = TestUtils.getProperty("TEST_PRIVATE_TOKEN"); + } + + + private static GitLabApi gitLabApi; + + public TestPipelineApi() { + super(); + } + + @BeforeClass + public static void setup() { + + String problems = ""; + if (TEST_NAMESPACE == null || TEST_NAMESPACE.trim().isEmpty()) { + problems += "TEST_NAMESPACE cannot be empty\n"; + } + + if (TEST_HOST_URL == null || TEST_HOST_URL.trim().isEmpty()) { + problems += "TEST_HOST_URL cannot be empty\n"; + } + + if (TEST_PRIVATE_TOKEN == null || TEST_PRIVATE_TOKEN.trim().isEmpty()) { + problems += "TEST_PRIVATE_TOKEN cannot be empty\n"; + } + if (problems.isEmpty()) { + gitLabApi = new GitLabApi(GitLabApi.ApiVersion.V4, TEST_HOST_URL, TEST_PRIVATE_TOKEN); + } else { + System.err.print(problems); + } + } + + @AfterClass + public static void teardown() { + } + + + @Before + public void beforeMethod() { + assumeTrue(gitLabApi != null); + } + + @Test + public void testCreateProjectPipeLineSchedule() throws GitLabApiException { + assumeTrue(TEST_NAMESPACE != null && TEST_PROJECT_NAME != null); + assumeTrue(TEST_NAMESPACE.trim().length() > 0 && TEST_PROJECT_NAME.trim().length() > 0); + + Integer testProjectId = gitLabApi.getProjectApi().getProject(TEST_NAMESPACE, TEST_PROJECT_NAME).getId(); + PipelineSchedule newPipelineSchedule = new PipelineSchedule(); + newPipelineSchedule.setDescription("test pipeline schedule"); + newPipelineSchedule.setCron("0 4 * * *"); + newPipelineSchedule.setRef("master"); + PipelineSchedule createdPipelineSchedule = gitLabApi.getPipelineApi().createPipelineSchedule(testProjectId,newPipelineSchedule); + assertNotNull(createdPipelineSchedule); + List pipelineSchedules = gitLabApi.getPipelineApi().getPipelineSchedules(testProjectId); + assertFalse(pipelineSchedules.isEmpty()); + } + + @Test + public void testModifyProjectPipeLineSchedule() throws GitLabApiException { + assumeTrue(TEST_NAMESPACE != null && TEST_PROJECT_NAME != null); + assumeTrue(TEST_NAMESPACE.trim().length() > 0 && TEST_PROJECT_NAME.trim().length() > 0); + + Integer testProjectId = gitLabApi.getProjectApi().getProject(TEST_NAMESPACE, TEST_PROJECT_NAME).getId(); + List pipelineSchedules = gitLabApi.getPipelineApi().getPipelineSchedules(testProjectId); + assertTrue(pipelineSchedules.size()==1); + PipelineSchedule existingPipelineSchedule = pipelineSchedules.get(0); + assertTrue(existingPipelineSchedule.getDescription().equals("test pipeline schedule")); + existingPipelineSchedule.setDescription("new name"); + gitLabApi.getPipelineApi().modifyPipelineSchedule(testProjectId,existingPipelineSchedule); + pipelineSchedules = gitLabApi.getPipelineApi().getPipelineSchedules(testProjectId); + PipelineSchedule newPipelineSchedule = pipelineSchedules.get(0); + assertTrue(pipelineSchedules.size()==1); + assertTrue(newPipelineSchedule.equals("new name")); + } + + + @Test + public void testDeleteProjectPipeLineSchedule() throws GitLabApiException { + assumeTrue(TEST_NAMESPACE != null && TEST_PROJECT_NAME != null); + assumeTrue(TEST_NAMESPACE.trim().length() > 0 && TEST_PROJECT_NAME.trim().length() > 0); + + Integer testProjectId = gitLabApi.getProjectApi().getProject(TEST_NAMESPACE, TEST_PROJECT_NAME).getId(); + List pipelineSchedules = gitLabApi.getPipelineApi().getPipelineSchedules(testProjectId); + assertFalse(pipelineSchedules.isEmpty()); + gitLabApi.getPipelineApi().deletePipelineSchedule(testProjectId,pipelineSchedules.get(0).getId()); + pipelineSchedules = gitLabApi.getPipelineApi().getPipelineSchedules(testProjectId); + assertTrue(pipelineSchedules.isEmpty()); + } +} diff --git a/src/test/resources/org/gitlab4j/api/pipeline-schedule.json b/src/test/resources/org/gitlab4j/api/pipeline-schedule.json new file mode 100644 index 000000000..cbe18b05b --- /dev/null +++ b/src/test/resources/org/gitlab4j/api/pipeline-schedule.json @@ -0,0 +1,21 @@ +{ + "id": 13, + "description": "Test schedule pipeline", + "ref": "master", + "cron": "* * * * *", + "cron_timezone": "Asia/Tokyo", + "next_run_at": "2017-05-19T13:41:00.121Z", + "active": true, + "created_at": "2017-05-19T13:31:08.849Z", + "updated_at": "2017-05-19T13:40:17.727Z", + "last_pipeline": { + "id": 332, + "sha": "0e788619d0b5ec17388dffb973ecd505946156db", + "ref": "master", + "status": "pending" + }, + "owner": { + "name": "Administrator", + "id": 1 + } +} \ No newline at end of file