web-dev-qa-db-fra.com

Comment appeler REST du flux de travail Jenkins

Je me demande comment appeler l'API REST à partir d'un script de flux de travail Jenkins (groovy). Je peux exécuter "sh 'curl -X POST ..." - cela fonctionne, mais la construction de la requête sous forme de commande curl est fastidieuse et le traitement de la réponse se complique. Je préférerais qu'un client HTTP Groovy natif programme en groovy - par lequel devrais-je commencer? Comme le script est exécuté dans Jenkins, il est nécessaire de copier tous les fichiers de dépendance nécessaires dans l’installation groovy de Jenkins. Un objet léger serait donc apprécié.

17
Assen Kolov

Il existe une étape intégrée disponible qui utilise Jenkins HTTP Request Plugin pour effectuer des demandes http.

Plugin: https://wiki.jenkins-ci.org/display/JENKINS/HTTP+Request+Plugin

Documentation détaillée: https://jenkins.io/doc/pipeline/steps/http_request/#httprequest-perform-an-http-request-and-return-a-response-object

Exemple tiré de la page du plugin github:

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

J'ai eu du mal à installer la bibliothèque HTTPBuilder. J'ai donc utilisé la classe d'URL plus élémentaire pour créer un 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    
    }       
}

Et puis je peux faire un GET avec quelque chose comme: HttpResponse resp = doGetHttpRequest("http://some.url");

Et un PUT avec des données JSON utilisant quelque chose comme: HttpResponse resp = this.doPutHttpRequestWithJson("{\"propA\":\"foo\"}", "http://some.url");

10
Jesse S

Native Groovy Code sans importer aucun package:

// 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());
}
9
Jim Perris

Bloquer le thread principal sur les appels d'E/S n'est pas une bonne idée. 

La délégation de l'opération d'E/S à une étape du shell est actuellement recommandée. 

L’autre façon, qui nécessite un développement, est d’ajouter une nouvelle étape. A propos, il y a une initiative pour ajouter un ensemble commun d'étapes à utiliser en toute sécurité dans le script de pipeline, bien qu'un client REST complet ait son propre plugin.

1
amuniz

Avez-vous essayé la classe HTTPBuilder de Groovy? Par exemple:

@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"

    }
}
0
pczeus