利用 Java 操作 Jenkins API 实现对 Jenkins 的控制详解


  !版权声明:本博客内容均均为原创,每篇博文作为知识积累,写博不易,转载请注明出处。

目录[-]


由于最近工作需要利用 Jenkins 远程 API 操作 Jenkins 来完成一些列操作,就抽空研究了下如何利用 JAVA 操作 Jenkins API,实现对 Jenkins Job、View等等的增、删、改、查操作。

系统环境:

  • Java 版本:1.8
  • Jenkins 版本:2.172

参靠及项目地址:

如果示例对你就帮助就 github 帮忙点个星哈~

一、 Jenkins API

1、Jenkins API 简介

Jenkins 远程 API 能够通过 Http 协议远程调用相关命令操作 Jenkins 进行 Jenkins 视图、任务、插件、构建信息、任务日志信息、统计信息等,非常容易与其配合更好的完成 CI/CD 工作。

2、Jenkins API 格式

Jenkins API 总共有三种格式,分别为:

  • JSON API
  • XML API
  • Python API

3、Jenkins 查看 API 信息

可以用浏览器打开你的 Jenkins UI 界面,然后 URL 地址栏后面追加 “/api/json” 或者 “/api/xml” ,效果如下:

  • “JenkinsURL/api/json” 显示:
<hudson _class='hudson.model.Hudson'>
    <assignedLabel>
        <name>master</name>
    </assignedLabel>
    <mode>NORMAL</mode>
    <nodeDescription>Jenkins的master节点</nodeDescription>
    <nodeName></nodeName>
    <numExecutors>1</numExecutors>
    <job _class='org.jenkinsci.plugins.workflow.job.WorkflowJob'>
        <name>deploy-test2</name>
        <url>http://127.0.0.1:8080/jenkins/job/deploy-test2/</url>
        <color>red</color>
    </job>
    <job _class='org.jenkinsci.plugins.workflow.job.WorkflowJob'>
        <name>test-job</name>
        <url>http://127.0.0.1:8080/jenkins/job/test-job/</url>
        <color>blue</color>
    </job>
    <quietingDown>false</quietingDown>
    <slaveAgentPort>50000</slaveAgentPort>
    <unlabeledLoad _class='jenkins.model.UnlabeledLoadStatistics'></unlabeledLoad>
    <useCrumbs>false</useCrumbs>
    <useSecurity>true</useSecurity>
    <view _class='hudson.model.AllView'>
        <name>all</name>
        <url>http://127.0.0.1:8080/jenkins/</url>
    </view>
</hudson>
  • “JenkinsURL/api/xml” 显示:
{
    "_class": "hudson.model.Hudson",
    "assignedLabels": [
        {
            "name": "master"
        }
    ],
    "mode": "NORMAL",
    "nodeDescription": "Jenkins的master节点",
    "nodeName": "",
    "numExecutors": 1,
    "description": null,
    "jobs": [
        {
            "_class": "org.jenkinsci.plugins.workflow.job.WorkflowJob",
            "name": "deploy-test2",
            "url": "http://127.0.0.1:8080/jenkins/job/deploy-test2/",
            "color": "red"
        },
        {
            "_class": "org.jenkinsci.plugins.workflow.job.WorkflowJob",
            "name": "test-job",
            "url": "http://127.0.0.1:8080/jenkins/job/test-job/",
            "color": "blue"
        }
    ],
    "overallLoad": {},
    "primaryView": {
        "_class": "hudson.model.AllView",
        "name": "all",
        "url": "http://127.0.0.1:8080/jenkins/"
    },
    "quietingDown": false,
    "slaveAgentPort": 50000,
    "unlabeledLoad": {
        "_class": "jenkins.model.UnlabeledLoadStatistics"
    },
    "useCrumbs": false,
    "useSecurity": true,
    "views": [
        {
            "_class": "hudson.model.AllView",
            "name": "all",
            "url": "http://192.168.2.11:8080/jenkins/"
        }
    ]
}

还可以访问 View、Job等 API 信息,例如:

  • View API: /view/<view-name>/api/json
  • Job API: /job/<job-name>/api/xml
  • build API: /job/<job-name>/<build-number>/

二、调用接口前对 Jenkins 参数调整

1、关闭 CSRF

由于在调用 Jenkins 中,操作执行 Job 一些命令时会用到 Post 方式命令,所以需要关闭 Jenkins 的 CSRF 选项。

关闭 系统管理->全局安全配置->跨站请求伪造保护 选项

2、系统设置中和 jenkins 地址一致

设置 系统管理->系统设置->Jenkins Location 的 URL 和 Jenkins 访问地址保持一致

三、使用 Java 调用 Jenkins API 示例

下面将演示如何通过 Java 调用 Jenkins API 来对 Jenkins 进行操作,在注释中有详细描述,就不在外面一步步说明了。

本示例项目 Github 地址:https://github.com/my-dlq/blog-example/tree/master/jenkins-api-demo

1、Maven 引入工具

在 Jenkins Github 中查找到已经有人做了封装调用 Jenkins API 的工具 Jar,这里只需要我们 Maven 中引入这个工具 java-client-api,就可以方便的调用 Jenkins API 了。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>club.mydlq</groupId>
    <artifactId>jenkins-api-demo</artifactId>
    <version>0.0.1</version>
    <name>jenkins-api-demo</name>
    <description>jenkins api demo</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--jenkins-java-client-->
        <dependency>
            <groupId>com.offbytwo.jenkins</groupId>
            <artifactId>jenkins-client</artifactId>
            <version>0.3.8</version>
        </dependency>
    </dependencies>

</project>

2、连接 Jenkins 工具类

此类主要用于连接 Jenkins

JenkinsConnect.java

import com.offbytwo.jenkins.JenkinsServer;
import com.offbytwo.jenkins.client.JenkinsHttpClient;
import java.net.URI;
import java.net.URISyntaxException;

/**
 * 连接 Jenkins
 */
public class JenkinsConnect {

    private JenkinsConnect(){}

    // 连接 Jenkins 需要设置的信息
    static final String JENKINS_URL = "http://192.168.2.11:8080/jenkins/";
    static final String JENKINS_USERNAME = "admin";
    static final String JENKINS_PASSWORD = "123456";

    /**
     * Http 客户端工具
     *
     * 如果有些 API 该Jar工具包未提供,可以用此Http客户端操作远程接口,执行命令
     * @return
     */
    public static JenkinsHttpClient getClient(){
        JenkinsHttpClient jenkinsHttpClient = null;
        try {
            jenkinsHttpClient = new JenkinsHttpClient(new URI(JENKINS_URL), JENKINS_USERNAME, JENKINS_PASSWORD);
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        return jenkinsHttpClient;
    }

    /**
     * 连接 Jenkins
     */
    public static JenkinsServer connection() {
        JenkinsServer jenkinsServer = null;
        try {
            jenkinsServer = new JenkinsServer(new URI(JENKINS_URL), JENKINS_USERNAME, JENKINS_PASSWORD);
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        return jenkinsServer;
    }
}

3、操作视图

此类主要用于操作 Jenkins 中的 View

ViewApi.java

import com.offbytwo.jenkins.JenkinsServer;
import com.offbytwo.jenkins.client.JenkinsHttpClient;
import com.offbytwo.jenkins.model.View;
import java.io.IOException;

/**
 * View(视图) 相关操作
 *
 * 例如对视图的增、删、改、查等操作
 */
public class ViewApi {

    // Jenkins 对象
    private JenkinsServer jenkinsServer;
    // http 客户端对象
    private JenkinsHttpClient jenkinsHttpClient;

    /**
     * 构造方法中调用连接 Jenkins 方法
     */
    ViewApi() {
        JenkinsApi jenkinsApi = new JenkinsApi();
        // 连接 Jenkins
        jenkinsServer = JenkinsConnect.connection();
        // 设置客户端连接 Jenkins
        jenkinsHttpClient = JenkinsConnect.getClient();
    }

    /**
     * 创建视图
     */
    public void createView() {
        try {
            // 创建一个 xml 字符串,里面设置一个 view 描述信息
            String xml = "<listView _class=\"hudson.model.ListView\">\n" +
                    "<description>用于测试的视图</description>\n" +
                    "</listView>";
            // 创建 view
            jenkinsServer.createView("test-view", xml);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取视图基本信息
     */
    public void getView() {
        try {
            // 视图名
            String viewName = "test-view";
            // 获取视图基本信息
            View view = jenkinsServer.getView(viewName);
            System.out.println(view.getName());
            System.out.println(view.getUrl());
            System.out.println(view.getDescription());
            // 获取视图xml信息
            String viewXml = jenkinsHttpClient.get("/view/" + viewName + "/api/xml");
            System.out.println(viewXml);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取视图配置 XML 信息
     */
    public void getViewConfig() {
        try {
            // 视图名
            String viewName = "test-view";
            // 获取视图配置xml信息
            String viewConfigXml = jenkinsHttpClient.get("/view/" + viewName + "/config.xml");
            System.out.println(viewConfigXml);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 更新视图信息
     */
    public void updateView() {
        try {
            // 创建一个 xml 字符串,里面设置一个要修改的某些字段,具体xml可以到jenkins查看
            // 例如,下面xml文件是从地址:https://Jenkins-IP/jenkins/view/test-view/config.xml 获取的
            String xml = "<hudson.model.ListView>\n" +
                    "<name>test-view</name>\n" +
                    "<description>用于测试的视图1111</description>\n" +
                    "<filterExecutors>false</filterExecutors>\n" +
                    "<filterQueue>false</filterQueue>\n" +
                    "<properties class=\"hudson.model.View$PropertyList\"/>\n" +
                    "<jobNames>\n" +
                    "<comparator class=\"hudson.util.CaseInsensitiveComparator\"/>\n" +
                    "</jobNames>\n" +
                    "<jobFilters/>\n" +
                    "<columns>\n" +
                    "<hudson.views.StatusColumn/>\n" +
                    "<hudson.views.WeatherColumn/>\n" +
                    "<hudson.views.JobColumn/>\n" +
                    "<hudson.views.LastSuccessColumn/>\n" +
                    "<hudson.views.LastFailureColumn/>\n" +
                    "<hudson.views.LastDurationColumn/>\n" +
                    "<hudson.views.BuildButtonColumn/>\n" +
                    "<hudson.plugins.favorite.column.FavoriteColumn plugin=\"favorite@2.3.2\"/>\n" +
                    "</columns>\n" +
                    "<recurse>false</recurse>\n" +
                    "</hudson.model.ListView>";
            jenkinsServer.updateView("test-view", xml);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除视图
     */
    public void deleteView() {
        try {
            String viewName = "test-view";
            jenkinsHttpClient.post("/view/" + viewName + "/doDelete");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        ViewApi viewApi = new ViewApi();
        // 创建视图
        //viewApi.createView();
        // 获取视图信息
        //viewApi.getView();
        // 获取视图配置xml信息
        //viewApi.getViewConfig();
        // 更新视图信息
        //viewApi.updateView();
        // 删除视图
        //viewApi.deleteView();
    }
}

4、操作任务

此类主要用于操作 Jenkins 中的 Job

JobApi.java

import com.offbytwo.jenkins.JenkinsServer;
import com.offbytwo.jenkins.client.JenkinsHttpClient;
import com.offbytwo.jenkins.model.Build;
import com.offbytwo.jenkins.model.Job;
import com.offbytwo.jenkins.model.JobWithDetails;
import com.offbytwo.jenkins.model.MavenJobWithDetails;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * Job(任务) 相关操作
 *
 * 例如对任务的增、删、改、查等操作
 */
public class JobApi {

    // Jenkins 对象
    private JenkinsServer jenkinsServer;
    // http 客户端对象
    private JenkinsHttpClient jenkinsHttpClient;

    /**
     * 构造方法中调用连接 Jenkins 方法
     */
    JobApi() {
        JenkinsApi jenkinsApi = new JenkinsApi();
        // 连接 Jenkins
        jenkinsServer = JenkinsConnect.connection();
        // 设置客户端连接 Jenkins
        jenkinsHttpClient = JenkinsConnect.getClient();
    }

    /**
     * 创建 Job
     */
    public void ceateJob(){
        try {
            /**创建一个流水线任务,且设置一个简单的脚本**/
            // 创建 Pipeline 脚本
            String script = "node(){ \n" +
                                "echo 'hello world!' \n" +
                            "}";
            // xml配置文件,且将脚本加入到配置中
            String xml = "<flow-definition plugin=\"workflow-job@2.32\">\n" +
                             "<description>测试项目</description>\n" +
                             "<definition class=\"org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition\" plugin=\"workflow-cps@2.66\">\n" +
                                 "<script>" + script + "</script>\n" +
                                 "<sandbox>true</sandbox>\n" +
                             "</definition>\n" +
                          "</flow-definition>";
            // 创建 Job
            jenkinsServer.createJob("test-job",xml);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 更新 Job
     *
     * 更改之前创建的无参数Job,更改其为参数Job
     */
    public void updateJob(){
        try {
            /**
             * 更改一个流水线任务,让一个无参数的任务变成带参数任务
             */
            // 创建 Pipeline 脚本,用一个key变量
            String script = "node(){ \n" +
                    "echo \"${key}\" \n" +
                    "}";
            // xml配置文件,且将脚本加入到配置中
            String xml = "<flow-definition plugin=\"workflow-job@2.32\">\n" +
                    "<actions/>\n" +
                    "<description>测试项目</description>\n" +
                    "<keepDependencies>false</keepDependencies>\n" +
                    "<properties>\n" +
                    "<hudson.model.ParametersDefinitionProperty>\n" +
                    "<parameterDefinitions>\n" +
                    "<hudson.model.StringParameterDefinition>\n" +
                    "<name>key</name>\n" +
                    "<description>用于测试的字符变量</description>\n" +
                    "<defaultValue>hello</defaultValue>\n" +
                    "<trim>false</trim>\n" +
                    "</hudson.model.StringParameterDefinition>\n" +
                    "</parameterDefinitions>\n" +
                    "</hudson.model.ParametersDefinitionProperty>\n" +
                    "</properties>\n" +
                    "<definition class=\"org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition\" plugin=\"workflow-cps@2.66\">\n" +
                    "<script>" + script + "</script>\n" +
                    "<sandbox>true</sandbox>\n" +
                    "</definition>\n" +
                    "<disabled>false</disabled>\n" +
                    "</flow-definition>";
            // 创建 Job
            jenkinsServer.updateJob("test-job",xml);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取 Job 基本信息
     */
    public void getJob(){
        try {
            // 获取 Job 信息
            JobWithDetails job = jenkinsServer.getJob("test-job");
            // 获取 Job 名称
            System.out.println(job.getName());
            // 获取 Job URL
            System.out.println(job.getUrl());
            // 获取 Job 下一个 build 编号
            System.out.println(job.getNextBuildNumber());
            // 获取 Job 显示的名称
            System.out.println(job.getDisplayName());
            // 输出 Job 描述信息
            System.out.println(job.getDescription());
            // 获取 Job 下游任务列表
            System.out.println(job.getDownstreamProjects());
            // 获取 Job 上游任务列表
            System.out.println(job.getUpstreamProjects());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取 Maven Job 信息
     */
    public void getMavenJob(){
        try {
            // 获取 Job 信息
            MavenJobWithDetails job = jenkinsServer.getMavenJob("test-job");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取 Job 列表
     */
    public void getJobList(){
        try {
            // 获取 Job 列表
            Map<String,Job> jobs = jenkinsServer.getJobs();
            for (Job job:jobs.values()){
                System.out.println(job.getName());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取 View 名称获取 Job 列表
     */
    public void getJobListByView(){
        try {
            // 获取 Job 列表
            Map<String,Job> jobs = jenkinsServer.getJobs("all");
            for (Job job:jobs.values()){
                System.out.println(job.getName());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 查看 Job XML 信息
     */
    public void getJobConfig(){
        try {
            String xml = jenkinsServer.getJobXml("test-job");
            System.out.println(xml);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 执行无参数 Job build
     */
    public void buildJob(){
        try {
            jenkinsServer.getJob("test-job").build();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 执行带参数 Job build
     */
    public void buildParamJob(){
        try {
            /**
             * 例如,现有一个job,拥有一个字符参数"key"
             * 现在对这个值进行设置,然后执行一个输出这个值的脚本
             */
            // 设置参数值
            Map<String,String> param = new HashMap<>();
            param.put("key","hello world!");
            // 执行 build 任务
            jenkinsServer.getJob("test-job").build(param);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 停止最后构建的 Job Build
     */
    public void stopLastJobBuild(){
        try {
            // 获取最后的 build 信息
            Build build = jenkinsServer.getJob("test-job").getLastBuild();
            // 停止最后的 build
            build.Stop();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除 Job
     */
    public void deleteJob(){
        try {
            jenkinsServer.deleteJob("test-job");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 禁用 Job
     */
    public void disableJob(){
        try {
            jenkinsServer.disableJob("test-job");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 启用 Job
     */
    public void enableJob(){
        try {
            jenkinsServer.enableJob("test-job");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        JobApi jobApi = new JobApi();
        // 创建 Job
        jobApi.ceateJob();
        // 构建无参数的 Job
        jobApi.buildJob();
        // 构建带参数的 Job
        jobApi.buildParamJob();
        // 停止最后构建的 Job Build
        jobApi.stopLastJobBuild();
        // 更新 Job
        jobApi.updateJob();
        // 获取 Job 信息
        jobApi.getJob();
        // 获取 Maven 项目 Job
        jobApi.getMavenJob();
        // 获取 Job 配置xml
        jobApi.getJobConfig();
        // 获取全部 Job 列表
        jobApi.getJobList();
        // 根据 view 名称获取 Job 列表
        jobApi.getJobListByView();
        // 禁用 Job
        jobApi.disableJob();
        // 启用 Job
        jobApi.enableJob();
        // 删除 Job
        jobApi.deleteJob();
    }

}

5、操作编译

此类主要用于操作 Jenkins 中的 Build

JobBuildApi.java

import com.offbytwo.jenkins.JenkinsServer;
import com.offbytwo.jenkins.client.JenkinsHttpClient;
import com.offbytwo.jenkins.helper.Range;
import com.offbytwo.jenkins.model.*;
import java.io.IOException;
import java.util.List;

/**
 * Job Build(任务构建) 相关操作
 *
 * 例如对任务 Build 相关的信息进行获取操作、例如获取构建日志
 */
public class JobBuildApi {

    // Jenkins 对象
    private JenkinsServer jenkinsServer;
    // http 客户端对象
    private JenkinsHttpClient jenkinsHttpClient;

    /**
     * 构造方法中调用连接 Jenkins 方法
     */
    JobBuildApi() {
        JenkinsApi jenkinsApi = new JenkinsApi();
        // 连接 Jenkins
        jenkinsServer = JenkinsConnect.connection();
        // 设置客户端连接 Jenkins
        jenkinsHttpClient = JenkinsConnect.getClient();
    }

    /**
     * 获取 Job 最后的 Build
     */
    public void getJobLastBuild(){
        try {
            // 获取 Job 信息
            JobWithDetails job = jenkinsServer.getJob("test-job");
            // 获得最后编译信息
            Build lastBuild = job.getLastBuild();
            // 获取最后成功的编译信息
            Build lastSuccessfulBuild = job.getLastSuccessfulBuild();
            // 获取最后事变的编译信息
            Build lastFailedBuild = job.getLastFailedBuild();
            // 获取最后完成的编译信息
            Build lastCompletedBuild = job.getLastCompletedBuild();
            // 获取最后稳定的编译信息
            Build lastStableBuild = job.getLastStableBuild();
            // 获取最后不稳定的编译信息
            Build lastUnstableBuild = job.getLastUnstableBuild();
            // 获取最后未成功的编译信息
            Build lastUnsuccessfulBuild = job.getLastUnsuccessfulBuild();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取 Job 首次 Build
     */
    public void getJobFirstBuild(){
        try {
            // 获取 Job 信息
            JobWithDetails job = jenkinsServer.getJob("test-job");
            // 获得首次编译信息
            Build firstBuild = job.getFirstBuild();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据 Job Build 编号获取编译信息
     */
    public void getJobByNumber(){
        try {
            // 获取 Job 信息
            JobWithDetails job = jenkinsServer.getJob("test-job");
            // 根据
            Build numberBuild = job.getBuildByNumber(1);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取全部 Job Build列表
     */
    public void getJobBuildListAll(){
        try {
            // 获取 Job 信息
            JobWithDetails job = jenkinsServer.getJob("test-job");
            // 获取全部 Build 信息
            List<Build> builds = job.getAllBuilds();
            for (Build build:builds){
                System.out.println(build.getNumber());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取 Job 一定范围的 Build 列表
     */
    public void getJobBuildListRange(){
        try {
            // 获取 Job 信息
            JobWithDetails job = jenkinsServer.getJob("test-job");
            // 设定范围
            Range range = Range.build().from(1).to(2);
            System.err.println(range.getRangeString());
            // 获取一定范围的 Build 信息
            List<Build> builds = job.getAllBuilds(range);
            for (Build build:builds){
                System.out.println(build.getNumber());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取 Build 基本信息
     */
    public void getJobBuildInfo(){
        try {
            // 获取 Job 信息
            JobWithDetails job = jenkinsServer.getJob("test-job");
            // 这里用最后一次编译来示例
            Build build = job.getLastBuild();
            // 获取构建的 URL 地址
            System.out.println(build.getUrl());
            // 获取构建编号
            System.out.println(build.getNumber());
            // 获取测试报告
            //build.getTestReport();
            // 获取测试结果
            //build.getTestResult();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取 Build 详细信息
     */
    public void getJobBuildDetailInfo(){
        try {
            // 获取 Job 信息
            JobWithDetails job = jenkinsServer.getJob("test-job");
            // 这里用最后一次编译来示例
            BuildWithDetails build = job.getLastBuild().details();
            // 获取构建的显示名称
            System.out.println(build.getDisplayName());
            // 获取构建的参数信息
            System.out.println(build.getParameters());
            // 获取构建编号
            System.out.println(build.getNumber());
            // 获取构建结果,如果构建未完成则会显示为null
            System.out.println(build.getResult());
            // 获取执行构建的活动信息
            System.out.println(build.getActions());
            // 获取构建持续多少时间(ms)
            System.out.println(build.getDuration());
            // 获取构建开始时间戳
            System.out.println(build.getTimestamp());
            // 获取构建头信息,里面包含构建的用户,上游信息,时间戳等
            List<BuildCause> buildCauses = build.getCauses();
            for (BuildCause bc:buildCauses){
                System.out.println(bc.getUserId());
                System.out.println(bc.getShortDescription());
                System.out.println(bc.getUpstreamBuild());
                System.out.println(bc.getUpstreamProject());
                System.out.println(bc.getUpstreamUrl());
                System.out.println(bc.getUserName());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取 Build Log 日志信息
     */
    public void getJobBuildLog(){
        try {
            // 获取 Job 信息
            JobWithDetails job = jenkinsServer.getJob("test-job");
            // 这里用最后一次编译来示例
            BuildWithDetails build = job.getLastBuild().details();
            // 获取构建的日志,如果正在执行构建,则会只获取已经执行的过程日志

            // Text格式日志
            System.out.println(build.getConsoleOutputText());
            // Html格式日志
            System.out.println(build.getConsoleOutputHtml());

            // 获取部分日志,一般用于正在执行构建的任务
            ConsoleLog consoleLog = build.getConsoleOutputText(0);
            // 获取当前日志大小
            System.out.println(consoleLog.getCurrentBufferSize());
            // 是否已经构建完成,还有更多日志信息
            System.out.println(consoleLog.getHasMoreData());
            // 获取当前截取的日志信息
            System.out.println(consoleLog.getConsoleLog());
        }catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取正在执行构建任务的日志信息
     */
    public void getBuildActiveLog(){
        try {
            // 这里用最后一次编译来示例
            BuildWithDetails build = jenkinsServer.getJob("test-job").getLastBuild().details();
            // 当前日志
            ConsoleLog currentLog = build.getConsoleOutputText(0);
            // 输出当前获取日志信息
            System.out.println(currentLog.getConsoleLog());
            // 检测是否还有更多日志,如果是则继续循环获取
            while (currentLog.getHasMoreData()){
                // 获取最新日志信息
                ConsoleLog newLog = build.getConsoleOutputText(currentLog.getCurrentBufferSize());
                // 输出最新日志
                System.out.println(newLog.getConsoleLog());
                currentLog = newLog;
                // 睡眠1s
                Thread.sleep(1000);
            }
        }catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        JobBuildApi jobBuildApi = new JobBuildApi();
        // 获取 Job 最后的 Build
        jobBuildApi.getJobLastBuild();
        // 获取 Job 首次 Build
        jobBuildApi.getJobFirstBuild();
        // 根据 Job Build 编号获取编译信息
        jobBuildApi.getJobByNumber();
        // 获取 Build 全部列表
        jobBuildApi.getJobBuildListAll();
        // 获取一定范围的 Build 列表
        jobBuildApi.getJobBuildListRange();
        // 获取 Build 基本信息
        jobBuildApi.getJobBuildInfo();
        // 获取 Build 详细信息
        jobBuildApi.getJobBuildDetailInfo();
        // 获取 Build Log 日志信息
        jobBuildApi.getJobBuildLog();
        // 获得正在执行的编译 Log 日志信息
        jobBuildApi.getBuildActiveLog();
    }
}

6、其它 Jenkins 相关操作

此类主要用于操作 Jenkins 中的基本信息,例如关闭 Jenkins、获取 Jenkins 插件信息等。

JenkinsApi.java

import java.io.IOException;
import com.offbytwo.jenkins.JenkinsServer;
import com.offbytwo.jenkins.model.*;
import java.util.List;
import java.util.Map;

/**
 * 获取 Jenkins 相关信息
 *
 * 例如获取插件信息、获取Label信息、关闭Jenkins等
 */
public class JenkinsApi {

    // Jenkins 对象
    private JenkinsServer jenkinsServer;

    /**
     * 构造方法中调用连接 Jenkins 方法
     */
    JenkinsApi(){
        jenkinsServer = JenkinsConnect.connection();
    }

    /**
     * 获取主机信息
     */
    public void getComputerInfo() {
        try {
            Map<String, Computer> map = jenkinsServer.getComputers();
            for (Computer computer : map.values()) {
                // 获取当前节点-节点名称
                System.out.println(computer.details().getDisplayName());
                // 获取当前节点-执行者数量
                System.out.println(computer.details().getNumExecutors());
                // 获取当前节点-执行者详细信息
                List<Executor> executorList = computer.details().getExecutors();
                // 查看当前节点-是否脱机
                System.out.println(computer.details().getOffline());
                // 获得节点的全部统计信息
                LoadStatistics loadStatistics = computer.details().getLoadStatistics();
                // 获取节点的-监控数据
                Map<String, Map> monitorData = computer.details().getMonitorData();
                //......
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 重启 Jenkins
     */
    public void restart() {
        try {
            jenkinsServer.restart(true);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 安全重启 Jenkins
     */
    public void safeRestart() {
        try {
            jenkinsServer.safeRestart(true);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 安全结束 Jenkins
     */
    public void safeExit() {
        try {
            jenkinsServer.safeExit(true);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 关闭 Jenkins 连接
     */
    public void close() {
        jenkinsServer.close();
    }

    /**
     * 根据 Label 查找代理节点信息
     */
    public void getLabelNodeInfo() {
        try {
            LabelWithDetails labelWithDetails = jenkinsServer.getLabel("jnlp-agent");
            // 获取标签名称
            System.out.println(labelWithDetails.getName());
            // 获取 Cloud 信息
            System.out.println(labelWithDetails.getClouds());
            // 获取节点信息
            System.out.println(labelWithDetails.getNodeName());
            // 获取关联的 Job
            System.out.println(labelWithDetails.getTiedJobs());
            // 获取参数列表
            System.out.println(labelWithDetails.getPropertiesList());
            // 是否脱机
            System.out.println(labelWithDetails.getOffline());
            // 获取描述信息
            System.out.println(labelWithDetails.getDescription());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 判断 Jenkins 是否运行
     */
    public void isRunning() {
        boolean isRunning = jenkinsServer.isRunning();
        System.out.println(isRunning);
    }

    /**
     * 获取 Jenkins 插件信息
     */
    public void getPluginInfo(){
        try {
            PluginManager pluginManager =jenkinsServer.getPluginManager();
            // 获取插件列表
            List<Plugin> plugins = pluginManager.getPlugins();
            for (Plugin plugin:plugins){
                // 插件 wiki URL 地址
                System.out.println(plugin.getUrl());
                // 版本号
                System.out.println(plugin.getVersion());
                // 简称
                System.out.println(plugin.getShortName());
                // 完整名称
                System.out.println(plugin.getLongName());
                // 是否支持动态加载
                System.out.println(plugin.getSupportsDynamicLoad());
                // 插件依赖的组件
                System.out.println(plugin.getDependencies());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        // 创建 JenkinsApi 对象,并在构造方法中连接 Jenkins
        JenkinsApi jenkinsApi = new JenkinsApi();
        // 重启 Jenkins
        //jenkinsApi.restart();
        // 安全重启 Jenkins
        //jenkinsApi.safeRestart();
        // 获取节点信息
        //jenkinsApi.getComputerInfo();
        // 安全结束 Jenkins
        //jenkinsApi.safeExit();
        // 关闭 Jenkins 连接
        //jenkinsApi.close();
        // 获取 Label 节点信息
        //jenkinsApi.getLabelNodeInfo();
        // 查看 Jenkins 是否允许
        //jenkinsApi.isRunning();
        // 获取 Jenkins 插件信息
        //jenkinsApi.getPluginInfo();
    }

}

四、对 Java Client 组件的补充

关于该 Jenkins Java Client 部分功能封装并不完整,这里有部分网友咨询相关问题,补充一下:

import com.offbytwo.jenkins.JenkinsServer;
import com.offbytwo.jenkins.client.JenkinsHttpClient;
import com.offbytwo.jenkins.client.util.EncodingUtils;
import java.io.IOException;

public class CustomService {

    // Jenkins 对象
    private JenkinsServer jenkinsServer;
    // http 客户端对象
    private JenkinsHttpClient jenkinsHttpClient;

    /**
     * 构造方法中调用连接 Jenkins 方法
     */
    CustomService() {
        // 连接 Jenkins
        jenkinsServer = JenkinsConnect.connection();
        // 设置客户端连接 Jenkins
        jenkinsHttpClient = JenkinsConnect.getClient();
    }

    /**
     * 创建 Jenkins Job 并指定 Job 类型
     * 关于 Jenkins Job 部分类型,如下:
     *   - 自由风格项目:hudson.model.FreeStyleProject
     *   - Maven 项目:hudson.maven.MavenModuleSet
     *   - 流水线项目:org.jenkinsci.plugins.workflow.job.WorkflowJob
     *   - 多配置项目:hudson.matrix.MatrixProject
     */
    public void createJob() {
        try {
            // job 名称
            String jobName = "test-project";
            // 创建 Job 的 xml,可以在 jenkins 中查看,例如 http://jenkins.mydlq.club/job/{job名称}/config.xml 来查看该 job 的 xml 配置
            String jobXml = "<project>\n" +
                    "<keepDependencies>false</keepDependencies>\n" +
                    "<properties/>\n" +
                    "<scm class=\"hudson.scm.NullSCM\"/>\n" +
                    "<canRoam>false</canRoam>\n" +
                    "<disabled>false</disabled>\n" +
                    "<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>\n" +
                    "<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>\n" +
                    "<triggers/>\n" +
                    "<concurrentBuild>false</concurrentBuild>\n" +
                    "<builders/>\n" +
                    "<publishers/>\n" +
                    "<buildWrappers/>\n" +
                    "<link type=\"text/css\" id=\"dark-mode\" rel=\"stylesheet\" href=\"\"/>\n" +
                    "</project>";
            // 创建 Jenkins Job 并指定 Job 类型
            jenkinsHttpClient.post_xml("createItem?name=" + EncodingUtils.encodeParam(jobName) +
                    "&mode=hudson.model.FreeStyleProject", jobXml, true);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        // 自定义服务
        CustomService customService = new CustomService();
        // 创建指定类型的 Job
        customService.createJob();
    }

}

—END—