在 Groovy 中循环执行 HTTP Post (Jenkins)

Execute HTTP Post in a loop in Groovy (Jenkins)

我正在 Jenkins 中开发一个共享库,以帮助与内部 API 进行交互。我可以进行一次调用,启动一个漫长的 运行ning 过程来创建一个对象。我必须继续查询 API 以检查进程是否完成。

我正在尝试使用一个简单的循环来完成这项工作,但我总是卡住。这是我查询 API 直到完成的函数:

def url = new URL("http://myapi/endpoint")
HttpURLConnection = http = (HttpURLConnection) url.openConnection()
http.setDoOutput(true)
http.setRequestMethod('POST')
http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded")
def body = ["string", "anotherstring"].join('=')
OutputStreamWriter osw = new OutputStreamWriter(http.outStream)
osw.write(body)
osw.flush()
osw.close()
for(int i = 0; i < 30; i++) {
    Integer counter = 0
    http.connect()
    response = http.content.text
    def status = new JsonSlurperClassic().parseText(response)
    // Code to check values here
}

当我 运行 通过管道执行此操作时,循环的第一次迭代工作正常。下一次迭代出现此错误:

Caused: java.io.NotSerializableException: sun.net.www.protocol.http.HttpURLConnection

我刚从 Groovy 开始,所以我觉得我在尝试做错这件事。我到处寻找答案并尝试了几件事,但都没有成功。

提前致谢。

当 运行 管道作业时,Jenkins 将不断保存执行状态,以便可以暂停并稍后恢复,这意味着 Jenkins 必须能够序列化脚本的状态,因此您在管道中创建的所有对象都必须是可序列化的。
如果对象不可序列化,只要 Jenkins 在保存状态时尝试序列化不可序列化的对象,您就会得到 NotSerializableException

要解决此问题,您可以使用 @NonCPS 注释,这将导致 Jenkins 执行该函数而不尝试对其进行序列化。在 pipeline-best-practice.

阅读有关此问题的更多信息

While normal Pipeline is restricted to serializable local variables (see appendix at bottom), @NonCPS functions can use more complex, nonserializable types internally (for example regex matchers, etc). Parameters and return types should still be Serializable, however.

但是存在一些限制,因此请仔细阅读文档,例如来自@NonCPS 方法的 return 值类型必须是可序列化的,并且您不能在 @NonCPS 中使用任何管道步骤或 CPS 转换方法注释函数。 Additional info can be found here.

最后一件事,要克服所有这些问题,您还可以使用 Jenkins HTTP Plugin,它包含您可能需要的所有 HTTP 功能,都封装在易于使用的内置界面中。