Support connections using core JDK facilities.

This commit is contained in:
Scott Frederick
2017-06-01 16:28:53 -05:00
parent c3f8efbb92
commit 3a7e1b548d
5 changed files with 76 additions and 41 deletions

View File

@@ -19,6 +19,8 @@ package org.springframework.credhub.configuration;
import java.io.IOException;
import java.security.GeneralSecurityException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
@@ -26,9 +28,12 @@ import org.apache.http.impl.client.HttpClients;
import org.springframework.credhub.support.ClientOptions;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import javax.net.ssl.SSLContext;
/**
* Factory for {@link ClientHttpRequestFactory} that supports Apache HTTP Components,
* OkHttp, Netty and the JDK HTTP client (in that order). This factory configures a
@@ -38,6 +43,7 @@ import org.springframework.util.ClassUtils;
* @author Scott Frederick
*/
public class ClientHttpRequestFactoryFactory {
private static final Log logger = LogFactory.getLog(ClientHttpRequestFactoryFactory.class);
private static final boolean HTTP_COMPONENTS_PRESENT = ClassUtils.isPresent(
"org.apache.http.client.HttpClient",
@@ -56,36 +62,58 @@ public class ClientHttpRequestFactoryFactory {
try {
if (HTTP_COMPONENTS_PRESENT) {
logger.info("Using Apache HttpComponents HttpClient for HTTP connections");
return HttpComponents.usingHttpComponents(options);
}
}
catch (GeneralSecurityException e) {
throw new IllegalStateException(e);
}
catch (IOException e) {
throw new IllegalStateException(e);
catch (Exception e) {
logger.warn("Exception caught while configuring HTTP connections", e);
}
throw new IllegalStateException("Only Apache HTTP Components is supported.");
logger.info("Defaulting to java.net.HttpUrlConnection for HTTP connections");
return HttpURLConnection.usingJdk(options);
}
/**
* {@link ClientHttpRequestFactory} for Apache HttpComponents.
* {@link ClientHttpRequestFactory} using {@link java.net.HttpURLConnection}.
*/
static class HttpURLConnection {
static ClientHttpRequestFactory usingJdk(ClientOptions options) {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
if (options.getConnectionTimeout() != null) {
factory.setConnectTimeout(options.getConnectionTimeout());
}
if (options.getReadTimeout() != null) {
factory.setReadTimeout(options.getReadTimeout());
}
return factory;
}
}
/**
* {@link ClientHttpRequestFactory} using Apache HttpComponents.
*/
static class HttpComponents {
static ClientHttpRequestFactory usingHttpComponents(ClientOptions options)
throws GeneralSecurityException, IOException {
HttpClientBuilder httpClientBuilder = HttpClients.custom();
HttpClientBuilder httpClientBuilder = HttpClients.custom()
.setSSLContext(SSLContext.getDefault())
.useSystemProperties();
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(options.getConnectionTimeout())
.setSocketTimeout(options.getReadTimeout())
.setAuthenticationEnabled(true)
.build();
RequestConfig.Builder requestConfigBuilder = RequestConfig.custom()
.setAuthenticationEnabled(true);
httpClientBuilder.setDefaultRequestConfig(requestConfig);
if (options.getConnectionTimeout() != null) {
requestConfigBuilder.setConnectTimeout(options.getConnectionTimeout());
}
if (options.getReadTimeout() != null) {
requestConfigBuilder.setSocketTimeout(options.getReadTimeout());
}
httpClientBuilder.setDefaultRequestConfig(requestConfigBuilder.build());
return new HttpComponentsClientHttpRequestFactory(httpClientBuilder.build());
}

View File

@@ -29,20 +29,19 @@ public class ClientOptions {
/**
* Connection timeout;
*/
private final int connectionTimeout;
private final Integer connectionTimeout;
/**
* Read timeout;
*/
private final int readTimeout;
private final Integer readTimeout;
/**
* Create new {@link ClientOptions} with default timeouts of {@literal 5}
* {@link TimeUnit#SECONDS} connection timeout and {@literal 15}
* {@link TimeUnit#SECONDS} read timeout.
* Create new {@link ClientOptions} with default timeouts.
*/
public ClientOptions() {
this((int) TimeUnit.SECONDS.toMillis(5), (int) TimeUnit.SECONDS.toMillis(15));
this.connectionTimeout = null;
this.readTimeout = null;
}
/**
@@ -59,20 +58,20 @@ public class ClientOptions {
}
/**
* Gets the connection timeout in {@link TimeUnit#MILLISECONDS}.
* Get the connection timeout in {@link TimeUnit#MILLISECONDS}.
*
* @return the connection timeout
* @return the connection timeout; can be {@literal null if not explicitly set}
*/
public int getConnectionTimeout() {
public Integer getConnectionTimeout() {
return connectionTimeout;
}
/**
* Gets the read timeout in {@link TimeUnit#MILLISECONDS}
* Get the read timeout in {@link TimeUnit#MILLISECONDS}.
*
* @return the read timeout
* @return the read timeout; can be {@literal null if not explicitly set}
*/
public int getReadTimeout() {
public Integer getReadTimeout() {
return readTimeout;
}

View File

@@ -24,13 +24,22 @@ import org.springframework.beans.factory.DisposableBean;
import org.springframework.credhub.support.ClientOptions;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertThat;
import static org.springframework.credhub.configuration.ClientHttpRequestFactoryFactory.HttpComponents.usingHttpComponents;
import static org.springframework.credhub.configuration.ClientHttpRequestFactoryFactory.HttpURLConnection.usingJdk;
public class ClientHttpRequestFactoryFactoryTests {
@Test
public void jdkDefaultClientCreated() throws Exception {
ClientHttpRequestFactory factory = usingJdk(new ClientOptions());
assertThat(factory, instanceOf(SimpleClientHttpRequestFactory.class));
}
@Test
public void httpComponentsClientCreated() throws Exception {
@@ -38,8 +47,7 @@ public class ClientHttpRequestFactoryFactoryTests {
assertThat(factory, instanceOf(HttpComponentsClientHttpRequestFactory.class));
HttpClient httpClient = ((HttpComponentsClientHttpRequestFactory) factory)
.getHttpClient();
HttpClient httpClient = ((HttpComponentsClientHttpRequestFactory) factory).getHttpClient();
assertThat(httpClient, instanceOf(CloseableHttpClient.class));

View File

@@ -52,10 +52,6 @@
<artifactId>spring-credhub-core</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>

View File

@@ -56,20 +56,24 @@ public class CredHubDemoController {
public Results runTests(@RequestBody Map<String, Object> value) {
Results results = new Results();
CredentialDetails<JsonCredential> credentialDetails = writeCredentials(value, results);
CredentialName credentialName = credentialDetails.getName();
try {
CredentialDetails<JsonCredential> credentialDetails = writeCredentials(value, results);
CredentialName credentialName = credentialDetails.getName();
getCredentialsById(credentialDetails.getId(), results);
getCredentialsById(credentialDetails.getId(), results);
getCredentialsByName(credentialName, results);
getCredentialsByName(credentialName, results);
findCredentialsByName(credentialName, results);
findCredentialsByName(credentialName, results);
findCredentialsByPath(credentialName.getName(), results);
findCredentialsByPath(credentialName.getName(), results);
interpolateServiceData(credentialName, results);
interpolateServiceData(credentialName, results);
deleteCredentials(credentialName, results);
deleteCredentials(credentialName, results);
} catch (Exception e) {
saveResults(results, "Exception caught: " + e.getMessage());
}
return results;
}