Groovy 如何从jenkins工作流调用REST

Groovy 如何从jenkins工作流调用REST,groovy,jenkins-workflow,Groovy,Jenkins Workflow,我想知道如何从(groovy)Jenkins工作流脚本调用RESTAPI。我可以执行“sh'curl-X POST…”——它可以工作,但是将请求构建为curl命令很麻烦,而且处理响应也很复杂。我更喜欢原生Groovy HTTP客户机,而不是用Groovy编程——我应该从哪一个开始?由于脚本是在Jenkins中运行的,因此需要将所有需要的依赖项jar复制到Jenkins上的groovy安装中,因此需要一些轻量级的东西。您尝试过groovy的HTTPBuilder类吗? 例如: @Grapes(

我想知道如何从(groovy)Jenkins工作流脚本调用RESTAPI。我可以执行“sh'curl-X POST…”——它可以工作,但是将请求构建为curl命令很麻烦,而且处理响应也很复杂。我更喜欢原生Groovy HTTP客户机,而不是用Groovy编程——我应该从哪一个开始?由于脚本是在Jenkins中运行的,因此需要将所有需要的依赖项jar复制到Jenkins上的groovy安装中,因此需要一些轻量级的东西。

您尝试过groovy的HTTPBuilder类吗? 例如:

@Grapes(
    @Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.7.1')
)

import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.ContentType.*
import static groovyx.net.http.Method.*

def http = new HTTPBuilder("http://api.geonames.org/citiesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&lang=de&username=demo")

http.request(POST, JSON ) { req ->
    body = []
    response.success = { resp, reader ->
        println "$resp.statusLine   Respond rec"

    }
}

在I/O调用上阻塞主线程不是一个好主意

目前推荐的方法是将I/O操作委派给shell步骤


另一种需要发展的方式是增加新的步骤。顺便说一句,虽然完整的REST客户端有自己的插件,但需要在管道脚本中添加一组安全使用的通用步骤。

我在安装HTTPBuilder库时遇到了问题,因此我最终使用了更基本的URL类来创建HttpUrlConnection

HttpResponse doGetHttpRequest(String requestUrl){    
    URL url = new URL(requestUrl);    
    HttpURLConnection connection = url.openConnection();    

    connection.setRequestMethod("GET");    

    //get the request    
    connection.connect();    

    //parse the response    
    HttpResponse resp = new HttpResponse(connection);    

    if(resp.isFailure()){    
        error("\nGET from URL: $requestUrl\n  HTTP Status: $resp.statusCode\n  Message: $resp.message\n  Response Body: $resp.body");    
    }    

    this.printDebug("Request (GET):\n  URL: $requestUrl");    
    this.printDebug("Response:\n  HTTP Status: $resp.statusCode\n  Message: $resp.message\n  Response Body: $resp.body");    

    return resp;    
}  

/**    
 * Posts the json content to the given url and ensures a 200 or 201 status on the response.    
 * If a negative status is returned, an error will be raised and the pipeline will fail.    
 */    
HttpResponse doPostHttpRequestWithJson(String json, String requestUrl){    
    return doHttpRequestWithJson(json, requestUrl, "POST");    
}    

/**    
 * Posts the json content to the given url and ensures a 200 or 201 status on the response.    
 * If a negative status is returned, an error will be raised and the pipeline will fail.    
 */    
HttpResponse doPutHttpRequestWithJson(String json, String requestUrl){    
    return doHttpRequestWithJson(json, requestUrl, "PUT");    
}

/**    
 * Post/Put the json content to the given url and ensures a 200 or 201 status on the response.    
 * If a negative status is returned, an error will be raised and the pipeline will fail.    
 * verb - PUT or POST    
 */    
HttpResponse doHttpRequestWithJson(String json, String requestUrl, String verb){    
    URL url = new URL(requestUrl);    
    HttpURLConnection connection = url.openConnection();    

    connection.setRequestMethod(verb);    
    connection.setRequestProperty("Content-Type", "application/json");    
    connection.doOutput = true;    

    //write the payload to the body of the request    
    def writer = new OutputStreamWriter(connection.outputStream);    
    writer.write(json);    
    writer.flush();    
    writer.close();    

    //post the request    
    connection.connect();    

    //parse the response    
    HttpResponse resp = new HttpResponse(connection);    

    if(resp.isFailure()){    
        error("\n$verb to URL: $requestUrl\n    JSON: $json\n    HTTP Status: $resp.statusCode\n    Message: $resp.message\n    Response Body: $resp.body");    
    }    

    this.printDebug("Request ($verb):\n  URL: $requestUrl\n  JSON: $json");    
    this.printDebug("Response:\n  HTTP Status: $resp.statusCode\n  Message: $resp.message\n  Response Body: $resp.body");    

    return resp;    
}  

class HttpResponse {    

    String body;    
    String message;    
    Integer statusCode;    
    boolean failure = false;    

    public HttpResponse(HttpURLConnection connection){    
        this.statusCode = connection.responseCode;    
        this.message = connection.responseMessage;    

        if(statusCode == 200 || statusCode == 201){    
            this.body = connection.content.text;//this would fail the pipeline if there was a 400    
        }else{    
            this.failure = true;    
            this.body = connection.getErrorStream().text;    
        }    

        connection = null; //set connection to null for good measure, since we are done with it    
    }       
}
然后我可以做一些类似的事情:
HttpResponse resp=doGetHttpRequest(“http://some.url");

以及一个包含JSON数据的PUT,使用如下内容:
HttpResponse resp=this.doputtprequestwithjson(“{\'propA\':\'foo\'},”http://some.url");

有一个内置步骤可用,即使用Jenkins HTTP请求插件进行HTTP请求

插件:

步骤文档:

插件github页面中的示例:

def response = httpRequest "http://httpbin.org/response-headers?param1=${param1}"
println('Status: '+response.status)
println('Response: '+response.content)

不导入任何包的本机Groovy代码:

// GET
def get = new URL("https://httpbin.org/get").openConnection();
def getRC = get.getResponseCode();
println(getRC);
if(getRC.equals(200)) {
    println(get.getInputStream().getText());
}


// POST
def post = new URL("https://httpbin.org/post").openConnection();
def message = '{"message":"this is a message"}'
post.setRequestMethod("POST")
post.setDoOutput(true)
post.setRequestProperty("Content-Type", "application/json")
post.getOutputStream().write(message.getBytes("UTF-8"));
def postRC = post.getResponseCode();
println(postRC);
if(postRC.equals(200)) {
    println(post.getInputStream().getText());
}


根据OP的要求,您能否详细介绍一下如何将HTTPBuilder库安装到Jenkins中?默认情况下,它似乎不可用。我已更新了示例,以显示如何使用Grapes Grab来提取依赖的HttpBuilder库,而无需在Jenkins类路径中包含其他步骤。我终于开始测试它,但不幸的是,它失败了,错误在这里:我与S.Richmond有相同的问题使用org.apache.ivy@pczeus,你有办法解决这个问题吗?我自己也遇到了这个问题(常春藤的问题)。我相信当我清除.grapes缓存并在IntelliJ中进行重建项目时,问题已经解决了,但我不确定。不管怎样,这里有两个链接可能会有所帮助:您是否找到了如何将HTTPBuilder安装到Jenkins?S.Richmond中,将所有缺少的JAR复制到Groovy libs文件夹(如问题中所述)是可行的,但这使得Jenkins服务器的配置过于复杂。我想我还是坚持使用curl。你能告诉我jenkins安装中的文件夹在哪里吗?我在docker映像中运行jenkins,在那里我用skdman安装了groovy。lib文件夹是var/jenkins_home/.sdkman/candidates/groovy/2.4.6/lib。谢谢你,这可能是最好的选择。我对你的答案投了赞成票,一旦我有时间测试它,我就会接受。谢谢,这太棒了。我需要添加基本身份验证:
def auth_token=“user:github_token”;def basic_auth=“basic${auth_token.bytes.encodeBase64().toString()}”;setRequestProperty(“授权”,基本身份验证)是否支持https?如果是,如何配置证书@raitisd@Van,我假设您不需要在Jenkins端配置任何东西。您只需在url中使用https即可。并且您调用的资源必须设置ssl。您可以忽略带有“IgnoreSlerRors:true”的证书问题@fochhow使用
IgnoreSlerRors:true
?语法是什么?有没有处理响应头的方法?我最后使用它作为
HTTP请求
插件开始挂在我们的Windows Jenkins实例上。谢谢openConnection()可能会引入安全漏洞,因此jenkins建议禁止该漏洞。如果允许,这将为其他第三方插件打开此方法调用,并可能使其更易受攻击。是否有方法处理响应标题?
getHeaderFields()