knox-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pzamp...@apache.org
Subject knox git commit: KNOX-1149 - HBase High Availability Fails with Kerberos Secured Cluster
Date Thu, 24 May 2018 17:32:54 GMT
Repository: knox
Updated Branches:
  refs/heads/master a1e1b207b -> 1b053c5e1


KNOX-1149 - HBase High Availability Fails with Kerberos Secured Cluster


Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/1b053c5e
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/1b053c5e
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/1b053c5e

Branch: refs/heads/master
Commit: 1b053c5e11b6fca3e88c0ccfb4911e4c8bba5bed
Parents: a1e1b20
Author: Phil Zampino <pzampino@apache.org>
Authored: Wed May 23 09:58:39 2018 -0400
Committer: Phil Zampino <pzampino@apache.org>
Committed: Thu May 24 13:01:44 2018 -0400

----------------------------------------------------------------------
 .../provider/impl/BaseZookeeperURLManager.java  | 96 +++++++++++++++-----
 .../provider/impl/HBaseZookeeperURLManager.java | 52 +++++++----
 .../impl/HBaseZookeeperURLManagerTest.java      | 26 +++++-
 3 files changed, 131 insertions(+), 43 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/knox/blob/1b053c5e/gateway-provider-ha/src/main/java/org/apache/knox/gateway/ha/provider/impl/BaseZookeeperURLManager.java
----------------------------------------------------------------------
diff --git a/gateway-provider-ha/src/main/java/org/apache/knox/gateway/ha/provider/impl/BaseZookeeperURLManager.java
b/gateway-provider-ha/src/main/java/org/apache/knox/gateway/ha/provider/impl/BaseZookeeperURLManager.java
index 868fda8..8262f8d 100644
--- a/gateway-provider-ha/src/main/java/org/apache/knox/gateway/ha/provider/impl/BaseZookeeperURLManager.java
+++ b/gateway-provider-ha/src/main/java/org/apache/knox/gateway/ha/provider/impl/BaseZookeeperURLManager.java
@@ -17,17 +17,28 @@
  */
 package org.apache.knox.gateway.ha.provider.impl;
 
+import java.security.Principal;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.ConcurrentLinkedQueue;
 
 import org.apache.commons.io.IOUtils;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.dispatch.KnoxSpnegoAuthSchemeFactory;
 import org.apache.knox.gateway.ha.provider.HaServiceConfig;
 import org.apache.knox.gateway.ha.provider.URLManager;
 import org.apache.knox.gateway.ha.provider.impl.i18n.HaMessages;
 import org.apache.knox.gateway.i18n.messages.MessagesFactory;
+import org.apache.http.auth.AuthSchemeProvider;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.Credentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.config.AuthSchemes;
 import org.apache.http.client.config.RequestConfig;
 import org.apache.http.client.methods.HttpGet;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.impl.client.BasicCredentialsProvider;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClientBuilder;
 
@@ -46,7 +57,7 @@ public abstract class BaseZookeeperURLManager implements URLManager {
 	/**
 	 * Host Ping Timeout
 	 */
-	private static final int TIMEOUT = 2000;
+	private static final int TIMEOUT = 5000;
 
 	private String zooKeeperEnsemble;
 	private String zooKeeperNamespace;
@@ -63,11 +74,7 @@ public abstract class BaseZookeeperURLManager implements URLManager {
 		}
 		
 		String zookeeperEnsemble = config.getZookeeperEnsemble();
-		if (zookeeperEnsemble != null && zookeeperEnsemble.trim().length() > 0) {
-			return true;
-		}
-
-		return false;
+		return zookeeperEnsemble != null && (zookeeperEnsemble.trim().length() > 0);
 	}
 
 	@Override
@@ -157,45 +164,84 @@ public abstract class BaseZookeeperURLManager implements URLManager
{
 	protected List<String> validateHosts(List<String> hosts, String suffix, String
acceptHeader) {
 		List<String> result = new ArrayList<String>();
 		
-		CloseableHttpClient client = null;
+		CloseableHttpClient client = buildHttpClient();
 		
 		try {
-			// Construct a HttpClient with short term timeout
-			RequestConfig.Builder requestBuilder = RequestConfig.custom()
-					.setConnectTimeout(TIMEOUT)
-					.setSocketTimeout(TIMEOUT)
-					.setConnectionRequestTimeout(TIMEOUT);
-
-			client = HttpClientBuilder.create()
-					.setDefaultRequestConfig(requestBuilder.build())
-					.build();
-			
 			for(String host: hosts) {
 				try	{
 					HttpGet get = new HttpGet(host + suffix);
-					
+
 					if (acceptHeader != null) {
 						get.setHeader("Accept", acceptHeader);
 					}
-					
+
+					// Ping host
 					String response = client.execute(get, new StringResponseHandler());
 					
 					if (response != null) {
 						result.add(host);
 					}
-				}
-				catch (Exception ex) {
+				} catch (Exception ex) {
 					// ignore host
 				}
 			}
-		}
-		catch (Exception ex) {
+		} catch (Exception e) {
 			// Ignore errors
-		}
-		finally	{
+		} finally	{
 			IOUtils.closeQuietly(client);
 		}
 		
 		return result;
 	}
+
+	/**
+	 * Construct an Apache HttpClient with suitable timeout and authentication.
+	 * 
+	 * @return Apache HttpClient
+	 */
+	private CloseableHttpClient buildHttpClient() {
+		CloseableHttpClient client = null;
+		
+		// Construct a HttpClient with short term timeout
+		RequestConfig.Builder requestBuilder = RequestConfig.custom()
+																												.setConnectTimeout(TIMEOUT)
+																												.setSocketTimeout(TIMEOUT)
+																												.setConnectionRequestTimeout(TIMEOUT);
+
+		// If Kerberos is enabled, allow for challenge/response transparent to client
+		if (Boolean.getBoolean(GatewayConfig.HADOOP_KERBEROS_SECURED)) {
+			CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+			credentialsProvider.setCredentials(AuthScope.ANY, new NullCredentials());
+
+			Registry<AuthSchemeProvider> authSchemeRegistry =
+														RegistryBuilder.<AuthSchemeProvider>create()
+																					 .register(AuthSchemes.SPNEGO, new KnoxSpnegoAuthSchemeFactory(true))
+																					 .build();
+			
+			client = HttpClientBuilder.create()
+																.setDefaultRequestConfig(requestBuilder.build())
+																.setDefaultAuthSchemeRegistry(authSchemeRegistry)
+																.setDefaultCredentialsProvider(credentialsProvider)
+																.build();
+		} else {
+			client = HttpClientBuilder.create()
+																.setDefaultRequestConfig(requestBuilder.build())
+																.build();
+		}
+
+		return client;
+	}
+	
+	private static class NullCredentials implements Credentials {
+		@Override
+		public Principal getUserPrincipal() {
+			return null;
+		}
+
+		@Override
+		public String getPassword() {
+			return null;
+		}
+	}
+
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/1b053c5e/gateway-provider-ha/src/main/java/org/apache/knox/gateway/ha/provider/impl/HBaseZookeeperURLManager.java
----------------------------------------------------------------------
diff --git a/gateway-provider-ha/src/main/java/org/apache/knox/gateway/ha/provider/impl/HBaseZookeeperURLManager.java
b/gateway-provider-ha/src/main/java/org/apache/knox/gateway/ha/provider/impl/HBaseZookeeperURLManager.java
index d2053cd..e4ffc12 100644
--- a/gateway-provider-ha/src/main/java/org/apache/knox/gateway/ha/provider/impl/HBaseZookeeperURLManager.java
+++ b/gateway-provider-ha/src/main/java/org/apache/knox/gateway/ha/provider/impl/HBaseZookeeperURLManager.java
@@ -44,7 +44,10 @@ public class HBaseZookeeperURLManager extends BaseZookeeperURLManager {
 	 */
 	private static final int PORT_NUMBER = 8080;
 
-	private static final String DEFAULT_ZOOKEEPER_NAMESPACE = "/hbase-unsecure";
+	private static final String DEFAULT_ZOOKEEPER_NAMESPACE_SECURE = "/hbase-secure";
+
+	private static final String DEFAULT_ZOOKEEPER_NAMESPACE_UNSECURE = "/hbase-unsecure";
+
 
 	// -------------------------------------------------------------------------------------
 	// Abstract methods
@@ -59,9 +62,9 @@ public class HBaseZookeeperURLManager extends BaseZookeeperURLManager {
 	protected List<String> lookupURLs() {
 		// Retrieve list of potential hosts from ZooKeeper
 		List<String> hosts = retrieveHosts();
-		
+
 		// Validate access to hosts using cheap ping style operation
-		List<String> validatedHosts = validateHosts(hosts,"/","text/xml");
+		List<String> validatedHosts = validateHosts(hosts,"/version/rest","text/xml");
 
 		// Randomize the hosts list for simple load balancing
 		if (!validatedHosts.isEmpty()) {
@@ -77,8 +80,7 @@ public class HBaseZookeeperURLManager extends BaseZookeeperURLManager {
 
 	@Override
 	protected String getZookeeperNamespace() {
-		String ns = super.getZookeeperNamespace();
-		return (ns == null || ns.isEmpty()) ? DEFAULT_ZOOKEEPER_NAMESPACE : ns;
+		return super.getZookeeperNamespace();
 	}
 
 	// -------------------------------------------------------------------------------------
@@ -100,17 +102,33 @@ public class HBaseZookeeperURLManager extends BaseZookeeperURLManager
{
 		try {
 			zooKeeperClient.start();
 
+			List<String> serverNodes = null;
+
 			String namespace = getZookeeperNamespace();
-			if (!namespace.startsWith("/")) {
-				namespace = "/" + namespace;
+			if (namespace != null && !namespace.isEmpty()) {
+			 	if (!namespace.startsWith("/")) {
+					namespace = "/" + namespace;
+				}
+				serverNodes = zooKeeperClient.getChildren().forPath(namespace + "/rs");
+			} else {
+				// If no namespace is explicitly specified, try the default secure namespace
+				try {
+					serverNodes = zooKeeperClient.getChildren().forPath(DEFAULT_ZOOKEEPER_NAMESPACE_SECURE
+ "/rs");
+				} catch (Exception e) {
+					// Ignore -- znode may not exist
+				}
+
+				if (serverNodes == null || serverNodes.isEmpty()) {
+					// Fall back to the default unsecure namespace if no secure nodes are found
+					serverNodes = zooKeeperClient.getChildren().forPath(DEFAULT_ZOOKEEPER_NAMESPACE_UNSECURE
+ "/rs");
+				}
 			}
 
-			// Retrieve list of all region server hosts
-			List<String> serverNodes = zooKeeperClient.getChildren().forPath(namespace + "/rs");
-			
-			for (String serverNode : serverNodes) {
-				String serverURL = constructURL(serverNode);
-				serverHosts.add(serverURL);
+			if (serverNodes != null) {
+				for (String serverNode : serverNodes) {
+					String serverURL = constructURL(serverNode);
+					serverHosts.add(serverURL);
+				}
 			}
 		} catch (Exception e) {
 			LOG.failedToGetZookeeperUrls(e);
@@ -121,10 +139,10 @@ public class HBaseZookeeperURLManager extends BaseZookeeperURLManager
{
 				zooKeeperClient.close();
 			}
 		}
-		
+
 		return serverHosts;
 	}
-	
+
 	/**
 	 * Given a String of the format "host,number,number" convert to a URL of the format
 	 * "http://host:port".
@@ -140,10 +158,10 @@ public class HBaseZookeeperURLManager extends BaseZookeeperURLManager
{
 		buffer.append(scheme);
 		buffer.append("://");
 		// Strip off the host name 
-		buffer.append(serverInfo.substring(0,serverInfo.indexOf(",")));
+		buffer.append(serverInfo.substring(0, serverInfo.indexOf(",")));
 		buffer.append(":");
 		buffer.append(PORT_NUMBER);
-		
+
 		return buffer.toString();
 	}
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/1b053c5e/gateway-provider-ha/src/test/java/org/apache/knox/gateway/ha/provider/impl/HBaseZookeeperURLManagerTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-ha/src/test/java/org/apache/knox/gateway/ha/provider/impl/HBaseZookeeperURLManagerTest.java
b/gateway-provider-ha/src/test/java/org/apache/knox/gateway/ha/provider/impl/HBaseZookeeperURLManagerTest.java
index 1869890..a4166f4 100644
--- a/gateway-provider-ha/src/test/java/org/apache/knox/gateway/ha/provider/impl/HBaseZookeeperURLManagerTest.java
+++ b/gateway-provider-ha/src/test/java/org/apache/knox/gateway/ha/provider/impl/HBaseZookeeperURLManagerTest.java
@@ -18,6 +18,9 @@
 package org.apache.knox.gateway.ha.provider.impl;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 import org.apache.curator.framework.CuratorFramework;
 import org.apache.curator.framework.CuratorFrameworkFactory;
@@ -68,13 +71,33 @@ public class HBaseZookeeperURLManagerTest {
     doTest(SECURE_NS);
   }
 
+  /**
+   * KNOX-1149
+   */
+  @Test
+  public void testDefaultNSHBaseZookeeperURLManagerLoadingWhenSecureAndUnsecureZNodesPresent()
throws Exception {
+    createZNodes(UNSECURE_NS);
+    createZNodes(SECURE_NS);
+    doTest(null);
+  }
+
+  /**
+   * KNOX-1149
+   */
+  @Test
+  public void testSpecifiedNSHBaseZookeeperURLManagerLoadingWhenSecureAndUnsecureZNodesPresent()
throws Exception {
+    createZNodes(UNSECURE_NS);
+    createZNodes(SECURE_NS);
+    doTest(UNSECURE_NS);
+  }
+
   @Test
   public void testSecureNSHBaseZookeeperURLManagerLoadingNoLeadingSlash() throws Exception
{
     createZNodes(SECURE_NS);
     doTest(SECURE_NS.substring(1)); // Omit the leading slash from the namespace
   }
 
-  private void doTest(String namespace) throws Exception {
+  private void doTest(String namespace) {
     HaServiceConfig config = new DefaultHaServiceConfig("WEBHBASE");
     config.setEnabled(true);
     config.setZookeeperEnsemble(cluster.getConnectString());
@@ -89,6 +112,7 @@ public class HBaseZookeeperURLManagerTest {
     Assert.assertTrue(manager instanceof HBaseZookeeperURLManager);
   }
 
+
   private void createZNodes(String namespace) throws Exception {
     CuratorFramework zooKeeperClient =
                           CuratorFrameworkFactory.builder().connectString(cluster.getConnectString())


Mime
View raw message