姿态 发表于 2019-4-10 17:05:19

Jenkins RESTful API 定制化

1.背景Jenkins具有丰富的插件生态,足以满足我们日常工作的需求;如果我们想通过具体的Jenkins任务直接对外提供服务,而我们不想将内部的具体实现对外暴露(否则,需添加对应的用户权限,通过页面执行job);可以对外直接提供接口,第三方直接调用接口(比如提供给开发,提测前回归冒烟用例集),执行相应的Jenkins任务并获取任务结果。2.Jenkins原生Remote access APIJenkins提供了原生的Remote accsee API, 主要用来做:1.检索Jenkins中信息
2.触发新构建
3.创建/复制任务
实例:获取项目FastTest信息:
curl -u user:pwd -X POST http://ip:port/jenkins/job/FastTest/api/xml
并支持Xpath进行信息提取,详见 https://issues.jenkins-ci.org/browse/JENKINS-626

触发新的构建(带参数构建):
curl -u user:pwd -X POST http://ip:port/jenkins/job/FastTest/buildWithParameters -d "environment=运行环境&module=模块&mailer=收件人"

该接口响应头信息:
* upload completely sent off: 94 out of 94 bytes
< HTTP/1.1 201 Created
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< Location: http://ip:port/jenkins/queue/item/111/
< Content-Length: 0
< Date: Wed, 05 Oct 2016 07:39:39 GMT
<
* Connection #0 to host 10.210.228.50 left intact

但是该接口无任何返回信息。
完整的Remote access API wiki 可以通过如下获取:curl-u user:pwd -X POST http://ip:port/jenkins/job/FastTest/api/ > /Users/hugang/Desktop/jenkins_api_wiki.html原生的接口,功能较为简单、不友好,需封装Jenkins的api,提供有价值的接口返回信息。3.Jenkins api wrappersJenkins api wrappers有多种编程语言实现, 可以很方便的操作Jenkins,具体如下:Node.js: https://www.npmjs.com/package/jenkins-apiruby: https://rubygems.org/gems/jenkins_api_clientpython: https://pypi.python.org/pypi/python-jenkins/java: https://github.com/jenkinsci/java-client-api本文将使用java的Jenkins api wrappers:java-client-api作为介绍,定制适合自己的Jenkins RESTful API.4.定制Jenkins RESTful API新建一个Maven webapp工程,工程pom.xml中添加java-client-api依赖:<dependency>
<groupId>com.offbytwo.jenkins</groupId>
<artifactId>jenkins-client</artifactId>
<version>0.3.6</version>
</dependency>
项目使用Spring RESTful web serviceController层执行用例接口:package com.weibo.qa.fasttestapi.controller;


import com.weibo.qa.fasttestapi.model.RunInfo;
import com.weibo.qa.fasttestapi.service.EmailSuffixService;
import com.weibo.qa.fasttestapi.service.FastTestJenkinsService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
*
* 接口/fasttest/run:
*
* params:
*
* env 测试环境
* module 模块
* email 收件人
*
*
* result:
*
* {"result":true,"jobId":int值}
*
* Created by hugang on 16/9/19.
*/
@RestController
public class RunController {

    @RequestMapping(value = "/fasttest/run.json", method = RequestMethod.POST)
    public RunInfo runFasttest(@RequestParam(value = "env", required = true) String env,
                        @RequestParam(value = "module", required = true, defaultValue = "BVT") String module,
                        @RequestParam(value = "email", required = true, defaultValue = "hugang") String email){

      FastTestJenkinsService fastTestJenkinsService = new FastTestJenkinsService();
      // 增加邮箱后缀
      EmailSuffixService emailSuffix = new EmailSuffixService();

      String receiver = emailSuffix.addEmailSuffix(email);

      int jobId = fastTestJenkinsService.buildJob(env, module, receiver);

      RunInfo runInfo = new RunInfo();

      runInfo.setJobId(jobId);
      runInfo.setResult(true);

      return runInfo;

    }

}
根据jobId判断是否执行结束接口:package com.weibo.qa.fasttestapi.controller;

import com.weibo.qa.fasttestapi.model.FinishInfo;
import com.weibo.qa.fasttestapi.service.FastTestJenkinsService;
import org.springframework.web.bind.annotation.*;

/**
* Created by hugang on 16/9/20.
*/

@RestController
public class FinishController {

    @RequestMapping(value = "/fasttest/finish.json",method = RequestMethod.GET)
    public @ResponseBody
    FinishInfo isFinish(@RequestParam(value = "job_id", required = true)int job_id) {

      FastTestJenkinsService fastTestJenkinsService = new FastTestJenkinsService();

      boolean isFinish = fastTestJenkinsService.isJobFinish(job_id);

      FinishInfo finishInfo = new FinishInfo();

      finishInfo.setFinished(isFinish);

      return finishInfo;

    }
}
service层执行具体的业务:FastTestJenkinsService.javapackage com.weibo.qa.fasttestapi.service;

import com.offbytwo.jenkins.JenkinsServer;
import com.offbytwo.jenkins.model.Job;
import com.offbytwo.jenkins.model.JobWithDetails;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;

/**
* Created by hugang on 16/9/19.
*/
public class FastTestJenkinsService {



    /**
   *
   * @param env 测试环境
   * @param module 测试模块
   * @param email收件人
   * @return jobId
   */
    public int buildJob(String env, String module, String email) {

      int buildNumber = 0;
      try{
            JenkinsServer jenkinsServer = new JenkinsServer(new URI("http://ip:port/jenkins"), "test", "pwd");

            Map<String, Job> jobs = jenkinsServer.getJobs();

            JobWithDetails job = jobs.get("FastTest").details();

            // 即将执行任务的jobId
            buildNumber = job.getNextBuildNumber();

            // 参数化构建
            Map<String, String> params = new HashMap<String, String>();
            params.put("environment", env);
            params.put("module", module);
            params.put("mailer", email);
            job.build(params);


      }catch (Exception e){
            e.printStackTrace();
      } finally {

      }
      return buildNumber;
    }


    /**
   *
   * @param jobId
   * @return 是否执行结束
   */
    public boolean isJobFinish(int jobId){

      if(jobId <=0){
            throw new IllegalArgumentException("jodId must greater than 0!");
      }


      try{

            JenkinsServer jenkinsServer = new JenkinsServer(new URI("http://ip:port/jenkins"), "user", "pwd");

            Map<String, Job> jobs = jenkinsServer.getJobs();

            JobWithDetails job = jobs.get("FastTest").details();

            boolean isBuilding = job.getBuildByNumber(jobId).details().isBuilding();

            return !isBuilding;

      } catch (Exception e){
            e.printStackTrace();
      } finally{

      }

      return false;
    }
model层执行用例返回数据:RunInfo.javapackage com.weibo.qa.fasttestapi.model;

/**
* 执行用例接口返回的数据
* Created by hugang on 16/9/19.
*/
public class RunInfo {
    private boolean result;
    private int jobId;


    public boolean isResult() {
      return result;
    }

    public void setResult(boolean result) {
      this.result = result;
    }

    public int getJobId() {
      return jobId;
    }

    public void setJobId(int jobId) {
      this.jobId = jobId;
    }
}
查看jobId对应的任务是否结束:FinishInfo.java

package com.weibo.qa.fasttestapi.model;

/**
* 查看执行用例是否结束
* Created by hugang on 16/9/19.
*/
public class FinishInfo {
    private boolean finished;

    public boolean isFinished() {
      return finished;
    }

    public void setFinished(boolean finished) {
      this.finished = finished;
    }
}

Miss_love 发表于 2019-4-11 08:38:07

:handshake

ITgiant 发表于 2019-4-16 10:22:54

:)

Miss_love 发表于 2020-12-30 16:41:30

支持分享
页: [1]
查看完整版本: Jenkins RESTful API 定制化