Hello, I am trying to set up an unit test in local environment for testing Apache Phoenix with kerberos.
Does anyone did something similar in the past? I am able to start the minicluster with kerberos but when I am getting the connection from the url I am always having the same error: 2016-05-11 18:26:04,234 (LeaseRenewer:C0228488@localhost:61693) [WARN - org.apache.hadoop.hdfs.LeaseRenewer.run(LeaseRenewer.java:458)] Failed to renew lease for [DFSClient_hb_m_localhost,61702,1462987530289_-639707842_181] for 32 seconds. Will retry shortly ... org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security.AccessControlException): SIMPLE authentication is not enabled. Available:[TOKEN, KERBEROS] at org.apache.hadoop.ipc.Client.call(Client.java:1468) at org.apache.hadoop.ipc.Client.call(Client.java:1399) at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:232) at com.sun.proxy.$Proxy19.renewLease(Unknown Source) at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolTranslatorPB.renewLease(ClientNamenodeProtocolTranslatorPB.java:571) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:187) at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:102) at com.sun.proxy.$Proxy20.renewLease(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.apache.hadoop.hbase.fs.HFileSystem$1.invoke(HFileSystem.java:279) at com.sun.proxy.$Proxy21.renewLease(Unknown Source) at org.apache.hadoop.hdfs.DFSClient.renewLease(DFSClient.java:878) at org.apache.hadoop.hdfs.LeaseRenewer.renew(LeaseRenewer.java:417) at org.apache.hadoop.hdfs.LeaseRenewer.run(LeaseRenewer.java:442) at org.apache.hadoop.hdfs.LeaseRenewer.access$700(LeaseRenewer.java:71) at org.apache.hadoop.hdfs.LeaseRenewer$1.run(LeaseRenewer.java:298) at java.lang.Thread.run(Thread.java:745) Just one thing, when I am changing the authentication mode to SIMPLE, the test is working fine but it is not valid because I am not using kerberos authentication. conf.set("hadoop.security.authentication", "SIMPLE") conf.set(User.HBASE_SECURITY_CONF_KEY, "SIMPLE") This is the entire code: import java.io.File import java.sql.DriverManager import java.util.Properties import org.apache.hadoop.conf.Configuration import org.apache.hadoop.fs.Path import org.apache.hadoop.hbase.coprocessor.CoprocessorHost import org.apache.hadoop.hbase.ipc.{RpcClientFactory, RpcClientImpl} import org.apache.hadoop.hbase.security._ import org.apache.hadoop.hbase.security.token.TokenProvider import org.apache.hadoop.hbase.testclassification.MediumTests import org.apache.hadoop.hbase.util.FSUtils import org.apache.hadoop.hbase.{HBaseTestingUtility, HConstants, LocalHBaseCluster} import org.apache.hadoop.hdfs.DFSConfigKeys import org.apache.hadoop.http.HttpConfig import org.apache.hadoop.minikdc.MiniKdc import org.apache.hadoop.security.UserGroupInformation import org.apache.phoenix.util.PhoenixRuntime._ import org.junit.experimental.categories.Category import org.scalatest.{BeforeAndAfterAll, Suite} @Category(Array(classOf[MediumTests])) trait PhoenixKdcTest extends BeforeAndAfterAll { this: Suite => private val TEST_UTIL: HBaseTestingUtility = new HBaseTestingUtility private var CLUSTER: LocalHBaseCluster = null private val KEYTAB_FILE: File = new File(TEST_UTIL.getDataTestDir("keytab").toUri.getPath) private var KDC: MiniKdc = null private val HOST: String = "localhost" private var USERNAME: String = null private var PRINCIPAL: String = null private var KDC_PRINCIPAL: String = null private var HTTP_PRINCIPAL: String = null private val KRB_PRINCIPAL: String = "hbase.regionserver.kerberos.principal" private val MASTER_KRB_PRINCIPAL: String = "hbase.master.kerberos.principal" private val KRB_KEYTAB_FILE: String = "hbase.regionserver.keytab.file" lazy val hbaseConfiguration = { val conf = TEST_UTIL.getConfiguration val quorum = conf.get("hbase.zookeeper.quorum") val clientPort = conf.get("hbase.zookeeper.property.clientPort") val znodeParent = conf.get("zookeeper.znode.parent") conf.set(HConstants.ZOOKEEPER_QUORUM, s"$quorum:$clientPort:$znodeParent") conf } @throws(classOf[Exception]) private def setHdfsSecuredConfiguration(conf: Configuration) { conf.set("hadoop.security.authentication", "KERBEROS") conf.set(User.HBASE_SECURITY_CONF_KEY, "KERBEROS") conf.setBoolean("hbase.security.authorization", true) conf.set(KRB_KEYTAB_FILE, System.getProperty(KRB_KEYTAB_FILE)) conf.set(KRB_PRINCIPAL, System.getProperty(KRB_PRINCIPAL)) conf.set(MASTER_KRB_PRINCIPAL, System.getProperty(KRB_PRINCIPAL)) conf.set(DFSConfigKeys.DFS_NAMENODE_USER_NAME_KEY, KDC_PRINCIPAL) conf.set(DFSConfigKeys.DFS_NAMENODE_KEYTAB_FILE_KEY, KEYTAB_FILE.getAbsolutePath) conf.set(DFSConfigKeys.DFS_DATANODE_USER_NAME_KEY, KDC_PRINCIPAL) conf.set(DFSConfigKeys.DFS_DATANODE_KEYTAB_FILE_KEY, KEYTAB_FILE.getAbsolutePath) conf.set(DFSConfigKeys.DFS_WEB_AUTHENTICATION_KERBEROS_PRINCIPAL_KEY, HTTP_PRINCIPAL + "@" + KDC.getRealm) conf.setBoolean(DFSConfigKeys.DFS_BLOCK_ACCESS_TOKEN_ENABLE_KEY, true) conf.set(DFSConfigKeys.DFS_HTTP_POLICY_KEY, HttpConfig.Policy.HTTPS_ONLY.name) conf.set(DFSConfigKeys.DFS_NAMENODE_HTTPS_ADDRESS_KEY, "localhost:0") conf.set(DFSConfigKeys.DFS_DATANODE_HTTPS_ADDRESS_KEY, "localhost:0") val keystoresDir: File = new File(TEST_UTIL.getDataTestDir("keystore").toUri.getPath) keystoresDir.mkdirs val sslConfDir: String = KeyStoreTestUtil.getClasspathDir(classOf[PhoenixKdcTest]) KeyStoreTestUtil.setupSSLConfig(keystoresDir.getAbsolutePath, sslConfDir, conf, false) conf.setBoolean("ignore.secure.ports.for.testing", true) } private def startMiniCluster(){ val prop: Properties = MiniKdc.createConf prop.put(MiniKdc.DEBUG, "true") KDC = new MiniKdc(prop, new File(TEST_UTIL.getDataTestDir("kdc").toUri.getPath)) KDC.start USERNAME = UserGroupInformation.getLoginUser.getShortUserName PRINCIPAL = USERNAME + "/" + HOST HTTP_PRINCIPAL = "HTTP/" + HOST KDC.createPrincipal(KEYTAB_FILE, PRINCIPAL, HTTP_PRINCIPAL) TEST_UTIL.startMiniZKCluster KDC_PRINCIPAL = PRINCIPAL + "@" + KDC.getRealm setSystemProperty("hbase.regionserver.keytab.file", KEYTAB_FILE.getAbsolutePath); setSystemProperty("hbase.regionserver.kerberos.principal", KDC_PRINCIPAL); setHdfsSecuredConfiguration(TEST_UTIL.getConfiguration) UserGroupInformation.setConfiguration(TEST_UTIL.getConfiguration) TEST_UTIL.getConfiguration.setStrings(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY, classOf[TokenProvider].getName) TEST_UTIL.startMiniDFSCluster(1) val rootdir: Path = TEST_UTIL.getDataTestDirOnTestFS("TestGenerateDelegationToken") FSUtils.setRootDir(TEST_UTIL.getConfiguration, rootdir) CLUSTER = new LocalHBaseCluster(TEST_UTIL.getConfiguration) User.login(TEST_UTIL.getConfiguration,KRB_KEYTAB_FILE,KRB_PRINCIPAL,HOST) CLUSTER.startup } override def beforeAll() { startMiniCluster() TEST_UTIL.getConfiguration.set(RpcClientFactory.CUSTOM_RPC_CLIENT_IMPL_CONF_KEY, classOf[RpcClientImpl].getName) val url = JDBC_PROTOCOL + JDBC_PROTOCOL_SEPARATOR + hbaseConfiguration.get(HConstants.ZOOKEEPER_QUORUM) + JDBC_PROTOCOL_SEPARATOR + PRINCIPAL + JDBC_PROTOCOL_SEPARATOR + KEYTAB_FILE // Setups a test table to test connectivity val conn = DriverManager.getConnection(url) conn.setAutoCommit(true) val stmt = conn.createStatement() stmt.execute("CREATE TABLE IF NOT EXISTS us_population(state CHAR(2) NOT NULL, city VARCHAR, population BIGINT CONSTRAINT my_pk PRIMARY KEY (state))") stmt.execute("UPSERT INTO us_population values ('CA', 'San Francisco', 837442)"); stmt.execute("UPSERT INTO us_population values ('NY', 'New York', 11231312)"); stmt.execute("UPSERT INTO us_population values ('TX', 'Texas', 6456465)"); val resultSet = stmt.executeQuery("SELECT * FROM us_population") val resultStream = new Iterator[String] { def hasNext = resultSet.next() def next() = resultSet.getString(1) }.toStream assert(resultStream.count(_=>true)==3) conn.close() } override def afterAll(){ if (CLUSTER != null) { CLUSTER.shutdown } CLUSTER.join if (KDC != null) { KDC.stop } TEST_UTIL.shutdownMiniCluster } private[security] def setSystemProperty(propertyName: String, propertyValue: String){ System.setProperty(propertyName, propertyValue) } } -- Un saludo - Best Regards. Abel