/*
 * 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.drill.exec.rpc.user.security;

import com.google.common.collect.Lists;
import com.typesafe.config.ConfigValueFactory;
import org.apache.drill.test.BaseTestQuery;
import org.apache.drill.categories.SecurityTest;
import org.apache.drill.common.config.DrillConfig;
import org.apache.drill.common.config.DrillProperties;
import org.apache.drill.exec.ExecConstants;
import org.apache.drill.exec.rpc.NonTransientRpcException;
import org.apache.drill.exec.rpc.RpcException;
import org.apache.drill.exec.rpc.control.ControlRpcMetrics;
import org.apache.drill.exec.rpc.data.DataRpcMetrics;
import org.apache.drill.exec.rpc.security.KerberosHelper;
import org.apache.drill.exec.rpc.user.UserRpcMetrics;
import org.apache.drill.exec.rpc.user.security.testing.UserAuthenticatorTestImpl;
import org.apache.drill.exec.server.BootStrapContext;
import org.apache.hadoop.security.authentication.util.KerberosName;
import org.apache.hadoop.security.authentication.util.KerberosUtil;
import org.apache.kerby.kerberos.kerb.client.JaasKrbUtil;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import javax.security.auth.Subject;
import java.lang.reflect.Field;
import java.security.PrivilegedExceptionAction;
import java.util.Properties;

import static junit.framework.TestCase.assertTrue;
import static junit.framework.TestCase.fail;

@Ignore("See DRILL-5387")
@Category(SecurityTest.class)
public class TestUserBitKerberosEncryption extends BaseTestQuery {
  private static final org.slf4j.Logger logger =
      org.slf4j.LoggerFactory.getLogger(TestUserBitKerberosEncryption.class);

  private static KerberosHelper krbHelper;
  private static DrillConfig newConfig;

  @BeforeClass
  public static void setupTest() throws Exception {
    krbHelper = new KerberosHelper(TestUserBitKerberosEncryption.class.getSimpleName(), null);
    krbHelper.setupKdc(dirTestWatcher.getTmpDir());

    // Create a new DrillConfig which has user authentication enabled and authenticator set to
    // UserAuthenticatorTestImpl.
    newConfig = new DrillConfig(DrillConfig.create(cloneDefaultTestConfigProperties())
        .withValue(ExecConstants.USER_AUTHENTICATION_ENABLED,
            ConfigValueFactory.fromAnyRef(true))
        .withValue(ExecConstants.USER_AUTHENTICATOR_IMPL,
            ConfigValueFactory.fromAnyRef(UserAuthenticatorTestImpl.TYPE))
        .withValue(BootStrapContext.SERVICE_PRINCIPAL,
            ConfigValueFactory.fromAnyRef(krbHelper.SERVER_PRINCIPAL))
        .withValue(BootStrapContext.SERVICE_KEYTAB_LOCATION,
            ConfigValueFactory.fromAnyRef(krbHelper.serverKeytab.toString()))
        .withValue(ExecConstants.AUTHENTICATION_MECHANISMS,
            ConfigValueFactory.fromIterable(Lists.newArrayList("plain", "kerberos")))
        .withValue(ExecConstants.USER_ENCRYPTION_SASL_ENABLED,
            ConfigValueFactory.fromAnyRef(true)));

    final Properties connectionProps = new Properties();
    connectionProps.setProperty(DrillProperties.SERVICE_PRINCIPAL, krbHelper.SERVER_PRINCIPAL);
    connectionProps.setProperty(DrillProperties.USER, krbHelper.CLIENT_PRINCIPAL);
    connectionProps.setProperty(DrillProperties.KEYTAB, krbHelper.clientKeytab.getAbsolutePath());

    // Ignore the compile time warning caused by the code below.

    // Config is statically initialized at this point. But the above configuration results in a different
    // initialization which causes the tests to fail. So the following two changes are required.

    // (1) Refresh Kerberos config.
    sun.security.krb5.Config.refresh();
    // (2) Reset the default realm.
    final Field defaultRealm = KerberosName.class.getDeclaredField("defaultRealm");
    defaultRealm.setAccessible(true);
    defaultRealm.set(null, KerberosUtil.getDefaultRealm());

    // Start a secure cluster with client using Kerberos related parameters.
    updateTestCluster(1, newConfig, connectionProps);
  }

  @AfterClass
  public static void cleanTest() throws Exception {
    krbHelper.stopKdc();
  }

  @Test
  public void successKeytabWithoutChunking() throws Exception {
    final Properties connectionProps = new Properties();
    connectionProps.setProperty(DrillProperties.SERVICE_PRINCIPAL, krbHelper.SERVER_PRINCIPAL);
    connectionProps.setProperty(DrillProperties.USER, krbHelper.CLIENT_PRINCIPAL);
    connectionProps.setProperty(DrillProperties.KEYTAB, krbHelper.clientKeytab.getAbsolutePath());

    newConfig = new DrillConfig(DrillConfig.create(cloneDefaultTestConfigProperties())
      .withValue(ExecConstants.USER_AUTHENTICATION_ENABLED,
        ConfigValueFactory.fromAnyRef(true))
      .withValue(ExecConstants.USER_AUTHENTICATOR_IMPL,
        ConfigValueFactory.fromAnyRef(UserAuthenticatorTestImpl.TYPE))
      .withValue(BootStrapContext.SERVICE_PRINCIPAL,
        ConfigValueFactory.fromAnyRef(krbHelper.SERVER_PRINCIPAL))
      .withValue(BootStrapContext.SERVICE_KEYTAB_LOCATION,
        ConfigValueFactory.fromAnyRef(krbHelper.serverKeytab.toString()))
      .withValue(ExecConstants.AUTHENTICATION_MECHANISMS,
        ConfigValueFactory.fromIterable(Lists.newArrayList("plain", "kerberos")))
      .withValue(ExecConstants.USER_ENCRYPTION_SASL_ENABLED,
        ConfigValueFactory.fromAnyRef(true)));

    updateTestCluster(1, newConfig, connectionProps);

    // Run few queries using the new client
    testBuilder()
        .sqlQuery("SELECT session_user FROM (SELECT * FROM sys.drillbits LIMIT 1)")
        .unOrdered()
        .baselineColumns("session_user")
        .baselineValues(krbHelper.CLIENT_SHORT_NAME)
        .go();
    test("SHOW SCHEMAS");
    test("USE INFORMATION_SCHEMA");
    test("SHOW TABLES");
    test("SELECT * FROM INFORMATION_SCHEMA.`TABLES` WHERE TABLE_NAME LIKE 'COLUMNS'");
    test("SELECT * FROM cp.`region.json`");
  }

  /**
   * Test connection counter values for both encrypted and unencrypted connections over all Drillbit channels.
   * Encryption is enabled only for UserRpc NOT for ControlRpc and DataRpc. Test validates corresponding connection
   * count for each channel.
   * For example: There is only 1 DrillClient so encrypted connection count of UserRpcMetrics will be 1. Before
   * running any query there should not be any connection (control or data) between Drillbits, hence those counters
   * are 0. After running a simple query since there is only 1 fragment which is root fragment the Control Connection
   * count is 0 (for unencrypted counter) since with DRILL-5721 status update of fragment to Foreman happens locally.
   * There is no Data Connection because there is no data exchange between multiple fragments.
   *
   * @throws Exception
   */
  @Test
  public void testConnectionCounters() throws Exception {
    final Properties connectionProps = new Properties();
    connectionProps.setProperty(DrillProperties.SERVICE_PRINCIPAL, krbHelper.SERVER_PRINCIPAL);
    connectionProps.setProperty(DrillProperties.USER, krbHelper.CLIENT_PRINCIPAL);
    connectionProps.setProperty(DrillProperties.KEYTAB, krbHelper.clientKeytab.getAbsolutePath());

    newConfig = new DrillConfig(DrillConfig.create(cloneDefaultTestConfigProperties())
      .withValue(ExecConstants.USER_AUTHENTICATION_ENABLED,
        ConfigValueFactory.fromAnyRef(true))
      .withValue(ExecConstants.USER_AUTHENTICATOR_IMPL,
        ConfigValueFactory.fromAnyRef(UserAuthenticatorTestImpl.TYPE))
      .withValue(BootStrapContext.SERVICE_PRINCIPAL,
        ConfigValueFactory.fromAnyRef(krbHelper.SERVER_PRINCIPAL))
      .withValue(BootStrapContext.SERVICE_KEYTAB_LOCATION,
        ConfigValueFactory.fromAnyRef(krbHelper.serverKeytab.toString()))
      .withValue(ExecConstants.AUTHENTICATION_MECHANISMS,
        ConfigValueFactory.fromIterable(Lists.newArrayList("plain", "kerberos")))
      .withValue(ExecConstants.USER_ENCRYPTION_SASL_ENABLED,
        ConfigValueFactory.fromAnyRef(true)));

    updateTestCluster(1, newConfig, connectionProps);

    assertTrue(UserRpcMetrics.getInstance().getEncryptedConnectionCount() == 1);
    assertTrue(UserRpcMetrics.getInstance().getUnEncryptedConnectionCount() == 0);

    // Run few queries using the new client
    testBuilder()
        .sqlQuery("SELECT session_user FROM (SELECT * FROM sys.drillbits LIMIT 1)")
        .unOrdered()
        .baselineColumns("session_user")
        .baselineValues(krbHelper.CLIENT_SHORT_NAME)
        .go();

    // Check encrypted counters value
    assertTrue(1 == UserRpcMetrics.getInstance().getEncryptedConnectionCount());
    assertTrue(0 == ControlRpcMetrics.getInstance().getEncryptedConnectionCount());
    assertTrue(0 == DataRpcMetrics.getInstance().getEncryptedConnectionCount());

    // Check unencrypted counters value
    assertTrue(0 == UserRpcMetrics.getInstance().getUnEncryptedConnectionCount());
    assertTrue(0 == ControlRpcMetrics.getInstance().getUnEncryptedConnectionCount());
    assertTrue(0 == DataRpcMetrics.getInstance().getUnEncryptedConnectionCount());
  }

  @Test
  public void successTicketWithoutChunking() throws Exception {
    final Properties connectionProps = new Properties();
    connectionProps.setProperty(DrillProperties.SERVICE_PRINCIPAL, krbHelper.SERVER_PRINCIPAL);
    connectionProps.setProperty(DrillProperties.KERBEROS_FROM_SUBJECT, "true");
    final Subject clientSubject = JaasKrbUtil.loginUsingKeytab(krbHelper.CLIENT_PRINCIPAL,
                                                               krbHelper.clientKeytab.getAbsoluteFile());

    newConfig = new DrillConfig(DrillConfig.create(cloneDefaultTestConfigProperties())
      .withValue(ExecConstants.USER_AUTHENTICATION_ENABLED,
        ConfigValueFactory.fromAnyRef(true))
      .withValue(ExecConstants.USER_AUTHENTICATOR_IMPL,
        ConfigValueFactory.fromAnyRef(UserAuthenticatorTestImpl.TYPE))
      .withValue(BootStrapContext.SERVICE_PRINCIPAL,
        ConfigValueFactory.fromAnyRef(krbHelper.SERVER_PRINCIPAL))
      .withValue(BootStrapContext.SERVICE_KEYTAB_LOCATION,
        ConfigValueFactory.fromAnyRef(krbHelper.serverKeytab.toString()))
      .withValue(ExecConstants.AUTHENTICATION_MECHANISMS,
        ConfigValueFactory.fromIterable(Lists.newArrayList("plain", "kerberos")))
      .withValue(ExecConstants.USER_ENCRYPTION_SASL_ENABLED,
        ConfigValueFactory.fromAnyRef(true)));

    Subject.doAs(clientSubject, new PrivilegedExceptionAction<Void>() {
      @Override
      public Void run() throws Exception {
        updateTestCluster(1, newConfig, connectionProps);
        return null;
      }
    });

    // Run few queries using the new client
    testBuilder()
        .sqlQuery("SELECT session_user FROM (SELECT * FROM sys.drillbits LIMIT 1)")
        .unOrdered()
        .baselineColumns("session_user")
        .baselineValues(krbHelper.CLIENT_SHORT_NAME)
        .go();
    test("SHOW SCHEMAS");
    test("USE INFORMATION_SCHEMA");
    test("SHOW TABLES");
    test("SELECT * FROM INFORMATION_SCHEMA.`TABLES` WHERE TABLE_NAME LIKE 'COLUMNS'");
    test("SELECT * FROM cp.`region.json` LIMIT 5");
  }

  @Test
  public void successKeytabWithChunking() throws Exception {
    final Properties connectionProps = new Properties();
    connectionProps.setProperty(DrillProperties.SERVICE_PRINCIPAL, krbHelper.SERVER_PRINCIPAL);
    connectionProps.setProperty(DrillProperties.USER, krbHelper.CLIENT_PRINCIPAL);
    connectionProps.setProperty(DrillProperties.KEYTAB, krbHelper.clientKeytab.getAbsolutePath());

    newConfig = new DrillConfig(DrillConfig.create(cloneDefaultTestConfigProperties())
      .withValue(ExecConstants.USER_AUTHENTICATION_ENABLED,
        ConfigValueFactory.fromAnyRef(true))
      .withValue(ExecConstants.USER_AUTHENTICATOR_IMPL,
        ConfigValueFactory.fromAnyRef(UserAuthenticatorTestImpl.TYPE))
      .withValue(BootStrapContext.SERVICE_PRINCIPAL,
        ConfigValueFactory.fromAnyRef(krbHelper.SERVER_PRINCIPAL))
      .withValue(BootStrapContext.SERVICE_KEYTAB_LOCATION,
        ConfigValueFactory.fromAnyRef(krbHelper.serverKeytab.toString()))
      .withValue(ExecConstants.AUTHENTICATION_MECHANISMS,
        ConfigValueFactory.fromIterable(Lists.newArrayList("plain", "kerberos")))
      .withValue(ExecConstants.USER_ENCRYPTION_SASL_ENABLED,
        ConfigValueFactory.fromAnyRef(true))
      .withValue(ExecConstants.USER_ENCRYPTION_SASL_MAX_WRAPPED_SIZE,
        ConfigValueFactory.fromAnyRef(100)));

    updateTestCluster(1, newConfig, connectionProps);

    // Run few queries using the new client
    testBuilder()
      .sqlQuery("SELECT session_user FROM (SELECT * FROM sys.drillbits LIMIT 1)")
      .unOrdered()
      .baselineColumns("session_user")
      .baselineValues(krbHelper.CLIENT_SHORT_NAME)
      .go();
    test("SHOW SCHEMAS");
    test("USE INFORMATION_SCHEMA");
    test("SHOW TABLES");
    test("SELECT * FROM INFORMATION_SCHEMA.`TABLES` WHERE TABLE_NAME LIKE 'COLUMNS'");
    test("SELECT * FROM cp.`region.json`");
  }

  @Test
  public void successKeytabWithChunkingDefaultChunkSize() throws Exception {
    final Properties connectionProps = new Properties();
    connectionProps.setProperty(DrillProperties.SERVICE_PRINCIPAL, krbHelper.SERVER_PRINCIPAL);
    connectionProps.setProperty(DrillProperties.USER, krbHelper.CLIENT_PRINCIPAL);
    connectionProps.setProperty(DrillProperties.KEYTAB, krbHelper.clientKeytab.getAbsolutePath());

    newConfig = new DrillConfig(DrillConfig.create(cloneDefaultTestConfigProperties())
      .withValue(ExecConstants.USER_AUTHENTICATION_ENABLED,
        ConfigValueFactory.fromAnyRef(true))
      .withValue(ExecConstants.USER_AUTHENTICATOR_IMPL,
        ConfigValueFactory.fromAnyRef(UserAuthenticatorTestImpl.TYPE))
      .withValue(BootStrapContext.SERVICE_PRINCIPAL,
        ConfigValueFactory.fromAnyRef(krbHelper.SERVER_PRINCIPAL))
      .withValue(BootStrapContext.SERVICE_KEYTAB_LOCATION,
        ConfigValueFactory.fromAnyRef(krbHelper.serverKeytab.toString()))
      .withValue(ExecConstants.AUTHENTICATION_MECHANISMS,
        ConfigValueFactory.fromIterable(Lists.newArrayList("plain", "kerberos")))
      .withValue(ExecConstants.USER_ENCRYPTION_SASL_ENABLED,
        ConfigValueFactory.fromAnyRef(true)));

    updateTestCluster(1, newConfig, connectionProps);

    // Run few queries using the new client
    testBuilder()
      .sqlQuery("SELECT session_user FROM (SELECT * FROM sys.drillbits LIMIT 1)")
      .unOrdered()
      .baselineColumns("session_user")
      .baselineValues(krbHelper.CLIENT_SHORT_NAME)
      .go();
    test("SHOW SCHEMAS");
    test("USE INFORMATION_SCHEMA");
    test("SHOW TABLES");
    test("SELECT * FROM INFORMATION_SCHEMA.`TABLES` WHERE TABLE_NAME LIKE 'COLUMNS'");
    test("SELECT * FROM cp.`region.json` LIMIT 5");
  }


  /**
   *  This test will not cover the data channel since we are using only 1 Drillbit and the query doesn't involve
   *  any exchange operator. But Data Channel encryption testing is covered separately in
   *  {@link org.apache.drill.exec.rpc.data.TestBitBitKerberos}
   */
  @Test
  public void successEncryptionAllChannelChunkMode() throws Exception {
    final Properties connectionProps = new Properties();
    connectionProps.setProperty(DrillProperties.SERVICE_PRINCIPAL, krbHelper.SERVER_PRINCIPAL);
    connectionProps.setProperty(DrillProperties.USER, krbHelper.CLIENT_PRINCIPAL);
    connectionProps.setProperty(DrillProperties.KEYTAB, krbHelper.clientKeytab.getAbsolutePath());

    newConfig = new DrillConfig(DrillConfig.create(cloneDefaultTestConfigProperties())
      .withValue(ExecConstants.USER_AUTHENTICATION_ENABLED,
        ConfigValueFactory.fromAnyRef(true))
      .withValue(ExecConstants.USER_AUTHENTICATOR_IMPL,
        ConfigValueFactory.fromAnyRef(UserAuthenticatorTestImpl.TYPE))
      .withValue(BootStrapContext.SERVICE_PRINCIPAL,
        ConfigValueFactory.fromAnyRef(krbHelper.SERVER_PRINCIPAL))
      .withValue(BootStrapContext.SERVICE_KEYTAB_LOCATION,
        ConfigValueFactory.fromAnyRef(krbHelper.serverKeytab.toString()))
      .withValue(ExecConstants.AUTHENTICATION_MECHANISMS,
        ConfigValueFactory.fromIterable(Lists.newArrayList("plain", "kerberos")))
      .withValue(ExecConstants.USER_ENCRYPTION_SASL_ENABLED,
        ConfigValueFactory.fromAnyRef(true))
      .withValue(ExecConstants.USER_ENCRYPTION_SASL_MAX_WRAPPED_SIZE,
        ConfigValueFactory.fromAnyRef(10000))
      .withValue(ExecConstants.BIT_AUTHENTICATION_ENABLED,
        ConfigValueFactory.fromAnyRef(true))
      .withValue(ExecConstants.BIT_AUTHENTICATION_MECHANISM,
        ConfigValueFactory.fromAnyRef("kerberos"))
      .withValue(ExecConstants.USE_LOGIN_PRINCIPAL,
        ConfigValueFactory.fromAnyRef(true))
      .withValue(ExecConstants.BIT_ENCRYPTION_SASL_ENABLED,
        ConfigValueFactory.fromAnyRef(true))
      .withValue(ExecConstants.BIT_ENCRYPTION_SASL_MAX_WRAPPED_SIZE,
        ConfigValueFactory.fromAnyRef(10000)));

    updateTestCluster(1, newConfig, connectionProps);

    // Run few queries using the new client
    testBuilder()
      .sqlQuery("SELECT session_user FROM (SELECT * FROM sys.drillbits LIMIT 1)")
      .unOrdered()
      .baselineColumns("session_user")
      .baselineValues(krbHelper.CLIENT_SHORT_NAME)
      .go();
    test("SHOW SCHEMAS");
    test("USE INFORMATION_SCHEMA");
    test("SHOW TABLES");
    test("SELECT * FROM INFORMATION_SCHEMA.`TABLES` WHERE TABLE_NAME LIKE 'COLUMNS'");
    test("SELECT * FROM cp.`region.json` LIMIT 5");
  }



  /**
   *  This test will not cover the data channel since we are using only 1 Drillbit and the query doesn't involve
   *  any exchange operator. But Data Channel encryption testing is covered separately in
   *  {@link org.apache.drill.exec.rpc.data.TestBitBitKerberos}
   */
  @Test
  public void successEncryptionAllChannel() throws Exception {

    final Properties connectionProps = new Properties();
    connectionProps.setProperty(DrillProperties.SERVICE_PRINCIPAL, krbHelper.SERVER_PRINCIPAL);
    connectionProps.setProperty(DrillProperties.USER, krbHelper.CLIENT_PRINCIPAL);
    connectionProps.setProperty(DrillProperties.KEYTAB, krbHelper.clientKeytab.getAbsolutePath());

    newConfig = new DrillConfig(DrillConfig.create(cloneDefaultTestConfigProperties())
      .withValue(ExecConstants.USER_AUTHENTICATION_ENABLED,
        ConfigValueFactory.fromAnyRef(true))
      .withValue(ExecConstants.USER_AUTHENTICATOR_IMPL,
        ConfigValueFactory.fromAnyRef(UserAuthenticatorTestImpl.TYPE))
      .withValue(BootStrapContext.SERVICE_PRINCIPAL,
        ConfigValueFactory.fromAnyRef(krbHelper.SERVER_PRINCIPAL))
      .withValue(BootStrapContext.SERVICE_KEYTAB_LOCATION,
        ConfigValueFactory.fromAnyRef(krbHelper.serverKeytab.toString()))
      .withValue(ExecConstants.AUTHENTICATION_MECHANISMS,
        ConfigValueFactory.fromIterable(Lists.newArrayList("plain", "kerberos")))
      .withValue(ExecConstants.USER_ENCRYPTION_SASL_ENABLED,
        ConfigValueFactory.fromAnyRef(true))
      .withValue(ExecConstants.BIT_AUTHENTICATION_ENABLED,
        ConfigValueFactory.fromAnyRef(true))
      .withValue(ExecConstants.BIT_AUTHENTICATION_MECHANISM,
        ConfigValueFactory.fromAnyRef("kerberos"))
      .withValue(ExecConstants.USE_LOGIN_PRINCIPAL,
        ConfigValueFactory.fromAnyRef(true))
      .withValue(ExecConstants.BIT_ENCRYPTION_SASL_ENABLED,
        ConfigValueFactory.fromAnyRef(true)));

    updateTestCluster(1, newConfig, connectionProps);

    // Run few queries using the new client
    testBuilder()
      .sqlQuery("SELECT session_user FROM (SELECT * FROM sys.drillbits LIMIT 1)")
      .unOrdered()
      .baselineColumns("session_user")
      .baselineValues(krbHelper.CLIENT_SHORT_NAME)
      .go();
    test("SHOW SCHEMAS");
    test("USE INFORMATION_SCHEMA");
    test("SHOW TABLES");
    test("SELECT * FROM INFORMATION_SCHEMA.`TABLES` WHERE TABLE_NAME LIKE 'COLUMNS'");
    test("SELECT * FROM cp.`region.json` LIMIT 5");
  }

  /**
   * Test connection counter values for both encrypted and unencrypted connections over all Drillbit channels.
   * Encryption is enabled for UserRpc, ControlRpc and DataRpc. Test validates corresponding connection
   * count for each channel.
   * For example: There is only 1 DrillClient so encrypted connection count of UserRpcMetrics
   * will be 1. Before running any query there should not be any connection (control or data) between Drillbits,
   * hence those counters are 0. After running a simple query since there is only 1 fragment which is root fragment
   * the Control Connection count is 0 (for encrypted counter), since with DRILL-5721 status update of fragment to
   * Foreman happens locally. There is no Data Connection because there is no data exchange between multiple fragments.
   */

  @Test
  public void testEncryptedConnectionCountersAllChannel() throws Exception {
    final Properties connectionProps = new Properties();
    connectionProps.setProperty(DrillProperties.SERVICE_PRINCIPAL, krbHelper.SERVER_PRINCIPAL);
    connectionProps.setProperty(DrillProperties.USER, krbHelper.CLIENT_PRINCIPAL);
    connectionProps.setProperty(DrillProperties.KEYTAB, krbHelper.clientKeytab.getAbsolutePath());

    newConfig = new DrillConfig(DrillConfig.create(cloneDefaultTestConfigProperties())
        .withValue(ExecConstants.USER_AUTHENTICATION_ENABLED,
            ConfigValueFactory.fromAnyRef(true))
        .withValue(ExecConstants.USER_AUTHENTICATOR_IMPL,
            ConfigValueFactory.fromAnyRef(UserAuthenticatorTestImpl.TYPE))
        .withValue(BootStrapContext.SERVICE_PRINCIPAL,
            ConfigValueFactory.fromAnyRef(krbHelper.SERVER_PRINCIPAL))
        .withValue(BootStrapContext.SERVICE_KEYTAB_LOCATION,
            ConfigValueFactory.fromAnyRef(krbHelper.serverKeytab.toString()))
        .withValue(ExecConstants.AUTHENTICATION_MECHANISMS,
            ConfigValueFactory.fromIterable(Lists.newArrayList("plain", "kerberos")))
        .withValue(ExecConstants.USER_ENCRYPTION_SASL_ENABLED,
            ConfigValueFactory.fromAnyRef(true))
        .withValue(ExecConstants.BIT_AUTHENTICATION_ENABLED,
            ConfigValueFactory.fromAnyRef(true))
        .withValue(ExecConstants.BIT_AUTHENTICATION_MECHANISM,
            ConfigValueFactory.fromAnyRef("kerberos"))
        .withValue(ExecConstants.USE_LOGIN_PRINCIPAL,
            ConfigValueFactory.fromAnyRef(true))
        .withValue(ExecConstants.BIT_ENCRYPTION_SASL_ENABLED,
            ConfigValueFactory.fromAnyRef(true)));

    updateTestCluster(1, newConfig, connectionProps);

    // Run few queries using the new client
    testBuilder()
        .sqlQuery("SELECT session_user FROM (SELECT * FROM sys.drillbits LIMIT 1)")
        .unOrdered()
        .baselineColumns("session_user")
        .baselineValues(krbHelper.CLIENT_SHORT_NAME)
        .go();

    // Check encrypted counters value
    assertTrue(1 == UserRpcMetrics.getInstance().getEncryptedConnectionCount());
    assertTrue(0 == ControlRpcMetrics.getInstance().getEncryptedConnectionCount());
    assertTrue(0 == DataRpcMetrics.getInstance().getEncryptedConnectionCount());

    // Check unencrypted counters value
    assertTrue(0 == UserRpcMetrics.getInstance().getUnEncryptedConnectionCount());
    assertTrue(0 == ControlRpcMetrics.getInstance().getUnEncryptedConnectionCount());
    assertTrue(0 == DataRpcMetrics.getInstance().getUnEncryptedConnectionCount());
  }

  @Test
  public void failurePlainMech() {
    try {
      final Properties connectionProps = new Properties();
      connectionProps.setProperty(DrillProperties.USER, "anonymous");
      connectionProps.setProperty(DrillProperties.PASSWORD, "anything works!");

      newConfig = new DrillConfig(DrillConfig.create(cloneDefaultTestConfigProperties())
        .withValue(ExecConstants.USER_AUTHENTICATION_ENABLED,
          ConfigValueFactory.fromAnyRef(true))
        .withValue(ExecConstants.USER_AUTHENTICATOR_IMPL,
          ConfigValueFactory.fromAnyRef(UserAuthenticatorTestImpl.TYPE))
        .withValue(BootStrapContext.SERVICE_PRINCIPAL,
          ConfigValueFactory.fromAnyRef(krbHelper.SERVER_PRINCIPAL))
        .withValue(BootStrapContext.SERVICE_KEYTAB_LOCATION,
          ConfigValueFactory.fromAnyRef(krbHelper.serverKeytab.toString()))
        .withValue(ExecConstants.AUTHENTICATION_MECHANISMS,
          ConfigValueFactory.fromIterable(Lists.newArrayList("plain", "kerberos")))
        .withValue(ExecConstants.USER_ENCRYPTION_SASL_ENABLED,
          ConfigValueFactory.fromAnyRef(true)));

      updateTestCluster(1, newConfig, connectionProps);
      fail();
    } catch (Exception ex) {
      assert (ex.getCause() instanceof NonTransientRpcException);
      System.out.println("Caught exception: " + ex.getMessage());
      logger.info("Caught exception: " + ex.getMessage());
    }
  }

  @Test
  public void encryptionEnabledWithOnlyPlainMech() {
    try {
      final Properties connectionProps = new Properties();
      connectionProps.setProperty(DrillProperties.SERVICE_PRINCIPAL, krbHelper.SERVER_PRINCIPAL);
      connectionProps.setProperty(DrillProperties.USER, krbHelper.CLIENT_PRINCIPAL);
      connectionProps.setProperty(DrillProperties.KEYTAB, krbHelper.clientKeytab.getAbsolutePath());

      newConfig = new DrillConfig(DrillConfig.create(cloneDefaultTestConfigProperties())
        .withValue(ExecConstants.USER_AUTHENTICATION_ENABLED,
          ConfigValueFactory.fromAnyRef(true))
        .withValue(ExecConstants.USER_AUTHENTICATOR_IMPL,
          ConfigValueFactory.fromAnyRef(UserAuthenticatorTestImpl.TYPE))
        .withValue(BootStrapContext.SERVICE_PRINCIPAL,
          ConfigValueFactory.fromAnyRef(krbHelper.SERVER_PRINCIPAL))
        .withValue(BootStrapContext.SERVICE_KEYTAB_LOCATION,
          ConfigValueFactory.fromAnyRef(krbHelper.serverKeytab.toString()))
        .withValue(ExecConstants.AUTHENTICATION_MECHANISMS,
          ConfigValueFactory.fromIterable(Lists.newArrayList("plain")))
        .withValue(ExecConstants.USER_ENCRYPTION_SASL_ENABLED,
          ConfigValueFactory.fromAnyRef(true)));
      updateTestCluster(1, newConfig, connectionProps);

      fail();
    } catch (Exception ex) {
      assert (ex.getCause() instanceof NonTransientRpcException);
      System.out.println("Caught exception: " + ex.getMessage());
      logger.info("Caught exception: " + ex.getMessage());
    }
  }

  /**
   * Test to validate that older clients are not allowed to connect to secure cluster
   * with encryption enabled.
   */
  @Test
  public void failureOldClientEncryptionEnabled() {
    try {
      final Properties connectionProps = new Properties();
      connectionProps.setProperty(DrillProperties.SERVICE_PRINCIPAL, krbHelper.SERVER_PRINCIPAL);
      connectionProps.setProperty(DrillProperties.USER, krbHelper.CLIENT_PRINCIPAL);
      connectionProps.setProperty(DrillProperties.KEYTAB, krbHelper.clientKeytab.getAbsolutePath());
      connectionProps.setProperty(DrillProperties.TEST_SASL_LEVEL, "1");

      newConfig = new DrillConfig(DrillConfig.create(cloneDefaultTestConfigProperties())
        .withValue(ExecConstants.USER_AUTHENTICATION_ENABLED,
          ConfigValueFactory.fromAnyRef(true))
        .withValue(ExecConstants.USER_AUTHENTICATOR_IMPL,
          ConfigValueFactory.fromAnyRef(UserAuthenticatorTestImpl.TYPE))
        .withValue(BootStrapContext.SERVICE_PRINCIPAL,
          ConfigValueFactory.fromAnyRef(krbHelper.SERVER_PRINCIPAL))
        .withValue(BootStrapContext.SERVICE_KEYTAB_LOCATION,
          ConfigValueFactory.fromAnyRef(krbHelper.serverKeytab.toString()))
        .withValue(ExecConstants.AUTHENTICATION_MECHANISMS,
          ConfigValueFactory.fromIterable(Lists.newArrayList("plain", "kerberos")))
        .withValue(ExecConstants.USER_ENCRYPTION_SASL_ENABLED,
          ConfigValueFactory.fromAnyRef(true)));
      updateTestCluster(1, newConfig, connectionProps);

      fail();
    } catch (Exception ex) {
      assert (ex.getCause() instanceof RpcException);
      System.out.println("Caught exception: " + ex.getMessage());
      logger.info("Caught exception: " + ex.getMessage());
    }
  }

  /**
   * Test to validate that older clients are successfully connecting to secure cluster
   * with encryption disabled.
   */
  @Test
  public void successOldClientEncryptionDisabled() {

    final Properties connectionProps = new Properties();
    connectionProps.setProperty(DrillProperties.SERVICE_PRINCIPAL, krbHelper.SERVER_PRINCIPAL);
    connectionProps.setProperty(DrillProperties.USER, krbHelper.CLIENT_PRINCIPAL);
    connectionProps.setProperty(DrillProperties.KEYTAB, krbHelper.clientKeytab.getAbsolutePath());
    connectionProps.setProperty(DrillProperties.TEST_SASL_LEVEL, "1");

    newConfig = new DrillConfig(DrillConfig.create(cloneDefaultTestConfigProperties())
      .withValue(ExecConstants.USER_AUTHENTICATION_ENABLED,
        ConfigValueFactory.fromAnyRef(true))
      .withValue(ExecConstants.USER_AUTHENTICATOR_IMPL,
        ConfigValueFactory.fromAnyRef(UserAuthenticatorTestImpl.TYPE))
      .withValue(BootStrapContext.SERVICE_PRINCIPAL,
        ConfigValueFactory.fromAnyRef(krbHelper.SERVER_PRINCIPAL))
      .withValue(BootStrapContext.SERVICE_KEYTAB_LOCATION,
        ConfigValueFactory.fromAnyRef(krbHelper.serverKeytab.toString()))
      .withValue(ExecConstants.AUTHENTICATION_MECHANISMS,
        ConfigValueFactory.fromIterable(Lists.newArrayList("plain", "kerberos"))));

    updateTestCluster(1, newConfig, connectionProps);
  }

  /**
   * Test to validate that clients which needs encrypted connection fails to connect
   * to server with encryption disabled.
   */
  @Test
  public void clientNeedsEncryptionWithNoServerSupport() throws Exception {
    try {
      final Properties connectionProps = new Properties();
      connectionProps.setProperty(DrillProperties.SERVICE_PRINCIPAL, krbHelper.SERVER_PRINCIPAL);
      connectionProps.setProperty(DrillProperties.USER, krbHelper.CLIENT_PRINCIPAL);
      connectionProps.setProperty(DrillProperties.KEYTAB, krbHelper.clientKeytab.getAbsolutePath());
      connectionProps.setProperty(DrillProperties.SASL_ENCRYPT, "true");

      newConfig = new DrillConfig(DrillConfig.create(cloneDefaultTestConfigProperties())
        .withValue(ExecConstants.USER_AUTHENTICATION_ENABLED,
          ConfigValueFactory.fromAnyRef(true))
        .withValue(ExecConstants.USER_AUTHENTICATOR_IMPL,
          ConfigValueFactory.fromAnyRef(UserAuthenticatorTestImpl.TYPE))
        .withValue(BootStrapContext.SERVICE_PRINCIPAL,
          ConfigValueFactory.fromAnyRef(krbHelper.SERVER_PRINCIPAL))
        .withValue(BootStrapContext.SERVICE_KEYTAB_LOCATION,
          ConfigValueFactory.fromAnyRef(krbHelper.serverKeytab.toString()))
        .withValue(ExecConstants.AUTHENTICATION_MECHANISMS,
          ConfigValueFactory.fromIterable(Lists.newArrayList("plain", "kerberos"))));

      updateTestCluster(1, newConfig, connectionProps);

      fail();
    } catch (Exception ex) {
      assert (ex.getCause() instanceof NonTransientRpcException);
    }
  }

  /**
   * Test to validate that clients which needs encrypted connection connects
   * to server with encryption enabled.
   */
  @Test
  public void clientNeedsEncryptionWithServerSupport() throws Exception {
    try {
      final Properties connectionProps = new Properties();
      connectionProps.setProperty(DrillProperties.SERVICE_PRINCIPAL, krbHelper.SERVER_PRINCIPAL);
      connectionProps.setProperty(DrillProperties.USER, krbHelper.CLIENT_PRINCIPAL);
      connectionProps.setProperty(DrillProperties.KEYTAB, krbHelper.clientKeytab.getAbsolutePath());
      connectionProps.setProperty(DrillProperties.SASL_ENCRYPT, "true");

      newConfig = new DrillConfig(DrillConfig.create(cloneDefaultTestConfigProperties())
        .withValue(ExecConstants.USER_AUTHENTICATION_ENABLED,
          ConfigValueFactory.fromAnyRef(true))
        .withValue(ExecConstants.USER_AUTHENTICATOR_IMPL,
          ConfigValueFactory.fromAnyRef(UserAuthenticatorTestImpl.TYPE))
        .withValue(BootStrapContext.SERVICE_PRINCIPAL,
          ConfigValueFactory.fromAnyRef(krbHelper.SERVER_PRINCIPAL))
        .withValue(BootStrapContext.SERVICE_KEYTAB_LOCATION,
          ConfigValueFactory.fromAnyRef(krbHelper.serverKeytab.toString()))
        .withValue(ExecConstants.AUTHENTICATION_MECHANISMS,
          ConfigValueFactory.fromIterable(Lists.newArrayList("plain", "kerberos")))
        .withValue(ExecConstants.USER_ENCRYPTION_SASL_ENABLED,
              ConfigValueFactory.fromAnyRef(true)));

      updateTestCluster(1, newConfig, connectionProps);
    } catch (Exception ex) {
      fail();
      assert (ex.getCause() instanceof NonTransientRpcException);
    }
  }
}
