HttpTask.groovy
/*
* Copyright (C) 2017 HttpBuilder-NG Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.httpbuilderng.http
import groovy.transform.CompileStatic
import groovy.transform.TupleConstructor
import groovyx.net.http.*
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.TaskAction
import java.util.function.Consumer
import static groovy.transform.TypeCheckingMode.SKIP
/**
* Gradle Task used to allow configuration and execution of HTTP requests using the HttpBuilder-NG library.
*
* The return values of the HTTP calls are not used in any manner. In order to process and handle responses, the
* <a href="https://http-builder-ng.github.io/http-builder-ng/asciidoc/html5/#_response">Response Handlers</a> should be used.
*
* All HTTP request methods supported by HttpBuilder-NG are supported, except OPTIONS and TRACE.
*/
@CompileStatic @SuppressWarnings('GroovyUnusedDeclaration')
class HttpTask extends DefaultTask {
private Object config
private final List<RequestConfig> requests = []
/**
* Used to provide the client configuration for the task. This is required if the global configuration is not specified in the <code>http</code>
* extension configuration.
*
* The configuration itself is based on the <code>HttpObjectConfig</code> from HttpBuilder-NG.
*
* @param closure the configuration closure
*/
@Input void config(@DelegatesTo(HttpObjectConfig) final Closure closure) {
config = closure
}
/**
* Used to provide the client configuration for the task. This is required if the global configuration is not specified in the <code>http</code>
* extension configuration.
*
* The configuration itself is based on the <code>HttpObjectConfig</code> from HttpBuilder-NG.
*
* @param consumer the configuration consumer
*/
@Input void config(final Consumer<HttpObjectConfig> consumer) {
config = consumer
}
@Input void get(@DelegatesTo(HttpConfig) final Closure conf) {
addRequestConfig 'get', conf
}
@Input void getAsync(@DelegatesTo(HttpConfig) final Closure conf) {
addRequestConfig 'getAsync', conf
}
@Input void get(final Consumer<HttpConfig> conf) {
addRequestConfig 'get', conf
}
@Input void getAsync(final Consumer<HttpConfig> conf) {
addRequestConfig 'getAsync', conf
}
@Input void head(@DelegatesTo(HttpConfig) final Closure conf) {
addRequestConfig 'head', conf
}
@Input void headAsync(@DelegatesTo(HttpConfig) final Closure conf) {
addRequestConfig 'headAsync', conf
}
@Input void head(final Consumer<HttpConfig> conf) {
addRequestConfig 'head', conf
}
@Input void headAsync(final Consumer<HttpConfig> conf) {
addRequestConfig 'headAsync', conf
}
@Input void put(@DelegatesTo(HttpConfig) final Closure conf) {
addRequestConfig 'put', conf
}
@Input void putAsync(@DelegatesTo(HttpConfig) final Closure conf) {
addRequestConfig 'putAsync', conf
}
@Input void put(final Consumer<HttpConfig> conf) {
addRequestConfig 'put', conf
}
@Input void putAsync(final Consumer<HttpConfig> conf) {
addRequestConfig 'putAsync', conf
}
@Input void post(@DelegatesTo(HttpConfig) final Closure conf) {
addRequestConfig 'post', conf
}
@Input void postAsync(@DelegatesTo(HttpConfig) final Closure conf) {
addRequestConfig 'postAsync', conf
}
@Input void post(final Consumer<HttpConfig> conf) {
addRequestConfig 'post', conf
}
@Input void postAsync(final Consumer<HttpConfig> conf) {
addRequestConfig 'postAsync', conf
}
@Input void delete(@DelegatesTo(HttpConfig) final Closure conf) {
addRequestConfig 'delete', conf
}
@Input void deleteAsync(@DelegatesTo(HttpConfig) final Closure conf) {
addRequestConfig 'deleteAsync', conf
}
@Input void delete(final Consumer<HttpConfig> conf) {
addRequestConfig 'delete', conf
}
@Input void deleteAsync(final Consumer<HttpConfig> conf) {
addRequestConfig 'deleteAsync', conf
}
@Input void patch(@DelegatesTo(HttpConfig) final Closure conf) {
addRequestConfig 'patch', conf
}
@Input void patchAsync(@DelegatesTo(HttpConfig) final Closure conf) {
addRequestConfig 'patchAsync', conf
}
@Input void patch(final Consumer<HttpConfig> conf) {
addRequestConfig 'patch', conf
}
@Input void patchAsync(final Consumer<HttpConfig> conf) {
addRequestConfig 'patchAsync', conf
}
private void addRequestConfig(final String method, final Object conf) {
requests << new RequestConfig(method, conf)
}
@TaskAction void http() {
HttpExtension extension = project.extensions.findByType(HttpExtension)
HttpBuilder builder = resolveHttpBuilder(extension)
if (!requests) {
throw new IllegalArgumentException('There are no requests configured.')
}
requests.each { RequestConfig rc ->
executeRequest(builder, rc)
}
}
@CompileStatic(SKIP)
private void executeRequest(final HttpBuilder builder, final RequestConfig rc) {
builder."${rc.method}"(rc.config instanceof Closure ? rc.config as Closure : rc.config as Consumer<HttpConfig>)
}
@CompileStatic(SKIP)
private HttpBuilder resolveHttpBuilder(final HttpExtension extension) {
switch (extension.library) {
case HttpLibrary.CORE:
return JavaHttpBuilder.configure(resolveConfig(extension))
case HttpLibrary.APACHE:
return ApacheHttpBuilder.configure(resolveConfig(extension))
case HttpLibrary.OKHTTP:
return OkHttpBuilder.configure(resolveConfig(extension))
default:
throw new IllegalArgumentException("HttpLibrary (${extension.library}) is not supported.")
}
}
private Object resolveConfig(final HttpExtension extension) {
Object configObject = config ?: extension.config
if (configObject) {
return configObject
} else {
throw new IllegalArgumentException('A configuration closure or consumer must be provided either globally or by the task configuration.')
}
}
@TupleConstructor
private static class RequestConfig {
final String method
final Object config
}
}