Rest Client: add callback to customize http client settings

The callback replaces the ability to fully replace the http client instance. By doing that, one used to lose any default that the RestClient had set for the underlying http client. Given that you'd usually override one or two things only, like a couple of timeout values, the ssl factory or the default credentials providers, it is not uder friendly if by doing that users end up replacing the whole http client instance and lose any default set by us.

Original commit: elastic/x-pack-elasticsearch@03adca6f62
This commit is contained in:
javanna 2016-07-11 20:54:43 +02:00 committed by Luca Cavanna
parent 4360cccad7
commit 107ab2d71d
4 changed files with 60 additions and 21 deletions

View File

@ -5,8 +5,6 @@
*/
package org.elasticsearch.xpack.security.authc.pki;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.ResponseException;
@ -15,16 +13,16 @@ import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.network.NetworkModule;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.test.SecurityIntegTestCase;
import org.elasticsearch.test.SecuritySettingsSource;
import org.elasticsearch.transport.Transport;
import org.elasticsearch.xpack.XPackPlugin;
import org.elasticsearch.xpack.security.Security;
import org.elasticsearch.xpack.security.authc.support.SecuredString;
import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken;
import org.elasticsearch.xpack.security.transport.SSLClientAuth;
import org.elasticsearch.xpack.security.transport.netty.SecurityNettyHttpServerTransport;
import org.elasticsearch.xpack.security.transport.netty.SecurityNettyTransport;
import org.elasticsearch.test.SecurityIntegTestCase;
import org.elasticsearch.test.SecuritySettingsSource;
import org.elasticsearch.transport.Transport;
import org.elasticsearch.xpack.XPackPlugin;
import org.junit.BeforeClass;
import javax.net.ssl.SSLContext;
@ -79,8 +77,7 @@ public class PkiOptionalClientAuthTests extends SecurityIntegTestCase {
}
public void testRestClientWithoutClientCertificate() throws Exception {
CloseableHttpClient httpClient = HttpClients.custom().setSSLContext(getSSLContext()).build();
try (RestClient restClient = createRestClient(httpClient, "https")) {
try (RestClient restClient = createRestClient(new SSLContextHttpConfigCallback(getSSLContext()), "https")) {
try {
restClient.performRequest("GET", "_nodes");
fail("request should have failed");

View File

@ -6,8 +6,6 @@
package org.elasticsearch.xpack.security.authc.pki;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.Response;
@ -78,8 +76,7 @@ public class PkiWithoutClientAuthenticationTests extends SecurityIntegTestCase {
public void testThatHttpWorks() throws Exception {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
CloseableHttpClient httpClient = HttpClients.custom().setSSLContext(sc).build();
try (RestClient restClient = createRestClient(httpClient, "https")) {
try (RestClient restClient = createRestClient(new SSLContextHttpConfigCallback(sc), "https")) {
try (Response response = restClient.performRequest("GET", "/_nodes",
new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
UsernamePasswordToken.basicAuthHeaderValue(SecuritySettingsSource.DEFAULT_USER_NAME,

View File

@ -0,0 +1,31 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.security.authc.pki;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.HttpClientBuilder;
import org.elasticsearch.client.RestClient;
import javax.net.ssl.SSLContext;
class SSLContextHttpConfigCallback implements RestClient.HttpClientConfigCallback {
private final SSLContext sslContext;
SSLContextHttpConfigCallback(SSLContext sslContext) {
this.sslContext = sslContext;
}
@Override
public void customizeDefaultRequestConfig(RequestConfig.Builder requestConfigBuilder) {
}
@Override
public void customizeHttpClient(HttpClientBuilder httpClientBuilder) {
httpClientBuilder.setSSLContext(sslContext);
}
}

View File

@ -5,10 +5,10 @@
*/
package org.elasticsearch.xpack.security.transport.ssl;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicHeader;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
@ -61,8 +61,7 @@ public class SslClientAuthTests extends SecurityIntegTestCase {
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
SSLContexts.createDefault(),
NoopHostnameVerifier.INSTANCE);
try (RestClient restClient = createRestClient(HttpClients.custom().setSSLSocketFactory(socketFactory).build(), "https")) {
try (RestClient restClient = createRestClient(new SSLSocketFactoryHttpConfigCallback(socketFactory), "https")) {
restClient.performRequest("GET", "/");
fail("Expected SSLHandshakeException");
} catch (SSLHandshakeException e) {
@ -75,14 +74,10 @@ public class SslClientAuthTests extends SecurityIntegTestCase {
.put(getSSLSettingsForStore("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.jks", "testclient"))
.build();
ClientSSLService sslService = new ClientSSLService(settings, new Global(settings));
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
sslService.sslContext(),
NoopHostnameVerifier.INSTANCE);
CloseableHttpClient client = HttpClients.custom().setSSLSocketFactory(socketFactory).build();
try (RestClient restClient = createRestClient(client, "https")) {
try (RestClient restClient = createRestClient(new SSLSocketFactoryHttpConfigCallback(socketFactory), "https")) {
try (Response response = restClient.performRequest("GET", "/",
new BasicHeader("Authorization", basicAuthHeaderValue(transportClientUsername(), transportClientPassword())))) {
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
@ -115,4 +110,23 @@ public class SslClientAuthTests extends SecurityIntegTestCase {
assertGreenClusterState(client);
}
}
private static class SSLSocketFactoryHttpConfigCallback implements RestClient.HttpClientConfigCallback {
private final SSLConnectionSocketFactory sslSocketFactory;
SSLSocketFactoryHttpConfigCallback(SSLConnectionSocketFactory sslSocketFactory) {
this.sslSocketFactory = sslSocketFactory;
}
@Override
public void customizeDefaultRequestConfig(RequestConfig.Builder requestConfigBuilder) {
}
@Override
public void customizeHttpClient(HttpClientBuilder httpClientBuilder) {
httpClientBuilder.setSSLSocketFactory(sslSocketFactory);
}
}
}