io.fabric8.maven.docker.wait.HttpPingChecker Maven / Gradle / Ivy
package io.fabric8.maven.docker.wait;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.fabric8.maven.docker.util.Logger;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustAllStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.ssl.SSLContextBuilder;
import io.fabric8.maven.docker.config.WaitConfiguration;
/**
* Check whether a given URL is available
*
*/
public class HttpPingChecker implements WaitChecker {
private int statusMin;
private int statusMax;
private String url;
private String method;
private boolean allowAllHosts;
private final Logger log;
// Disable HTTP client retries by default.
private static final int HTTP_CLIENT_RETRIES = 0;
// Timeout for pings
private static final int HTTP_PING_TIMEOUT = 500;
/**
* Ping the given URL
*
* @param url URL to check
* @param method HTTP method to use
* @param status status code to check
*/
public HttpPingChecker(String url, String method, String status, Logger log) {
this.url = url;
this.method = method;
this.log = log;
Matcher matcher = Pattern.compile("^(\\d+)\\s*\\.\\.+\\s*(\\d+)$").matcher(status);
if (matcher.matches()) {
statusMin = Integer.parseInt(matcher.group(1));
statusMax = Integer.parseInt(matcher.group(2));
} else {
statusMin = statusMax = Integer.parseInt(status);
}
}
public HttpPingChecker(String waitUrl, final Logger log) {
this(waitUrl, WaitConfiguration.DEFAULT_HTTP_METHOD, WaitConfiguration.DEFAULT_STATUS_RANGE, log);
}
public HttpPingChecker(String url, String method, String status, boolean allowAllHosts, final Logger log) {
this(url, method, status, log);
this.allowAllHosts = allowAllHosts;
}
@Override
public boolean check() {
try {
return ping();
} catch (IOException exception) {
// Could occur and then the check is always considered as failed
log.debug("Check failed due to %s: %s", exception.getMessage(), exception);
return false;
}
}
private boolean ping() throws IOException {
RequestConfig requestConfig =
RequestConfig.custom()
.setSocketTimeout(HTTP_PING_TIMEOUT)
.setConnectTimeout(HTTP_PING_TIMEOUT)
.setConnectionRequestTimeout(HTTP_PING_TIMEOUT)
.setRedirectsEnabled(false)
.build();
CloseableHttpClient httpClient;
if (allowAllHosts) {
SSLContextBuilder builder = new SSLContextBuilder();
try {
builder.loadTrustMaterial(new TrustAllStrategy());
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(builder.build(), NoopHostnameVerifier.INSTANCE);
httpClient = HttpClientBuilder.create()
.setDefaultRequestConfig(requestConfig)
.setRetryHandler(new DefaultHttpRequestRetryHandler(HTTP_CLIENT_RETRIES, false))
.setSSLSocketFactory(socketFactory)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.build();
} catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException e) {
throw new IOException("Unable to set self signed strategy on http wait: " + e, e);
}
} else {
httpClient = HttpClientBuilder.create()
.setDefaultRequestConfig(requestConfig)
.setRetryHandler(new DefaultHttpRequestRetryHandler(HTTP_CLIENT_RETRIES, false))
.build();
}
log.debug("Checking %s %s", method.toUpperCase(), url);
try (CloseableHttpResponse response = httpClient.execute(RequestBuilder.create(method.toUpperCase()).setUri(url).build())) {
int responseCode = response.getStatusLine().getStatusCode();
if (responseCode == HttpURLConnection.HTTP_NOT_IMPLEMENTED) {
throw new IllegalArgumentException("Invalid or not supported HTTP method '" + method.toUpperCase() + "' for checking " + url);
}
log.debug("%s %s returned %s",method.toUpperCase(), url, responseCode);
return responseCode >= statusMin && responseCode <= statusMax;
} finally {
httpClient.close();
}
}
@Override
public void cleanUp() {
// No cleanup required for this checker
}
@Override
public String getLogLabel() {
return "on url " + url;
}
}