1,需求

获取每次构建请求对应的buildNum ,方便后续的操作,比如依据buildNum 获取对应的控制台LOG 。

2,尝试一:JobWithDetails获取下一次构建序号

使用的是JobWithDetails 获取下一次构建的序号。大致代码如下:

JenkinsServer server = new JenkinsServer(new URI(http://localhost:9999), "Jenkins用户名", "Jenkins密码");
JobWithDetails job = jenkinsServer.getJob("你的项目名");

//字符类型的参数
Map<String, String> strParam = new HashMap<>();
//。。。依据Jenkins 服务上配置的构建表单,put 到 strParam 中去,要求 字段名相同。
//文件类型的参数
Map<String, File> fileParam = new HashMap<>();
//。。。依据Jenkins 服务上配置的构建表单,put 文件 到 fileParam 中去,要求 字段名相同。
 //执行Job
 job.build(strParam, fileParam);
 //获取BuildNum
int buildNum = job.getNextBuildNumber();
。。。。

出现的问题是:
如果一个项目多次build的情况下,通过上面获取的buildNum 的值可能为同一个值。

分析:
当同一个项目发生多次build请求的话,每次服务器对于同一个项目,只会执行其中的一个请求,剩下的则丢到队列里进行排队,排队中的项目 其实是没有被分配buildNum 的,可以通过queue接口访问,具体可继续看下文所述。
例如下图:图中的两个build 是同一个项目的。
在这里插入图片描述

额,是不是有点无奈~哈哈,不要灰心嘛, 办法总会有的。

3,尝试二: 使用Queue

获取Queue ,我最初的入手点,是通过JenkinsSever .getQueue,部分代码如下:

List<QueueItem> waitQueue = jenkinsServer.getQueue().getItems();
            for (QueueItem queueItem : waitQueue) {
            //可获取Queue相关的信息
                LOGGER.info("job名字:{},是否阻塞:{},是否被取消:{}", queueItem.getTask().getName(), queueItem.isBlocked(), queueItem.isCancelled());
 }

在这里插入图片描述
情景说明:
预批量 发送 2次 请求 启动JOB-A

解题思路:
当检测到JenkinsSever.getQueue 里有 JOB-A , 则延迟发送请求 。

再次陷入难题:
第1次请求成功后 并且执行状态 为正在构建中, 这时候 第二次发送过去的时候,JenkinsSever.getQueue里不存在了,所以 后端 代码 开始执行 job.build(strParam, fileParam); , 然后 悲剧 了, 这时候因为 第一次的JOB-A 并没有完全 执行完 ,第二次 被丢到了队列中去了 。 获取到的 job.getNextBuildNumber(); 和 第一次JOB-A 获取的值一样 !!!

所以: 最好把 job.getNextBuildNumber() 理解为 正在运行中的 吧 ,

4,最终尝试:请求Queue的API接口

虽然通过JobWithDetails 获取不到正确的buildNum , 但可以获取到每次构建的队列ID 哦 。
仔细看 JobWithDetails 的 build 方法竟然还有返回值 QueueReference ,哈哈,贼开心啦,看着类名就知道和 Queue 有关啦,果然,

//返回值 ,一般是构建队列的请求url 
// eg: http://localhost:8080/queue/item/225/
//接口数据接口url: http://localhost:8080/queue/item/225/api/json 
queueReference.getQueueItemUrlPart()

注意: 上述的“225”是对应的构建队列No , 不是固定的,每次构建一个项目,都会 分配一个 唯一的 队列号!
这个Queue 一般在构建项目结束后,过一段时间,再去请求会报404 , 估摸着应该是构建完成了,队列里要移除的原因吧~

以下提供一个具体实例,方便理解:
(1)开始构建一个项目,如下图,已经被安排到队列中去了。
在这里插入图片描述
(2)再Java 里启动 Job 之后,可以获取对应的队列Url , 控制台打印如下图。
在这里插入图片描述
(3)浏览器访问队列API 接口 。需要注意的是,只要启动了Job ,就会有 一个队列 , 但是每个队列API 接口数据 里 的 executable 不是 都会有的,只有 被开始执行了,才会分配。如果没有 , 则说明还在是排队中
在这里插入图片描述

所以,我最终的解决办法就是 , 获取 executable 里的 number 作为 准确的 buildNum 。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐