You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by su...@apache.org on 2017/01/11 20:03:53 UTC
knox git commit: KNOX-805 ability to define custom HttpClient
(Vincent Devillers via Sumit Gupta)
Repository: knox
Updated Branches:
refs/heads/master 7458fa670 -> e2e39f3fa
KNOX-805 ability to define custom HttpClient (Vincent Devillers via Sumit Gupta)
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/e2e39f3f
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/e2e39f3f
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/e2e39f3f
Branch: refs/heads/master
Commit: e2e39f3faa2f75ac632c425fe916bfed1c6bcc0d
Parents: 7458fa6
Author: Sumit Gupta <su...@apache.org>
Authored: Wed Jan 11 14:55:54 2017 -0500
Committer: Sumit Gupta <su...@apache.org>
Committed: Wed Jan 11 15:03:47 2017 -0500
----------------------------------------------------------------------
gateway-shell/pom.xml | 5 +
.../hadoop/gateway/shell/ClientContext.java | 206 +++++++++++++++++++
.../org/apache/hadoop/gateway/shell/Hadoop.java | 158 +++++++-------
3 files changed, 298 insertions(+), 71 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/e2e39f3f/gateway-shell/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-shell/pom.xml b/gateway-shell/pom.xml
index a698eed..a6f1ea2 100644
--- a/gateway-shell/pom.xml
+++ b/gateway-shell/pom.xml
@@ -76,6 +76,11 @@
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
+ <dependency>
+ <groupId>commons-configuration</groupId>
+ <artifactId>commons-configuration</artifactId>
+ <version>1.6</version>
+ </dependency>
<dependency>
<groupId>junit</groupId>
http://git-wip-us.apache.org/repos/asf/knox/blob/e2e39f3f/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/ClientContext.java
----------------------------------------------------------------------
diff --git a/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/ClientContext.java b/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/ClientContext.java
new file mode 100644
index 0000000..6055f68
--- /dev/null
+++ b/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/ClientContext.java
@@ -0,0 +1,206 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.hadoop.gateway.shell;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.MapConfiguration;
+import org.apache.commons.configuration.SubsetConfiguration;
+
+import java.util.HashMap;
+
+public class ClientContext {
+
+ private final Configuration configuration;
+ private final PoolContext poolContext;
+ private final SocketContext socketContext;
+ private final ConnectionContext connectionContext;
+
+ private ClientContext() {
+ configuration = new MapConfiguration(new HashMap<>());
+ poolContext = new PoolContext(this);
+ socketContext = new SocketContext(this);
+ connectionContext = new ConnectionContext(this);
+ }
+
+ private static class Context {
+ private final ClientContext clientContext;
+ protected final Configuration configuration;
+
+ private Context(ClientContext clientContext, String prefix) {
+ this.clientContext = clientContext;
+ this.configuration = new SubsetConfiguration(clientContext.configuration, prefix);
+ }
+
+ public ClientContext end() {
+ return clientContext;
+ }
+ }
+
+ public static class PoolContext extends Context {
+
+ private PoolContext(ClientContext clientContext) {
+ super(clientContext, "pool");
+ }
+
+ public int maxTotal() {
+ return configuration.getInt("total", 20);
+ }
+
+ public PoolContext maxTotal(final int timeout) {
+ configuration.addProperty("total", timeout);
+ return this;
+ }
+
+ public int defaultMaxPerRoute() {
+ return configuration.getInt("max-per-route", 20);
+ }
+
+ public PoolContext defaultMaxPerRoute(final int reuseaddr) {
+ configuration.addProperty("max-per-route", reuseaddr);
+ return this;
+ }
+ }
+
+ public static class SocketContext extends Context {
+
+ private SocketContext(ClientContext clientContext) {
+ super(clientContext, "socket");
+ }
+
+ public int timeout() {
+ return configuration.getInt("timeout", 0);
+ }
+
+ public SocketContext timeout(final int timeout) {
+ configuration.addProperty("timeout", timeout);
+ return this;
+ }
+
+ public boolean reuseAddress() {
+ return configuration.getBoolean("reuse-address", false);
+ }
+
+ public SocketContext reuseAddress(final boolean reuseAddress) {
+ configuration.addProperty("reuse-address", reuseAddress);
+ return this;
+ }
+
+ public int linger() {
+ return configuration.getInt("linger", -1);
+ }
+
+ public SocketContext linger(final int value) {
+ configuration.addProperty("linger", value);
+ return this;
+ }
+
+ public boolean keepalive() {
+ return configuration.getBoolean("keepalive", false);
+ }
+
+ public SocketContext keepalive(final boolean enableKeepalive) {
+ configuration.addProperty("keepalive", enableKeepalive);
+ return this;
+ }
+
+ public boolean tcpNoDelay() {
+ return configuration.getBoolean("nodelay", true);
+ }
+
+ public SocketContext tcpNoDelay(final boolean value) {
+ configuration.addProperty("nodelay", value);
+ return this;
+ }
+ }
+
+ public static class ConnectionContext extends Context {
+
+ private ConnectionContext(ClientContext clientContext) {
+ super(clientContext, "connection");
+ }
+
+ public int timeout() {
+ return configuration.getInt("timeout", 0);
+ }
+
+ public ConnectionContext timeout(final int timeout) {
+ configuration.addProperty("timeout", timeout);
+ return this;
+ }
+
+ public boolean staleChecking() {
+ return configuration.getBoolean("stalecheck", true);
+ }
+
+ public ConnectionContext staleChecking(final boolean value) {
+ configuration.addProperty("stalecheck", value);
+ return this;
+ }
+
+ public boolean secure() {
+ return configuration.getBoolean("secure", true);
+ }
+
+ public ConnectionContext secure(final boolean value) {
+ configuration.addProperty("secure", value);
+ return this;
+ }
+
+ public int bufferSize() {
+ return configuration.getInt("buffer-size", -1);
+ }
+
+ public ConnectionContext bufferSize(final int size) {
+ configuration.addProperty("buffer-size", size);
+ return this;
+ }
+ }
+
+ public PoolContext pool() {
+ return poolContext;
+ }
+
+ public SocketContext socket() {
+ return socketContext;
+ }
+
+ public ConnectionContext connection() {
+ return connectionContext;
+ }
+
+ public static ClientContext with(final String username, final String password, final String url) {
+ ClientContext context = new ClientContext();
+ context.configuration.addProperty("username", username);
+ context.configuration.addProperty("password", password);
+ context.configuration.addProperty("url", url);
+ return context;
+ }
+
+ public String username() {
+ return configuration.getString("username");
+ }
+
+ public String password() {
+ return configuration.getString("password");
+ }
+
+ public String url() {
+ return configuration.getString("url");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/e2e39f3f/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/Hadoop.java
----------------------------------------------------------------------
diff --git a/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/Hadoop.java b/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/Hadoop.java
index 6bfc407..651b061 100644
--- a/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/Hadoop.java
+++ b/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/Hadoop.java
@@ -24,19 +24,28 @@ import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
-import org.apache.http.client.protocol.ClientContext;
-import org.apache.http.conn.scheme.PlainSocketFactory;
-import org.apache.http.conn.scheme.Scheme;
-import org.apache.http.conn.scheme.SchemeRegistry;
-import org.apache.http.conn.ssl.SSLContextBuilder;
-import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.config.ConnectionConfig;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.config.SocketConfig;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
+import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.impl.conn.PoolingClientConnectionManager;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.ssl.SSLContexts;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -57,8 +66,6 @@ import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
-import javax.net.ssl.SSLContext;
-
public class Hadoop {
private static final String GATEWAY_CLIENT_TRUST_DEFAULT_PASS = "changeit";
@@ -69,69 +76,91 @@ public class Hadoop {
String base;
HttpHost host;
- DefaultHttpClient client;
+ CloseableHttpClient client;
BasicHttpContext context;
- String username;
- String password;
ExecutorService executor;
public static Hadoop login( String url, String username, String password ) throws URISyntaxException {
- return new Hadoop( url, username, password, true );
+ return new Hadoop(ClientContext.with(username, password, url));
}
- public static Hadoop loginInsecure( String url, String username, String password ) throws URISyntaxException {
- System.out.println("**************** WARNING ******************\n"
- + "This is an insecure client instance and may\n"
- + "leave the interactions subject to a man in\n"
- + "the middle attack. Please use the login()\n"
- + "method instead of loginInsecure() for any\n"
- + "sensitive or production usecases.\n"
- + "*******************************************");
- return new Hadoop( url, username, password );
+ public static Hadoop loginInsecure(String url, String username, String password) throws URISyntaxException {
+ return new Hadoop(ClientContext.with(username, password, url)
+ .connection().secure(false).end());
}
- private Hadoop( String url, String username, String password ) throws HadoopException, URISyntaxException {
- this(url, username, password, false);
- }
-
- private Hadoop( String url, String username, String password, boolean secure ) throws HadoopException, URISyntaxException {
+ public Hadoop( ClientContext clientContext) throws HadoopException, URISyntaxException {
this.executor = Executors.newCachedThreadPool();
- this.base = url;
- this.username = username;
- this.password = password;
-
- URI uri = new URI( url );
- host = new HttpHost( uri.getHost(), uri.getPort(), uri.getScheme() );
+ this.base = clientContext.url();
try {
- if (!secure) {
- client = createInsecureClient();
- }
- else {
- client = createClient();
- }
- client.getCredentialsProvider().setCredentials(
- new AuthScope( host.getHostName(), host.getPort() ),
- new UsernamePasswordCredentials( username, password ) );
- AuthCache authCache = new BasicAuthCache();
- BasicScheme authScheme = new BasicScheme();
- authCache.put( host, authScheme );
- context = new BasicHttpContext();
- context.setAttribute( ClientContext.AUTH_CACHE, authCache );
- } catch( GeneralSecurityException e ) {
- throw new HadoopException( "Failed to create HTTP client.", e );
+ client = createClient(clientContext);
+ } catch (GeneralSecurityException e) {
+ throw new HadoopException("Failed to create HTTP client.", e);
}
}
- private static DefaultHttpClient createClient() throws GeneralSecurityException {
- SchemeRegistry registry = new SchemeRegistry();
+ private CloseableHttpClient createClient(ClientContext clientContext) throws GeneralSecurityException {
+
+ // SSL
+ HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
+ TrustStrategy trustStrategy = TrustSelfSignedStrategy.INSTANCE;
+ if (clientContext.connection().secure()) {
+ hostnameVerifier = SSLConnectionSocketFactory.getDefaultHostnameVerifier();
+ } else {
+ System.out.println("**************** WARNING ******************\n"
+ + "This is an insecure client instance and may\n"
+ + "leave the interactions subject to a man in\n"
+ + "the middle attack. Please use the login()\n"
+ + "method instead of loginInsecure() for any\n"
+ + "sensitive or production usecases.\n"
+ + "*******************************************");
+ }
+
KeyStore trustStore = getTrustStore();
- SSLSocketFactory socketFactory = new SSLSocketFactory(trustStore);
- registry.register( new Scheme( "https", 443, socketFactory ) );
- registry.register( new Scheme( "http", 80, new PlainSocketFactory() ) );
- PoolingClientConnectionManager mgr = new PoolingClientConnectionManager( registry );
- DefaultHttpClient client = new DefaultHttpClient( mgr, new DefaultHttpClient().getParams() );
- return client;
+ SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(trustStore, trustStrategy).build();
+ Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
+ .register("http", PlainConnectionSocketFactory.getSocketFactory())
+ .register("https", new SSLConnectionSocketFactory(sslContext, hostnameVerifier)).build();
+
+ // Pool
+ PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
+ connectionManager.setMaxTotal(clientContext.pool().maxTotal());
+ connectionManager.setDefaultMaxPerRoute(clientContext.pool().defaultMaxPerRoute());
+
+ ConnectionConfig connectionConfig = ConnectionConfig.custom()
+ .setBufferSize(clientContext.connection().bufferSize())
+ .build();
+ connectionManager.setDefaultConnectionConfig(connectionConfig);
+
+ SocketConfig socketConfig = SocketConfig.custom()
+ .setSoKeepAlive(clientContext.socket().keepalive())
+ .setSoLinger(clientContext.socket().linger())
+ .setSoReuseAddress(clientContext.socket().reuseAddress())
+ .setSoTimeout(clientContext.socket().timeout())
+ .setTcpNoDelay(clientContext.socket().tcpNoDelay())
+ .build();
+ connectionManager.setDefaultSocketConfig(socketConfig);
+
+ // Auth
+ URI uri = URI.create(clientContext.url());
+ host = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme());
+
+ CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+ credentialsProvider.setCredentials(
+ new AuthScope(host.getHostName(), host.getPort()),
+ new UsernamePasswordCredentials(clientContext.username(), clientContext.password()));
+
+ AuthCache authCache = new BasicAuthCache();
+ BasicScheme authScheme = new BasicScheme();
+ authCache.put(host, authScheme);
+ context = new BasicHttpContext();
+ context.setAttribute(org.apache.http.client.protocol.HttpClientContext.AUTH_CACHE, authCache);
+
+ return HttpClients.custom()
+ .setConnectionManager(connectionManager)
+ .setDefaultCredentialsProvider(credentialsProvider)
+ .build();
}
private static KeyStore getTrustStore() throws GeneralSecurityException {
@@ -197,18 +226,6 @@ public class Hadoop {
return ks;
}
- private static DefaultHttpClient createInsecureClient() throws GeneralSecurityException {
- SchemeRegistry registry = new SchemeRegistry();
- SSLSocketFactory socketFactory = new SSLSocketFactory(
- new TrustSelfSignedStrategy(),
- SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER );
- registry.register( new Scheme( "https", 443, socketFactory ) );
- registry.register( new Scheme( "http", 80, new PlainSocketFactory() ) );
- PoolingClientConnectionManager mgr = new PoolingClientConnectionManager( registry );
- DefaultHttpClient client = new DefaultHttpClient( mgr, new DefaultHttpClient().getParams() );
- return client;
- }
-
public String base() {
return base;
}
@@ -254,5 +271,4 @@ public class Hadoop {
executor.shutdown();
return executor.awaitTermination( timeout, unit );
}
-
}