Skip to content

Commit

Permalink
Merge pull request #81 from choweiyuan/list-jenkins-jobs
Browse files Browse the repository at this point in the history
API to get list of Jenkins Jobs
  • Loading branch information
cdancy authored Jan 27, 2020
2 parents 61da547 + 7fdad6c commit fc02d29
Show file tree
Hide file tree
Showing 8 changed files with 220 additions and 22 deletions.
24 changes: 24 additions & 0 deletions src/main/java/com/cdancy/jenkins/rest/domain/job/Job.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.cdancy.jenkins.rest.domain.job;

import com.google.auto.value.AutoValue;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.json.SerializedNames;

@AutoValue
public abstract class Job {

@Nullable
public abstract String clazz();

public abstract String name();

public abstract String url();

Job() {
}

@SerializedNames({"_class", "name", "url"})
public static Job create(final String clazz, final String name, final String url) {
return new AutoValue_Job(clazz, name, url);
}
}
44 changes: 44 additions & 0 deletions src/main/java/com/cdancy/jenkins/rest/domain/job/JobList.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.cdancy.jenkins.rest.domain.job;

import com.google.auto.value.AutoValue;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.json.SerializedNames;

import java.util.List;

@AutoValue
public abstract class JobList {

@Nullable
public abstract String clazz();

public abstract List<Job> jobs();

@Nullable
public abstract String url();

JobList() {
}

@SerializedNames({"_class", "jobs", "url"})
public static JobList create(final String clazz, final List<Job> jobs, final String url) {
return new AutoValue_JobList(clazz, jobs, url);
}
}
14 changes: 8 additions & 6 deletions src/main/java/com/cdancy/jenkins/rest/features/JobsApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import javax.ws.rs.core.MediaType;

import com.cdancy.jenkins.rest.domain.job.*;
import com.google.gson.JsonObject;
import com.cdancy.jenkins.rest.parsers.*;
import org.jclouds.Fallbacks;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.rest.annotations.BinderParam;
Expand All @@ -48,16 +48,18 @@
import com.cdancy.jenkins.rest.domain.common.RequestStatus;
import com.cdancy.jenkins.rest.fallbacks.JenkinsFallbacks;
import com.cdancy.jenkins.rest.filters.JenkinsAuthenticationFilter;
import com.cdancy.jenkins.rest.parsers.BuildNumberToInteger;
import com.cdancy.jenkins.rest.parsers.LocationToQueueId;
import com.cdancy.jenkins.rest.parsers.OutputToProgressiveText;
import com.cdancy.jenkins.rest.parsers.RequestStatusParser;
import com.cdancy.jenkins.rest.parsers.OptionalFolderPathParser;

@RequestFilters(JenkinsAuthenticationFilter.class)
@Path("/")
public interface JobsApi {

@Named("jobs:get-jobs")
@Path("{folderPath}api/json")
@Fallback(Fallbacks.NullOnNotFoundOr404.class)
@Consumes(MediaType.APPLICATION_JSON)
@GET
JobList jobList(@PathParam("folderPath") @ParamParser(FolderPathParser.class) String folderPath);

@Named("jobs:job-info")
@Path("{optionalFolderPath}job/{name}/api/json")
@Fallback(Fallbacks.NullOnNotFoundOr404.class)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.cdancy.jenkins.rest.parsers;

import com.google.common.base.Function;

import javax.inject.Singleton;

/*
* Turn the optionalFolderPath param to jenkins URL style
*/
@Singleton
public class FolderPathParser implements Function<Object,String> {

public static final String EMPTY_STRING = "";
public static final String FOLDER_NAME_PREFIX = "job/";
public static final Character FOLDER_NAME_SEPARATOR = '/';

@Override
public String apply(Object folderPath) {
final StringBuilder path = new StringBuilder((String) folderPath);
if (path.length() == 0) {
return EMPTY_STRING;
}

if(path.charAt(0) == FOLDER_NAME_SEPARATOR){
path.deleteCharAt(0);
}
if(path.charAt(path.length() - 1) == FOLDER_NAME_SEPARATOR) {
path.deleteCharAt(path.length() - 1);
}
final String[] folders = path.toString().split(Character.toString(FOLDER_NAME_SEPARATOR));
path.setLength(0);
for(final String folder : folders) {
path.append(FOLDER_NAME_PREFIX).append(folder).append(FOLDER_NAME_SEPARATOR);
}
return path.toString();
}
}
30 changes: 20 additions & 10 deletions src/test/java/com/cdancy/jenkins/rest/features/JobsApiLiveTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,11 @@
*/
package com.cdancy.jenkins.rest.features;

import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;

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

import com.cdancy.jenkins.rest.domain.job.Cause;
import com.cdancy.jenkins.rest.domain.job.Parameter;
import com.cdancy.jenkins.rest.domain.job.*;
import com.cdancy.jenkins.rest.domain.plugins.Plugin;
import com.cdancy.jenkins.rest.domain.plugins.Plugins;
import com.cdancy.jenkins.rest.domain.queue.QueueItem;
Expand All @@ -35,12 +29,11 @@
import com.cdancy.jenkins.rest.BaseJenkinsApiLiveTest;
import com.cdancy.jenkins.rest.domain.common.IntegerResponse;
import com.cdancy.jenkins.rest.domain.common.RequestStatus;
import com.cdancy.jenkins.rest.domain.job.BuildInfo;
import com.cdancy.jenkins.rest.domain.job.JobInfo;
import com.cdancy.jenkins.rest.domain.job.ProgressiveText;

import com.google.common.collect.Lists;

import static org.testng.Assert.*;

@Test(groups = "live", testName = "JobsApiLiveTest", singleThreaded = true)
public class JobsApiLiveTest extends BaseJenkinsApiLiveTest {

Expand All @@ -57,6 +50,14 @@ public void testCreateJob() {
assertTrue(success.value());
}

@Test(dependsOnMethods = "testCreateJob")
public void testGetJobListFromRoot() {
JobList output = api().jobList("");
assertNotNull(output);
assertFalse(output.jobs().isEmpty());
assertEquals(output.jobs().size(), 2);
}

@Test(dependsOnMethods = "testCreateJob")
public void testGetJobInfo() {
JobInfo output = api().jobInfo(null, "DevTest");
Expand Down Expand Up @@ -274,6 +275,15 @@ public void testCreateJobWithIncorrectFolderPath() {
assertFalse(success.value());
}

@Test(dependsOnMethods = "testCreateJobInFolder")
public void testGetJobListInFolder() {
JobList output = api().jobList("test-folder/test-folder-1");
assertNotNull(output);
assertFalse(output.jobs().isEmpty());
assertEquals(output.jobs().size(), 1);
assertEquals(output.jobs().get(0), Job.create("hudson.model.FreeStyleProject", "JobInFolder", "http://127.0.0.1:8080/job/test-folder/job/test-folder-1/job/JobInFolder/"));
}

@Test(dependsOnMethods = "testCreateJobInFolder")
public void testUpdateJobConfigInFolder() {
String config = payloadFromResource("/freestyle-project.xml");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,6 @@
*/
package com.cdancy.jenkins.rest.features;

import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand All @@ -41,12 +35,53 @@
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.MockWebServer;

import static org.testng.Assert.*;

/**
* Mock tests for the {@link com.cdancy.jenkins.rest.features.JobsApi} class.
*/
@Test(groups = "unit", testName = "JobsApiMockTest")
public class JobsApiMockTest extends BaseJenkinsMockTest {

public void testGetInnerFolderJobList() throws Exception {
MockWebServer server = mockWebServer();

String body = payloadFromResource("/jobsInJenkinsFolder.json");
server.enqueue(new MockResponse().setBody(body).setResponseCode(200));
JenkinsApi jenkinsApi = api(server.url("/").url());
JobsApi api = jenkinsApi.jobsApi();
try {
JobList output = api.jobList("Folder1/Folder 2");
assertNotNull(output);
assertNotNull(output.jobs());
assertEquals(output.jobs().size(), 1);
assertEquals(output.jobs().get(0), Job.create("hudson.model.FreeStyleProject", "Test Project", "http://localhost:8080/job/username"));
assertSent(server, "GET", "/job/Folder1/job/Folder%202/api/json");
} finally {
jenkinsApi.close();
server.shutdown();
}
}

public void testGetRootFolderJobList() throws Exception {
MockWebServer server = mockWebServer();

String body = payloadFromResource("/jobsInRootFolder.json");
server.enqueue(new MockResponse().setBody(body).setResponseCode(200));
JenkinsApi jenkinsApi = api(server.url("/").url());
JobsApi api = jenkinsApi.jobsApi();
try {
JobList output = api.jobList("");
assertNotNull(output);
assertNotNull(output.jobs());
assertEquals(output.jobs().size(), 6);
assertSent(server, "GET", "/api/json");
} finally {
jenkinsApi.close();
server.shutdown();
}
}

public void testGetJobInfo() throws Exception {
MockWebServer server = mockWebServer();

Expand Down
10 changes: 10 additions & 0 deletions src/test/resources/jobsInJenkinsFolder.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"_class" : "com.cloudbees.hudson.plugins.folder.Folder",
"jobs" : [
{
"_class" : "hudson.model.FreeStyleProject",
"name" : "Test Project",
"url": "http://localhost:8080/job/username"
}
]
}
36 changes: 36 additions & 0 deletions src/test/resources/jobsInRootFolder.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"_class" : "hudson.model.Hudson",
"jobs" : [
{
"_class" : "hudson.maven.MavenModuleSet",
"name" : "Test Tool",
"url": "http://localhost:32769/job/fish-test/"
},
{
"_class" : "org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject",
"name" : "Test MultiBranch Project",
"url": "http://localhost:32769/job/fish-multibranch/"
},
{
"_class" : "com.cloudbees.hudson.plugins.folder.Folder",
"name" : "Test Folder",
"url": "http://localhost:32769/job/fish-folder/"
},
{
"_class" : "com.cloudbees.tiger.plugins.palace.templates.DockerSlaveTemplate",
"name" : "Test Docker Slave",
"url":"http://localhost:32769/job/fish-agent/"
},
{
"_class" : "hudson.model.FreeStyleProject",
"name" : "Test Free Style",
"url": "http://localhost:32769/job/fish-project/",
"color": "red"
},
{
"_class" : "org.jenkinsci.plugins.workflow.job.WorkflowJob",
"name" : "Test Workflow Job",
"url": "http://localhost:32769/job/fish-workflow/"
}
]
}

0 comments on commit fc02d29

Please sign in to comment.