Java使用Jenkins API操作任务,视图,部署等

1、什么是Jenkins API

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

2、Jenkins API分类

①、JSON API

浏览器打开http://JenkinsURL/api/json

image-20211008113808815

格式化如下

{
    "_class":"hudson.model.Hudson",
    "assignedLabels":[
        {
            "name":"master"
        }
    ],
    "mode":"NORMAL",
    "nodeDescription":"the master Jenkins node",
    "nodeName":"",
    "numExecutors":2,
    "description":null,
    "jobs":[
        {
            "_class":"hudson.maven.MavenModuleSet",
            "name":"CenterServer",
            "url":"http://192.168.225.130/job/CenterServer/",
            "color":"blue"
        },
        {
            "_class":"hudson.maven.MavenModuleSet",
            "name":"HelloWorld",
            "url":"http://192.168.225.130/job/HelloWorld/",
            "color":"blue"
        },
        {
            "_class":"hudson.maven.MavenModuleSet",
            "name":"PMServer",
            "url":"http://192.168.225.130/job/PMServer/",
            "color":"blue"
        }
    ],
    "overallLoad":{

    },
    "primaryView":{
        "_class":"hudson.model.AllView",
        "name":"all",
        "url":"http://192.168.225.130/"
    },
    "quietDownReason":null,
    "quietingDown":false,
    "slaveAgentPort":-1,
    "unlabeledLoad":{
        "_class":"jenkins.model.UnlabeledLoadStatistics"
    },
    "url":"http://192.168.225.130/",
    "useCrumbs":true,
    "useSecurity":true,
    "views":[
        {
            "_class":"hudson.model.AllView",
            "name":"all",
            "url":"http://192.168.225.130/"
        }
    ]
}

②、XML API

浏览器打开http://JenkinsURL/api/xml

image-20211008114011905

<hudson _class="hudson.model.Hudson">
    <assignedLabel>
        <name>master</name>
    </assignedLabel>
    <mode>NORMAL</mode>
    <nodeDescription>the master Jenkins node</nodeDescription>
    <nodeName/>
    <numExecutors>2</numExecutors>
    <job _class="hudson.maven.MavenModuleSet">
        <name>CenterServer</name>
        <url>http://192.168.225.130/job/CenterServer/</url>
        <color>blue</color>
    </job>
    <job _class="hudson.maven.MavenModuleSet">
        <name>HelloWorld</name>
        <url>http://192.168.225.130/job/HelloWorld/</url>
        <color>blue</color>
    </job>
    <job _class="hudson.maven.MavenModuleSet">
        <name>PMServer</name>
        <url>http://192.168.225.130/job/PMServer/</url>
        <color>blue</color>
    </job>
    <overallLoad/>
    <primaryView _class="hudson.model.AllView">
        <name>all</name>
        <url>http://192.168.225.130/</url>
    </primaryView>
    <quietingDown>false</quietingDown>
    <slaveAgentPort>-1</slaveAgentPort>
    <unlabeledLoad _class="jenkins.model.UnlabeledLoadStatistics"/>
    <url>http://192.168.225.130/</url>
    <useCrumbs>true</useCrumbs>
    <useSecurity>true</useSecurity>
    <view _class="hudson.model.AllView">
        <name>all</name>
        <url>http://192.168.225.130/</url>
    </view>
</hudson>

③、Python API

浏览器打开http://JenkinsURL/api/python

格式化如下

image-20211008114113962

{
    "_class":"hudson.model.Hudson",
    "assignedLabels":[
        {
            "name":"master"
        }
    ],
    "mode":"NORMAL",
    "nodeDescription":"the master Jenkins node",
    "nodeName":"",
    "numExecutors":2,
    "description":None,
    "jobs":[
        {
            "_class":"hudson.maven.MavenModuleSet",
            "name":"CenterServer",
            "url":"http://192.168.225.130/job/CenterServer/",
            "color":"blue"
        },
        {
            "_class":"hudson.maven.MavenModuleSet",
            "name":"HelloWorld",
            "url":"http://192.168.225.130/job/HelloWorld/",
            "color":"blue"
        },
        {
            "_class":"hudson.maven.MavenModuleSet",
            "name":"PMServer",
            "url":"http://192.168.225.130/job/PMServer/",
            "color":"blue"
        }
    ],
    "overallLoad":{

    },
    "primaryView":{
        "_class":"hudson.model.AllView",
        "name":"all",
        "url":"http://192.168.225.130/"
    },
    "quietDownReason":None,
    "quietingDown":False,
    "slaveAgentPort":-1,
    "unlabeledLoad":{
        "_class":"jenkins.model.UnlabeledLoadStatistics"
    },
    "url":"http://192.168.225.130/",
    "useCrumbs":True,
    "useSecurity":True,"views":[
        {
            "_class":"hudson.model.AllView",
            "name":"all",
            "url":"http://192.168.225.130/"
        }
    ]
}

④、其他

根据以上三种API查询出来的信息中出现了几个任务的urlhttp://192.168.225.130/job/HelloWorld/,可以在在后面追加/api/xml访问查看对应Job的构建记录

image-20211008142015180

根据提供了若干构建记录还可以查看构建的详细信息,直接访问提供的url即可http://192.168.225.130/job/helloworld/11/

image-20211008142300297

3、使用Java调用Jenkins API

创建一个Jenkins API Demo工程

image-20211008142854297

导入依赖

<dependencies>
    <!-- https://mvnrepository.com/artifact/com.offbytwo.jenkins/jenkins-client -->
    <dependency>
        <groupId>com.offbytwo.jenkins</groupId>
        <artifactId>jenkins-client</artifactId>
        <version>0.3.8</version>
    </dependency>
</dependencies>

创建Jenkins链接工具类JenkinsConnectFactory

package com.phz.jenkins_api_demo.factory;

import com.offbytwo.jenkins.JenkinsServer;
import com.offbytwo.jenkins.client.JenkinsHttpClient;

import java.net.URI;
import java.net.URISyntaxException;

/**
 * @author PengHuAnZhi
 * @ProjectName Jenkins API Demo
 * @Description Jenkins连接工具类
 * @time 2021/10/8 14:33
 */
public class JenkinsConnectFactory {
    static final String JENKINS_URL = "http://192.168.225.130";
    static final String JENKINS_USERNAME = "PengHuanZhi";
    static final String JENKINS_PASSWORD = "123456789";
    private static JenkinsHttpClient jenkinsHttpClient = null;
    private static JenkinsServer jenkinsServer = null;

    public static JenkinsHttpClient getClientInstance() {
        if (jenkinsHttpClient == null) {
            try {
                jenkinsHttpClient = new JenkinsHttpClient(new URI(JENKINS_URL, JENKINS_USERNAME, JENKINS_PASSWORD), "PengHuanZhi", "11622ce96b51846c8658a6390253d87f7e");
            } catch (URISyntaxException e) {
                e.printStackTrace();
            }
        }
        return jenkinsHttpClient;
    }

    public static JenkinsServer getConnection() {
        if (jenkinsServer == null) {
            try {
                jenkinsServer = new JenkinsServer(new URI(JENKINS_URL, JENKINS_USERNAME, JENKINS_PASSWORD), "PengHuanZhi", "11622ce96b51846c8658a6390253d87f7e");
            } catch (URISyntaxException e) {
                e.printStackTrace();
            }
        }
        return jenkinsServer;
    }
}

①、View

Ⅰ、创建View

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

image-20211008154926896

Ⅱ、获取View

/**
 * @description 获取视图基本信息
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void getView() {
    try {
        // 视图名
        String viewName = "test-view";
        // 获取视图基本信息
        View view = JenkinsConnectFactory.getConnection().getView(viewName);
        System.out.println(view.getName());
        System.out.println(view.getUrl());
        System.out.println(view.getDescription());
        // 获取视图xml信息
        String viewXml = JenkinsConnectFactory.getClientInstance().get("/view/" + viewName + "/api/xml");
        System.out.println(viewXml);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

image-20211008154906735

Ⅲ、获取View配置 XML 信息

/**
 * @description 获取视图基本信息
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void getViewConfig() {
    try {
        // 视图名
        String viewName = "test-view";
        // 获取视图配置xml信息
        String viewConfigXml = JenkinsConnectFactory.getClientInstance().get("/view/" + viewName + "/config.xml");
        System.out.println(viewConfigXml);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

image-20211008155023155

Ⅳ、更新View

/**
 * @description 更新视图信息
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
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>";
        JenkinsConnectFactory.getConnection().updateView("test-view", xml);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

image-20211008155133993

Ⅴ、删除View

/**
 * @description 删除视图
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void deleteView() {
    try {
        String viewName = "test-view";
        JenkinsConnectFactory.getClientInstance().post("/view/" + viewName + "/doDelete");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

image-20211008155223839

②、Job

Ⅰ、创建Job

/**
 * @description 创建Job
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void createJob() {
    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
        JenkinsConnectFactory.getConnection().createJob("test-job", xml);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1bLLJziA-1633686593481)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211008161119542.png)]

Ⅱ、更新Job

/**
 * @description 更新Job 更改之前创建的无参数Job,更改其为参数Job
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
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
        JenkinsConnectFactory.getConnection().updateJob("test-job", xml);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

image-20211008161247709

Ⅲ、获取Job基本信息

/**
 * @description 获取 Job 基本信息
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void getJob() {
    try {
        // 获取 Job 信息
        JobWithDetails job = JenkinsConnectFactory.getConnection().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();
    }
}

image-20211008162648898

Ⅳ、获取Maven Job信息

/**
 * @description 获取 Maven Job 信息
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void getMavenJob() {
    try {
        // 获取 Job 信息
        MavenJobWithDetails job = JenkinsConnectFactory.getConnection().getMavenJob("HelloWorld");
        // 获取 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.getDownstreamProjects());
        // 获取 Job 上游任务列表
        System.out.println(job.getUpstreamProjects());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

image-20211008162841371

Ⅴ、获取Job列表

/**
 * @description 获取 Job 列表
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void getJobList() {
    try {
        // 获取 Job 列表
        Map<String, Job> jobs = JenkinsConnectFactory.getConnection().getJobs();
        for (Job job : jobs.values()) {
            System.out.println(job.getName());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

image-20211008162918835

Ⅵ、根据View名称获取Job列表

/**
 * @description 根据 View 名称获取 Job 列表
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void getJobListByView() {
    try {
        // 获取 Job 列表
        Map<String, Job> jobs = JenkinsConnectFactory.getConnection().getJobs("all");
        for (Job job : jobs.values()) {
            System.out.println(job.getName());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

image-20211008163022306

Ⅶ、查看Job XML信息

/**
 * @description 查看 Job 配置信息(XML)
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void getJobConfig() {
    try {
        String xml = JenkinsConnectFactory.getConnection().getJobXml("test-job");
        System.out.println(xml);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

image-20211008163118165

Ⅷ、无参数 Job build

因为修改过本Job为有参Job,这里测试还需更改为无参job

/**
 * @description 执行无参数 Job build
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void buildJob() {
    try {
        JenkinsConnectFactory.getConnection().getJob("test-job").build();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Ⅸ、有参构建

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

image-20211008164107428

Ⅹ、停止最后构建的 Job Build

/**
 * @description 停止最后构建的 Job Build
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void stopLastJobBuild() {
    try {
        // 获取最后的 build 信息
        Build build = JenkinsConnectFactory.getConnection().getJob("HelloWorld").getLastBuild();
        // 停止最后的 build
        build.Stop();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

image-20211008164859726

ⅩⅠ、禁用 Job

/**
 * @description 禁用 Job
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void disableJob() {
    try {
        JenkinsConnectFactory.getConnection().disableJob("test-job");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

image-20211008165208914

ⅩⅡ、启用Job

/**
 * 启用 Job
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void enableJob() {
    try {
        JenkinsConnectFactory.getConnection().enableJob("test-job");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

image-20211008165335690

ⅩⅢ、删除 Job

/**
 * @description 删除 Job
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void deleteJob() {
    try {
        JenkinsConnectFactory.getConnection().deleteJob("test-job");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

image-20211008165045746

③、编译

Ⅰ、获取Build基本信息

/**
 * @param build build对象
 * @description 将Build内部信息打印
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
private void printBuild(Build build) throws IOException {
    System.out.println(build.getNumber());
    System.out.println(build.getUrl());
    System.out.println(build.getQueueId());
}

Ⅱ、获取 Job 最后的 Build

/**
 * @description 获取 Job 最后的 Build
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void getJobLastBuild() {
    try {
        // 获取 Job 信息
        JobWithDetails job = JenkinsConnectFactory.getConnection().getJob("test-job");
        // 获得最后编译信息
        Build lastBuild = job.getLastBuild();
        printBuild(lastBuild);
        // 获取最后成功的编译信息
        Build lastSuccessfulBuild = job.getLastSuccessfulBuild();
        printBuild(lastSuccessfulBuild);
        // 获取最后事变的编译信息
        Build lastFailedBuild = job.getLastFailedBuild();
        printBuild(lastFailedBuild);
        // 获取最后完成的编译信息
        Build lastCompletedBuild = job.getLastCompletedBuild();
        printBuild(lastCompletedBuild);
        // 获取最后稳定的编译信息
        Build lastStableBuild = job.getLastStableBuild();
        printBuild(lastStableBuild);
        // 获取最后不稳定的编译信息
        Build lastUnstableBuild = job.getLastUnstableBuild();
        printBuild(lastUnstableBuild);
        // 获取最后未成功的编译信息
        Build lastUnsuccessfulBuild = job.getLastUnsuccessfulBuild();
        printBuild(lastUnsuccessfulBuild);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

image-20211008170337616

Ⅲ、获取 Job 首次 Build

/**
 * @description 获取 Job 首次 Build
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void getJobFirstBuild() {
    try {
        // 获取 Job 信息
        JobWithDetails job = JenkinsConnectFactory.getConnection().getJob("test-job");
        // 获得首次编译信息
        Build firstBuild = job.getFirstBuild();
        printBuild(firstBuild);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

image-20211008170508024

Ⅳ、根据 Job Build 编号获取编译信息

/**
 * @description 根据 Job Build 编号获取编译信息
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void getJobByNumber() {
    try {
        // 获取 Job 信息
        JobWithDetails job = JenkinsConnectFactory.getConnection().getJob("test-job");
        // 根据
        Build numberBuild = job.getBuildByNumber(1);
        printBuild(numberBuild);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

image-20211008170607523

Ⅴ、获取全部 Job Build列表

/**
 * @description 获取全部 Job Build列表
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void getJobBuildListAll() {
    try {
        // 获取 Job 信息
        JobWithDetails job = JenkinsConnectFactory.getConnection().getJob("test-job");
        // 获取全部 Build 信息
        List<Build> builds = job.getAllBuilds();
        for (Build build : builds) {
            System.out.println(build.getNumber());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

image-20211008170703314

Ⅵ、获取 Job 一定范围的 Build 列表

/**
 * @description 获取 Job 一定范围的 Build 列表
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void getJobBuildListRange() {
    try {
        // 获取 Job 信息
        JobWithDetails job = JenkinsConnectFactory.getConnection().getJob("test-job");
        // 设定范围
        Range range = Range.build().from(0).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();
    }
}

image-20211008170936248

Ⅶ、获取Build详细信息

/**
 * @description 获取 Build 详细信息
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void getJobBuildDetailInfo() {
    try {
        // 获取 Job 信息
        JobWithDetails job = JenkinsConnectFactory.getConnection().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();
    }
}

image-20211008171232437

Ⅷ、获取 Build Log 日志信息

/**
 * @description 获取 Build Log 日志信息
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void getJobBuildLog() {
    try {
        // 获取 Job 信息
        JobWithDetails job = JenkinsConnectFactory.getConnection().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();
    }
}

image-20211008171323524

Ⅸ、获取正在执行构建任务的日志信息

/**
 * @description 获取正在执行构建任务的日志信息
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void getBuildActiveLog() {
    try {
        // 这里用最后一次编译来示例
        BuildWithDetails build = JenkinsConnectFactory.getConnection().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();
    }
}

image-20211008171401836

④、其他

Ⅰ、获取主机信息

/**
 * @description 获取主机信息
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void getComputerInfo() {
    try {
        Map<String, Computer> map = JenkinsConnectFactory.getConnection().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();
    }
}

image-20211008171446108

Ⅱ、重启Jenkins

/**
 * @description 重启 Jenkins
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void restart() {
    try {
        JenkinsConnectFactory.getConnection().restart(true);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Ⅲ、安全重启Jenkins

/**
 * @description 安全重启 Jenkins
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void safeRestart() {
    try {
        JenkinsConnectFactory.getConnection().safeRestart(true);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Ⅳ、安全结束Jenkins

/**
 * @description 安全结束 Jenkins
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void safeExit() {
    try {
        JenkinsConnectFactory.getConnection().safeExit(true);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

image-20211008171651850

Ⅴ、关闭连接

/**
 * @description 关闭 Jenkins 连接
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void close() {
    JenkinsConnectFactory.getConnection().close();
}

Ⅵ、根据 Label 查找代理节点信息

/**
 * @description 根据 Label 查找代理节点信息
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void getLabelNodeInfo() {
    try {
        LabelWithDetails labelWithDetails = JenkinsConnectFactory.getConnection().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();
    }
}

image-20211008171832114

Ⅶ、判断Jenkins是否运行

/**
 * @description 判断 Jenkins 是否运行
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void isRunning() {
    boolean isRunning = JenkinsConnectFactory.getConnection().isRunning();
    System.out.println(isRunning);
}

image-20211008171915494

Ⅷ、获取 Jenkins 插件信息

/**
 * @description 获取 Jenkins 插件信息
 * @author PengHuAnZhi
 * @date 2021/10/8 17:20
 */
public void getPluginInfo() {
    try {
        PluginManager pluginManager = JenkinsConnectFactory.getConnection().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();
    }
}

image-20211008172006927

4、问题处理

①、HttpResponseException: Forbidden

这种跨域问题有两种处理办法,第一种就是关闭Jenkins的跨域保护

Ⅰ、关闭跨域保护(高版本)

笔者Jenkins服务放在了一台CentOS8虚拟机中

vim /etc/sysconfig/jenkins

找到JENKINS_JAVA_OPTIONS配置

image-20211008151621370

在后面追加如下内容

-Dhudson.security.csrf.GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION=true

image-20211008151748192

保存退出重启Jenkins服务

systemctl restart jenkins.service 

查看配置生效

image-20211008153025592

Ⅱ、携带Token建立连接

进入用户管理页面,新增一个Token

image-20211008153342665

在创建JenkinsHttpClientJenkinsServer的时候添加该Token,如下

                jenkinsHttpClient = new JenkinsHttpClient(new URI(JENKINS_URL, JENKINS_USERNAME, JENKINS_PASSWORD), "PengHuanZhi", "11622ce96b51846c8658a6390253d87f7e");
                jenkinsServer = new JenkinsServer(new URI(JENKINS_URL, JENKINS_USERNAME, JENKINS_PASSWORD), "PengHuanZhi", "11622ce96b51846c8658a6390253d87f7e");

参考1

参考2

  • 7
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,您可以按照以下步骤使用Java代码实现Jenkins API来执行打包和部署: 1. 首先,您需要使用Jenkins提供的Java API,您可以从官方文档中了解如何使用API。 2. 在您的Java代码中,您需要使用Jenkins的REST API来执行打包和部署操作。您可以通过以下方式来执行此操作: a. 首先,您需要构建REST API的URL。例如,如果您想执行名为"job_name"的作业,则URL将如下所示: `http://<jenkins_server_url>/job/<job_name>/build` b. 您需要设置HTTP请求的头文件,以便Jenkins可以验证您的请求。您需要设置"Authorization"头文件,其中包含您的Jenkins用户名和API令牌。例如: ``` String jenkinsUrl = "<jenkins_server_url>"; String jobName = "<job_name>"; String username = "<jenkins_username>"; String apiToken = "<jenkins_api_token>"; String auth = username + ":" + apiToken; byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(Charset.forName("US-ASCII"))); String authHeader = "Basic " + new String(encodedAuth); URL url = new URL(jenkinsUrl + "/job/" + jobName + "/build"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setRequestProperty("Authorization", authHeader); connection.setDoOutput(true); ``` c. 然后,您需要设置POST请求的参数,以便Jenkins可以了解您要执行的操作。例如,如果您要执行打包和部署操作,则需要设置以下参数: ``` String parameters = "token=<build_token>&cause=<build_cause>&PARAMETER_NAME=<parameter_value>"; byte[] postData = parameters.getBytes(Charset.forName("UTF-8")); int postDataLength = postData.length; connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); connection.setRequestProperty("Content-Length", Integer.toString(postDataLength)); try (DataOutputStream wr = new DataOutputStream(connection.getOutputStream())) { wr.write(postData); } ``` 在上面的代码中,"token"参数是用于验证请求的令牌,"cause"参数是用于记录此次构建的原因(例如,"manual"表示手动构建)。"PARAMETER_NAME"参数是您要设置的参数名称,"parameter_value"是您要设置的参数值。 d. 最后,您需要执行HTTP请求,并处理Jenkins的响应。例如,如果您想获取构建的编号,则可以使用以下代码: ``` int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_CREATED) { String location = connection.getHeaderField("Location"); String[] parts = location.split("/"); String buildNumber = parts[parts.length - 1]; System.out.println("Build number: " + buildNumber); } else { System.out.println("Failed to start build: " + responseCode); } ``` 在上面的代码中,如果HTTP响应代码为"HTTP_CREATED"(表示构建已成功启动),则从响应头中获取构建号。否则,打印错误消息。 这些是使用Java代码执行Jenkins API来执行打包和部署操作的基本步骤。您可以根据自己的需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值