/*
 * 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.hive.metastore;

import java.io.IOException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.permission.AclEntry;
import org.apache.hadoop.fs.permission.AclStatus;
import static org.apache.hadoop.fs.permission.AclEntryScope.ACCESS;
import static org.apache.hadoop.fs.permission.AclEntryType.GROUP;
import org.apache.hadoop.hdfs.MiniDFSCluster;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.metastore.ReplChangeManager.RecycleType;

import org.apache.hadoop.hive.metastore.api.FieldSchema;
import org.apache.hadoop.hive.metastore.api.Table;
import org.apache.hadoop.hive.metastore.utils.EncryptionZoneUtils;
import org.apache.hadoop.util.StringUtils;
import org.apache.hadoop.hdfs.DFSTestUtil;
import org.apache.hadoop.ipc.RemoteException;
import org.apache.hadoop.hive.metastore.client.builder.DatabaseBuilder;
import org.apache.hadoop.hive.metastore.client.builder.TableBuilder;
import org.apache.hadoop.hive.metastore.api.Type;
import org.apache.hadoop.hive.metastore.api.NoSuchObjectException;
import org.apache.hadoop.hive.metastore.api.InvalidOperationException;
import org.apache.hadoop.hive.metastore.api.MetaException;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.thrift.TException;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;

/**
 * TestMetaStoreAuthorization.
 */
public class TestMetaStoreMultipleEncryptionZones {
  private static HiveMetaStoreClient client;
  private static HiveConf hiveConf;
  private static Configuration conf;
  private static Warehouse warehouse;
  private static FileSystem warehouseFs;
  private static MiniDFSCluster miniDFSCluster;
  private static String cmroot;
  private static FileSystem fs;
  private static String cmrootEncrypted;
  private static String jksFile = System.getProperty("java.io.tmpdir") + "/test.jks";
  private static String cmrootFallBack;

  @BeforeClass
  public static void setUp() throws Exception {
    //Create secure cluster
    conf = new Configuration();
    conf.set("hadoop.security.key.provider.path", "jceks://file" + jksFile);
    conf.set("dfs.namenode.acls.enabled", "true");
    miniDFSCluster = new MiniDFSCluster.Builder(conf).numDataNodes(1).format(true).build();
    DFSTestUtil.createKey("test_key_cm", miniDFSCluster, conf);
    DFSTestUtil.createKey("test_key_db", miniDFSCluster, conf);
    hiveConf = new HiveConf(TestReplChangeManager.class);
    hiveConf.setBoolean(HiveConf.ConfVars.REPLCMENABLED.varname, true);
    hiveConf.setInt(CommonConfigurationKeysPublic.FS_TRASH_INTERVAL_KEY, 60);
    hiveConf.set(HiveConf.ConfVars.METASTOREWAREHOUSE.varname,
            "hdfs://" + miniDFSCluster.getNameNode().getHostAndPort()
                    + HiveConf.ConfVars.METASTOREWAREHOUSE.defaultStrVal);

    cmroot = "hdfs://" + miniDFSCluster.getNameNode().getHostAndPort() + "/cmroot";
    cmrootFallBack = "hdfs://" + miniDFSCluster.getNameNode().getHostAndPort() + "/cmrootFallback";
    cmrootEncrypted = "cmrootEncrypted";
    hiveConf.set(HiveConf.ConfVars.REPLCMDIR.varname, cmroot);
    hiveConf.set(HiveConf.ConfVars.REPLCMENCRYPTEDDIR.varname, cmrootEncrypted);
    hiveConf.set(HiveConf.ConfVars.REPLCMFALLBACKNONENCRYPTEDDIR.varname, cmrootFallBack);
    initReplChangeManager();

    try {
      client = new HiveMetaStoreClient(hiveConf);
    } catch (Throwable e) {
      System.err.println("Unable to open the metastore");
      System.err.println(StringUtils.stringifyException(e));
      throw e;
    }
  }

  private static void initReplChangeManager() throws Exception{
    warehouse = new Warehouse(hiveConf);
    warehouseFs = warehouse.getWhRoot().getFileSystem(hiveConf);
    fs = new Path(cmroot).getFileSystem(hiveConf);
    fs.mkdirs(warehouse.getWhRoot());
  }

  @AfterClass
  public static void tearDown() throws Exception {
    try {
      miniDFSCluster.shutdown();
      client.close();
    } catch (Throwable e) {
      System.err.println("Unable to close metastore");
      System.err.println(StringUtils.stringifyException(e));
      throw e;
    }
  }

  @Test
  public void dropTableWithDifferentEncryptionZonesDifferentKey() throws Throwable {
    String dbName1 = "encrdbdiffkey1";
    String dbName2 = "encrdbdiffkey2";
    String tblName1 = "encrtbl1";
    String tblName2 = "encrtbl2";
    String typeName = "Person";

    silentDropDatabase(dbName1);
    silentDropDatabase(dbName2);
    new DatabaseBuilder()
            .setName(dbName1)
            .addParam("repl.source.for", "1, 2, 3")
            .create(client, hiveConf);

    new DatabaseBuilder()
            .setName(dbName2)
            .addParam("repl.source.for", "1, 2, 3")
            .create(client, hiveConf);

    client.dropType(typeName);
    Type typ1 = new Type();
    typ1.setName(typeName);
    typ1.setFields(new ArrayList<>(2));
    typ1.getFields().add(
            new FieldSchema("name", ColumnType.STRING_TYPE_NAME, ""));
    typ1.getFields().add(
            new FieldSchema("income", ColumnType.INT_TYPE_NAME, ""));
    client.createType(typ1);

    Path dirDb1 = new Path(warehouse.getWhRoot(), dbName1 +".db");
    warehouseFs.delete(dirDb1, true);
    warehouseFs.mkdirs(dirDb1);
    EncryptionZoneUtils.createEncryptionZone(dirDb1, "test_key_db", conf);
    Path dirTbl1 = new Path(dirDb1, tblName1);
    warehouseFs.mkdirs(dirTbl1);
    Path part11 = new Path(dirTbl1, "part1");
    createFile(part11, "testClearer11");

    Path dirDb2 = new Path(warehouse.getWhRoot(), dbName2 +".db");
    warehouseFs.delete(dirDb2, true);
    warehouseFs.mkdirs(dirDb2);
    EncryptionZoneUtils.createEncryptionZone(dirDb2, "test_key_cm", conf);
    Path dirTbl2 = new Path(dirDb2, tblName2);
    warehouseFs.mkdirs(dirTbl2);
    Path part12 = new Path(dirTbl2, "part1");
    createFile(part12, "testClearer12");

    new TableBuilder()
            .setDbName(dbName1)
            .setTableName(tblName1)
            .setCols(typ1.getFields())
            .setNumBuckets(1)
            .addBucketCol("name")
            .addStorageDescriptorParam("test_param_1", "Use this for comments etc")
            .create(client, hiveConf);

    Table tbl = client.getTable(dbName1, tblName1);
    Assert.assertNotNull(tbl);

    new TableBuilder()
            .setDbName(dbName2)
            .setTableName(tblName2)
            .setCols(typ1.getFields())
            .setNumBuckets(1)
            .addBucketCol("name")
            .addStorageDescriptorParam("test_param_1", "Use this for comments etc")
            .create(client, hiveConf);

    boolean exceptionThrown = false;
    try {
      client.dropTable(dbName1, tblName1);
    } catch (MetaException e) {
      exceptionThrown = true;
      assertTrue(e.getMessage().contains("can't be moved from encryption zone"));
    }
    assertFalse(exceptionThrown);
    assertFalse(warehouseFs.exists(part11));
    try {
      client.getTable(dbName1, tblName1);
    } catch (NoSuchObjectException e) {
      exceptionThrown = true;
    }
    assertTrue(exceptionThrown);
    exceptionThrown = false;
    try {
      client.dropTable(dbName2, tblName2);
    } catch (MetaException e) {
      exceptionThrown = true;
      assertTrue(e.getMessage().contains("can't be moved from encryption zone"));
    }
    assertFalse(exceptionThrown);
    assertFalse(warehouseFs.exists(part12));
    try {
      client.getTable(dbName2, tblName2);
    } catch (NoSuchObjectException e) {
      exceptionThrown = true;
    }
    assertTrue(exceptionThrown);


  }

  @Test
  public void dropTableWithTableAtEncryptionZoneRoot() throws Throwable {
    String dbName = "encrdbroot";
    String tblName1 = "encrtbl1";
    String tblName2 = "encrtbl2";
    String typeName = "Person";

    silentDropDatabase(dbName);
    new DatabaseBuilder()
            .setName(dbName)
            .addParam("repl.source.for", "1, 2, 3")
            .create(client, hiveConf);

    client.dropType(typeName);
    Type typ1 = new Type();
    typ1.setName(typeName);
    typ1.setFields(new ArrayList<>(2));
    typ1.getFields().add(
            new FieldSchema("name", ColumnType.STRING_TYPE_NAME, ""));
    typ1.getFields().add(
            new FieldSchema("income", ColumnType.INT_TYPE_NAME, ""));
    client.createType(typ1);

    new TableBuilder()
            .setDbName(dbName)
            .setTableName(tblName1)
            .setCols(typ1.getFields())
            .setNumBuckets(1)
            .addBucketCol("name")
            .addStorageDescriptorParam("test_param_1", "Use this for comments etc")
            .create(client, hiveConf);

    Table tbl = client.getTable(dbName, tblName1);
    Assert.assertNotNull(tbl);

    new TableBuilder()
            .setDbName(dbName)
            .setTableName(tblName2)
            .setCols(typ1.getFields())
            .setNumBuckets(1)
            .addBucketCol("name")
            .addStorageDescriptorParam("test_param_1", "Use this for comments etc")
            .create(client, hiveConf);

    Path dirDb = new Path(warehouse.getWhRoot(), dbName +".db");
    warehouseFs.mkdirs(dirDb);
    Path dirTbl1 = new Path(dirDb, tblName1);
    warehouseFs.mkdirs(dirTbl1);
    EncryptionZoneUtils.createEncryptionZone(dirTbl1, "test_key_db", conf);
    Path part11 = new Path(dirTbl1, "part1");
    createFile(part11, "testClearer11");

    Path dirTbl2 = new Path(dirDb, tblName2);
    warehouseFs.mkdirs(dirTbl2);
    EncryptionZoneUtils.createEncryptionZone(dirTbl2, "test_key_cm", conf);
    Path part12 = new Path(dirTbl2, "part1");
    createFile(part12, "testClearer12");

    boolean exceptionThrown = false;
    try {
      client.dropTable(dbName, tblName1);
    } catch (MetaException e) {
      exceptionThrown = true;
      assertTrue(e.getMessage().contains("can't be moved from encryption zone"));
    }
    assertFalse(exceptionThrown);
    assertFalse(warehouseFs.exists(part11));
    try {
      client.getTable(dbName, tblName1);
    } catch (NoSuchObjectException e) {
      exceptionThrown = true;
    }
    assertTrue(exceptionThrown);
    exceptionThrown = false;
    try {
      client.dropTable(dbName, tblName2);
    } catch (MetaException e) {
      exceptionThrown = true;
      assertTrue(e.getMessage().contains("can't be moved from encryption zone"));
    }
    assertFalse(exceptionThrown);
    assertFalse(warehouseFs.exists(part12));
    try {
      client.getTable(dbName, tblName2);
    } catch (NoSuchObjectException e) {
      exceptionThrown = true;
    }
    assertTrue(exceptionThrown);
    assertTrue(warehouseFs.exists(new Path(dirTbl1, cmrootEncrypted)));
    assertTrue(warehouseFs.exists(new Path(dirTbl2, cmrootEncrypted)));
  }

  @Test
  public void dropTableWithDifferentEncryptionZonesSameKey() throws Throwable {
    String dbName1 = "encrdbsamekey1";
    String dbName2 = "encrdbsamekey2";
    String tblName1 = "encrtbl1";
    String tblName2 = "encrtbl2";
    String typeName = "Person";

    silentDropDatabase(dbName1);
    silentDropDatabase(dbName2);
    new DatabaseBuilder()
            .setName(dbName1)
            .addParam("repl.source.for", "1, 2, 3")
            .create(client, hiveConf);

    new DatabaseBuilder()
            .setName(dbName2)
            .addParam("repl.source.for", "1, 2, 3")
            .create(client, hiveConf);

    client.dropType(typeName);
    Type typ1 = new Type();
    typ1.setName(typeName);
    typ1.setFields(new ArrayList<>(2));
    typ1.getFields().add(
            new FieldSchema("name", ColumnType.STRING_TYPE_NAME, ""));
    typ1.getFields().add(
            new FieldSchema("income", ColumnType.INT_TYPE_NAME, ""));
    client.createType(typ1);

    Path dirDb1 = new Path(warehouse.getWhRoot(), dbName1 +".db");
    warehouseFs.mkdirs(dirDb1);
    EncryptionZoneUtils.createEncryptionZone(dirDb1, "test_key_db", conf);
    Path dirTbl1 = new Path(dirDb1, tblName1);
    warehouseFs.mkdirs(dirTbl1);
    Path part11 = new Path(dirTbl1, "part1");
    createFile(part11, "testClearer11");

    Path dirDb2 = new Path(warehouse.getWhRoot(), dbName2 +".db");
    warehouseFs.mkdirs(dirDb2);
    EncryptionZoneUtils.createEncryptionZone(dirDb2, "test_key_db", conf);
    Path dirTbl2 = new Path(dirDb2, tblName2);
    warehouseFs.mkdirs(dirTbl2);
    Path part12 = new Path(dirTbl2, "part1");
    createFile(part12, "testClearer12");

    new TableBuilder()
            .setDbName(dbName1)
            .setTableName(tblName1)
            .setCols(typ1.getFields())
            .setNumBuckets(1)
            .addBucketCol("name")
            .addStorageDescriptorParam("test_param_1", "Use this for comments etc")
            .create(client, hiveConf);

    Table tbl = client.getTable(dbName1, tblName1);
    Assert.assertNotNull(tbl);

    new TableBuilder()
            .setDbName(dbName2)
            .setTableName(tblName2)
            .setCols(typ1.getFields())
            .setNumBuckets(1)
            .addBucketCol("name")
            .addStorageDescriptorParam("test_param_1", "Use this for comments etc")
            .create(client, hiveConf);

    boolean exceptionThrown = false;
    try {
      client.dropTable(dbName1, tblName1);
    } catch (MetaException e) {
      exceptionThrown = true;
      assertTrue(e.getMessage().contains("can't be moved from encryption zone"));
    }
    assertFalse(exceptionThrown);
    assertFalse(warehouseFs.exists(part11));
    try {
      client.getTable(dbName1, tblName1);
    } catch (NoSuchObjectException e) {
      exceptionThrown = true;
    }
    assertTrue(exceptionThrown);
    exceptionThrown = false;
    try {
      client.dropTable(dbName2, tblName2);
    } catch (MetaException e) {
      exceptionThrown = true;
      assertTrue(e.getMessage().contains("can't be moved from encryption zone"));
    }
    assertFalse(exceptionThrown);
    assertFalse(warehouseFs.exists(part12));
    try {
      client.getTable(dbName2, tblName2);
    } catch (NoSuchObjectException e) {
      exceptionThrown = true;
    }
    assertTrue(exceptionThrown);

  }

  @Test
  public void dropTableWithSameEncryptionZones() throws Throwable {
    String dbName = "encrdb3";
    String tblName1 = "encrtbl1";
    String tblName2 = "encrtbl2";
    String typeName = "Person";
    silentDropDatabase(dbName);

    new DatabaseBuilder()
            .setName(dbName)
            .addParam("repl.source.for", "1, 2, 3")
            .create(client, hiveConf);

    client.dropType(typeName);
    Type typ1 = new Type();
    typ1.setName(typeName);
    typ1.setFields(new ArrayList<>(2));
    typ1.getFields().add(
            new FieldSchema("name", ColumnType.STRING_TYPE_NAME, ""));
    typ1.getFields().add(
            new FieldSchema("income", ColumnType.INT_TYPE_NAME, ""));
    client.createType(typ1);

    new TableBuilder()
            .setDbName(dbName)
            .setTableName(tblName1)
            .setCols(typ1.getFields())
            .setNumBuckets(1)
            .addBucketCol("name")
            .addStorageDescriptorParam("test_param_1", "Use this for comments etc")
            .create(client, hiveConf);

    Table tbl = client.getTable(dbName, tblName1);
    Assert.assertNotNull(tbl);

    new TableBuilder()
            .setDbName(dbName)
            .setTableName(tblName2)
            .setCols(typ1.getFields())
            .setNumBuckets(1)
            .addBucketCol("name")
            .addStorageDescriptorParam("test_param_1", "Use this for comments etc")
            .create(client, hiveConf);

    Path dirDb = new Path(warehouse.getWhRoot(), dbName +".db");
    warehouseFs.delete(dirDb, true);
    warehouseFs.mkdirs(dirDb);
    EncryptionZoneUtils.createEncryptionZone(dirDb, "test_key_db", conf);
    Path dirTbl1 = new Path(dirDb, tblName1);
    warehouseFs.mkdirs(dirTbl1);
    Path part11 = new Path(dirTbl1, "part1");
    createFile(part11, "testClearer11");

    Path dirTbl2 = new Path(dirDb, tblName2);
    warehouseFs.mkdirs(dirTbl2);
    Path part12 = new Path(dirTbl2, "part1");
    createFile(part12, "testClearer12");

    boolean exceptionThrown = false;
    try {
      client.dropTable(dbName, tblName1);
    } catch (MetaException e) {
      exceptionThrown = true;
      assertTrue(e.getMessage().contains("can't be moved from encryption zone"));
    }
    assertFalse(exceptionThrown);
    assertFalse(warehouseFs.exists(part11));
    try {
      client.getTable(dbName, tblName1);
    } catch (NoSuchObjectException e) {
      exceptionThrown = true;
    }
    assertTrue(exceptionThrown);
    exceptionThrown = false;
    try {
      client.dropTable(dbName, tblName2);
    } catch (MetaException e) {
      exceptionThrown = true;
      assertTrue(e.getMessage().contains("can't be moved from encryption zone"));
    }
    assertFalse(exceptionThrown);
    assertFalse(warehouseFs.exists(part12));
    try {
      client.getTable(dbName, tblName2);
    } catch (NoSuchObjectException e) {
      exceptionThrown = true;
    }
    assertTrue(exceptionThrown);
  }

  @Test
  public void dropTableWithoutEncryptionZonesForCm() throws Throwable {
    String dbName = "simpdb1";
    String tblName = "simptbl";
    String typeName = "Person";
    silentDropDatabase(dbName);
    new DatabaseBuilder()
            .setName(dbName)
            .addParam("repl.source.for", "1, 2, 3")
            .create(client, hiveConf);

    client.dropType(typeName);
    Type typ1 = new Type();
    typ1.setName(typeName);
    typ1.setFields(new ArrayList<>(2));
    typ1.getFields().add(
            new FieldSchema("name", ColumnType.STRING_TYPE_NAME, ""));
    typ1.getFields().add(
            new FieldSchema("income", ColumnType.INT_TYPE_NAME, ""));
    client.createType(typ1);

    new TableBuilder()
            .setDbName(dbName)
            .setTableName(tblName)
            .setCols(typ1.getFields())
            .setNumBuckets(1)
            .addBucketCol("name")
            .addStorageDescriptorParam("test_param_1", "Use this for comments etc")
            .create(client, hiveConf);

    Table tbl = client.getTable(dbName, tblName);
    Assert.assertNotNull(tbl);

    Path dirDb = new Path(warehouse.getWhRoot(), dbName +".db");
    warehouseFs.mkdirs(dirDb);
    Path dirTbl1 = new Path(dirDb, tblName);
    warehouseFs.mkdirs(dirTbl1);
    Path part11 = new Path(dirTbl1, "part1");
    createFile(part11, "testClearer11");

    boolean exceptionThrown = false;
    try {
      client.dropTable(dbName, tblName);
    } catch (Exception e) {
      exceptionThrown = true;
    }
    assertFalse(exceptionThrown);
    assertFalse(warehouseFs.exists(part11));
    try {
      client.getTable(dbName, tblName);
    } catch (NoSuchObjectException e) {
      exceptionThrown = true;
    }
    assertTrue(exceptionThrown);
  }

  @Test
  public void dropExternalTableWithSameEncryptionZonesForCm() throws Throwable {
    String dbName = "encrdb4";
    String tblName1 = "encrtbl1";
    String tblName2 = "encrtbl2";
    String typeName = "Person";
    silentDropDatabase(dbName);
    new DatabaseBuilder()
            .setName(dbName)
            .addParam("repl.source.for", "1, 2, 3")
            .create(client, hiveConf);

    client.dropType(typeName);
    Type typ1 = new Type();
    typ1.setName(typeName);
    typ1.setFields(new ArrayList<>(2));
    typ1.getFields().add(
            new FieldSchema("name", ColumnType.STRING_TYPE_NAME, ""));
    typ1.getFields().add(
            new FieldSchema("income", ColumnType.INT_TYPE_NAME, ""));
    client.createType(typ1);

    new TableBuilder()
            .setDbName(dbName)
            .setTableName(tblName1)
            .setCols(typ1.getFields())
            .setNumBuckets(1)
            .addBucketCol("name")
            .addTableParam("EXTERNAL", "true")
            .addTableParam("external.table.purge", "true")
            .addStorageDescriptorParam("test_param_1", "Use this for comments etc")
            .create(client, hiveConf);

    Table tbl = client.getTable(dbName, tblName1);
    Assert.assertNotNull(tbl);

    new TableBuilder()
            .setDbName(dbName)
            .setTableName(tblName2)
            .setCols(typ1.getFields())
            .setNumBuckets(1)
            .addBucketCol("name")
            .addTableParam("EXTERNAL", "true")
            .addTableParam("external.table.purge", "true")
            .addStorageDescriptorParam("test_param_1", "Use this for comments etc")
            .create(client, hiveConf);

    Path dirDb = new Path(warehouse.getWhRoot(), dbName +".db");
    warehouseFs.delete(dirDb, true);
    warehouseFs.mkdirs(dirDb);
    EncryptionZoneUtils.createEncryptionZone(dirDb, "test_key_db", conf);
    Path dirTbl1 = new Path(dirDb, tblName1);
    warehouseFs.mkdirs(dirTbl1);
    Path part11 = new Path(dirTbl1, "part1");
    createFile(part11, "testClearer11");

    Path dirTbl2 = new Path(dirDb, tblName2);
    warehouseFs.mkdirs(dirTbl2);
    Path part12 = new Path(dirTbl2, "part1");
    createFile(part12, "testClearer12");

    boolean exceptionThrown = false;
    try {
      client.dropTable(dbName, tblName1);
    } catch (MetaException e) {
      exceptionThrown = true;
    }
    assertFalse(exceptionThrown);
    assertFalse(warehouseFs.exists(part11));
    try {
      client.getTable(dbName, tblName1);
    } catch (NoSuchObjectException e) {
      exceptionThrown = true;
    }
    assertTrue(exceptionThrown);
    exceptionThrown = false;
    try {
      client.dropTable(dbName, tblName2);
    } catch (MetaException e) {
      exceptionThrown = true;
    }
    assertFalse(exceptionThrown);
    assertFalse(warehouseFs.exists(part11));
    try {
      client.getTable(dbName, tblName2);
    } catch (NoSuchObjectException e) {
      exceptionThrown = true;
    }
    assertTrue(exceptionThrown);
  }

  @Test
  public void dropExternalTableWithDifferentEncryptionZones() throws Throwable {
    String dbName = "encrdb5";
    String tblName1 = "encrtbl1";
    String tblName2 = "encrtbl2";
    String typeName = "Person";

    silentDropDatabase(dbName);
    new DatabaseBuilder()
            .setName(dbName)
            .addParam("repl.source.for", "1, 2, 3")
            .create(client, hiveConf);

    client.dropType(typeName);
    Type typ1 = new Type();
    typ1.setName(typeName);
    typ1.setFields(new ArrayList<>(2));
    typ1.getFields().add(
            new FieldSchema("name", ColumnType.STRING_TYPE_NAME, ""));
    typ1.getFields().add(
            new FieldSchema("income", ColumnType.INT_TYPE_NAME, ""));
    client.createType(typ1);

    new TableBuilder()
            .setDbName(dbName)
            .setTableName(tblName1)
            .setCols(typ1.getFields())
            .setNumBuckets(1)
            .addBucketCol("name")
            .addTableParam("EXTERNAL", "true")
            .addTableParam("external.table.purge", "true")
            .addStorageDescriptorParam("test_param_1", "Use this for comments etc")
            .create(client, hiveConf);

    Table tbl = client.getTable(dbName, tblName1);
    Assert.assertNotNull(tbl);

    new TableBuilder()
            .setDbName(dbName)
            .setTableName(tblName2)
            .setCols(typ1.getFields())
            .setNumBuckets(1)
            .addBucketCol("name")
            .addTableParam("EXTERNAL", "true")
            .addTableParam("external.table.purge", "true")
            .addStorageDescriptorParam("test_param_1", "Use this for comments etc")
            .create(client, hiveConf);

    Path dirDb = new Path(warehouse.getWhRoot(), dbName +".db");
    warehouseFs.mkdirs(dirDb);
    Path dirTbl1 = new Path(dirDb, tblName1);
    warehouseFs.mkdirs(dirTbl1);
    EncryptionZoneUtils.createEncryptionZone(dirTbl1, "test_key_db", conf);
    Path part11 = new Path(dirTbl1, "part1");
    createFile(part11, "testClearer11");

    Path dirTbl2 = new Path(dirDb, tblName2);
    warehouseFs.mkdirs(dirTbl2);
    EncryptionZoneUtils.createEncryptionZone(dirTbl2, "test_key_db", conf);
    Path part12 = new Path(dirTbl2, "part1");
    createFile(part12, "testClearer12");

    boolean exceptionThrown = false;
    try {
      client.dropTable(dbName, tblName1);
    } catch (MetaException e) {
      exceptionThrown = true;
    }
    assertFalse(exceptionThrown);
    assertFalse(warehouseFs.exists(part11));
    try {
      client.getTable(dbName, tblName1);
    } catch (NoSuchObjectException e) {
      exceptionThrown = true;
    }
    assertTrue(exceptionThrown);
    exceptionThrown = false;
    try {
      client.dropTable(dbName, tblName2);
    } catch (MetaException e) {
      exceptionThrown = true;
    }
    assertFalse(exceptionThrown);
    assertFalse(warehouseFs.exists(part12));
    try {
      client.getTable(dbName, tblName2);
    } catch (NoSuchObjectException e) {
      exceptionThrown = true;
    }
    assertTrue(exceptionThrown);
  }

  @Test
  public void dropExternalTableWithDifferentEncryptionZonesDifferentKey() throws Throwable {
    String dbName = "encrdb6";
    String tblName1 = "encrtbl1";
    String tblName2 = "encrtbl2";
    String typeName = "Person";

    silentDropDatabase(dbName);
    new DatabaseBuilder()
            .setName(dbName)
            .addParam("repl.source.for", "1, 2, 3")
            .create(client, hiveConf);

    client.dropType(typeName);
    Type typ1 = new Type();
    typ1.setName(typeName);
    typ1.setFields(new ArrayList<>(2));
    typ1.getFields().add(
            new FieldSchema("name", ColumnType.STRING_TYPE_NAME, ""));
    typ1.getFields().add(
            new FieldSchema("income", ColumnType.INT_TYPE_NAME, ""));
    client.createType(typ1);

    new TableBuilder()
            .setDbName(dbName)
            .setTableName(tblName1)
            .setCols(typ1.getFields())
            .setNumBuckets(1)
            .addBucketCol("name")
            .addTableParam("EXTERNAL", "true")
            .addTableParam("external.table.purge", "true")
            .addStorageDescriptorParam("test_param_1", "Use this for comments etc")
            .create(client, hiveConf);

    Table tbl = client.getTable(dbName, tblName1);
    Assert.assertNotNull(tbl);

    new TableBuilder()
            .setDbName(dbName)
            .setTableName(tblName2)
            .setCols(typ1.getFields())
            .setNumBuckets(1)
            .addBucketCol("name")
            .addTableParam("EXTERNAL", "true")
            .addTableParam("external.table.purge", "true")
            .addStorageDescriptorParam("test_param_1", "Use this for comments etc")
            .create(client, hiveConf);

    Path dirDb = new Path(warehouse.getWhRoot(), dbName +".db");
    warehouseFs.mkdirs(dirDb);
    Path dirTbl1 = new Path(dirDb, tblName1);
    warehouseFs.mkdirs(dirTbl1);
    EncryptionZoneUtils.createEncryptionZone(dirTbl1, "test_key_db", conf);
    Path part11 = new Path(dirTbl1, "part1");
    createFile(part11, "testClearer11");

    Path dirTbl2 = new Path(dirDb, tblName2);
    warehouseFs.mkdirs(dirTbl2);
    EncryptionZoneUtils.createEncryptionZone(dirTbl2, "test_key_cm", conf);
    Path part12 = new Path(dirTbl2, "part1");
    createFile(part12, "testClearer12");

    boolean exceptionThrown = false;
    try {
      client.dropTable(dbName, tblName1);
    } catch (MetaException e) {
      exceptionThrown = true;
    }
    assertFalse(exceptionThrown);
    assertFalse(warehouseFs.exists(part11));
    try {
      client.getTable(dbName, tblName1);
    } catch (NoSuchObjectException e) {
      exceptionThrown = true;
    }
    assertTrue(exceptionThrown);
    exceptionThrown = false;
    try {
      client.dropTable(dbName, tblName2);
    } catch (MetaException e) {
      exceptionThrown = true;
    }
    assertFalse(exceptionThrown);
    assertFalse(warehouseFs.exists(part12));
    try {
      client.getTable(dbName, tblName2);
    } catch (NoSuchObjectException e) {
      exceptionThrown = true;
    }
    assertTrue(exceptionThrown);
  }

  @Test
  public void dropExternalTableWithoutEncryptionZonesForCm() throws Throwable {
    String dbName = "simpdb2";
    String tblName = "simptbl";
    String typeName = "Person";
    silentDropDatabase(dbName);
    new DatabaseBuilder()
            .setName(dbName)
            .addParam("repl.source.for", "1, 2, 3")
            .create(client, hiveConf);

    client.dropType(typeName);
    Type typ1 = new Type();
    typ1.setName(typeName);
    typ1.setFields(new ArrayList<>(2));
    typ1.getFields().add(
            new FieldSchema("name", ColumnType.STRING_TYPE_NAME, ""));
    typ1.getFields().add(
            new FieldSchema("income", ColumnType.INT_TYPE_NAME, ""));
    client.createType(typ1);

    new TableBuilder()
            .setDbName(dbName)
            .setTableName(tblName)
            .setCols(typ1.getFields())
            .setNumBuckets(1)
            .addBucketCol("name")
            .addTableParam("EXTERNAL", "true")
            .addTableParam("external.table.purge", "true")
            .addStorageDescriptorParam("test_param_1", "Use this for comments etc")
            .create(client, hiveConf);

    Table tbl = client.getTable(dbName, tblName);
    Assert.assertNotNull(tbl);

    Path dirDb = new Path(warehouse.getWhRoot(), dbName +".db");
    warehouseFs.mkdirs(dirDb);
    Path dirTbl1 = new Path(dirDb, tblName);
    warehouseFs.mkdirs(dirTbl1);
    Path part11 = new Path(dirTbl1, "part1");
    createFile(part11, "testClearer11");

    boolean exceptionThrown = false;
    try {
      client.dropTable(dbName, tblName);
    } catch (Exception e) {
      exceptionThrown = true;
    }
    assertFalse(exceptionThrown);
    assertFalse(warehouseFs.exists(part11));
    try {
      client.getTable(dbName, tblName);
    } catch (NoSuchObjectException e) {
      exceptionThrown = true;
    }
    assertTrue(exceptionThrown);
  }

  @Test
  public void truncateTableWithDifferentEncryptionZones() throws Throwable {
    String dbName1 = "encrdbtrunc1";
    String dbName2 = "encrdbtrunc2";
    String tblName1 = "encrtbl1";
    String tblName2 = "encrtbl2";
    String typeName = "Person";

    silentDropDatabase(dbName1);
    silentDropDatabase(dbName2);
    new DatabaseBuilder()
            .setName(dbName1)
            .addParam("repl.source.for", "1, 2, 3")
            .create(client, hiveConf);

    new DatabaseBuilder()
            .setName(dbName2)
            .addParam("repl.source.for", "1, 2, 3")
            .create(client, hiveConf);

    client.dropType(typeName);
    Type typ1 = new Type();
    typ1.setName(typeName);
    typ1.setFields(new ArrayList<>(2));
    typ1.getFields().add(
            new FieldSchema("name", ColumnType.STRING_TYPE_NAME, ""));
    typ1.getFields().add(
            new FieldSchema("income", ColumnType.INT_TYPE_NAME, ""));
    client.createType(typ1);

    Path dirDb1 = new Path(warehouse.getWhRoot(), dbName1 +".db");
    warehouseFs.delete(dirDb1, true);
    warehouseFs.mkdirs(dirDb1);
    EncryptionZoneUtils.createEncryptionZone(dirDb1, "test_key_db", conf);
    Path dirTbl1 = new Path(dirDb1, tblName1);
    warehouseFs.mkdirs(dirTbl1);
    Path part11 = new Path(dirTbl1, "part1");
    createFile(part11, "testClearer11");

    Path dirDb2 = new Path(warehouse.getWhRoot(), dbName2 +".db");
    warehouseFs.delete(dirDb2, true);
    warehouseFs.mkdirs(dirDb2);
    EncryptionZoneUtils.createEncryptionZone(dirDb2, "test_key_db", conf);
    Path dirTbl2 = new Path(dirDb2, tblName2);
    warehouseFs.mkdirs(dirTbl2);
    Path part12 = new Path(dirTbl2, "part1");
    createFile(part12, "testClearer12");

    new TableBuilder()
            .setDbName(dbName1)
            .setTableName(tblName1)
            .setCols(typ1.getFields())
            .setNumBuckets(1)
            .addBucketCol("name")
            .addStorageDescriptorParam("test_param_1", "Use this for comments etc")
            .create(client, hiveConf);

    Table tbl = client.getTable(dbName1, tblName1);
    Assert.assertNotNull(tbl);

    new TableBuilder()
            .setDbName(dbName2)
            .setTableName(tblName2)
            .setCols(typ1.getFields())
            .setNumBuckets(1)
            .addBucketCol("name")
            .addStorageDescriptorParam("test_param_1", "Use this for comments etc")
            .create(client, hiveConf);

    boolean exceptionThrown = false;
    try {
      client.truncateTable(dbName1, tblName1, null);
    } catch (MetaException e) {
      exceptionThrown = true;
      assertTrue(e.getMessage().contains("can't be moved from encryption zone"));
    }
    assertFalse(exceptionThrown);
    assertFalse(warehouseFs.exists(part11));
    assertNotNull(client.getTable(dbName1, tblName1));
    exceptionThrown = false;
    try {
      client.truncateTable(dbName2, tblName2, null);
    } catch (MetaException e) {
      exceptionThrown = true;
      assertTrue(e.getMessage().contains("can't be moved from encryption zone"));
    }
    assertFalse(exceptionThrown);
    assertFalse(warehouseFs.exists(part12));
    assertNotNull(client.getTable(dbName2, tblName2));
  }

  @Test
  public void truncateTableWithDifferentEncryptionZonesDifferentKey() throws Throwable {
    String dbName1 = "encrdb1";
    String dbName2 = "encrdb2";
    String tblName1 = "encrtbl1";
    String tblName2 = "encrtbl2";
    String typeName = "Person";

    silentDropDatabase(dbName1);
    silentDropDatabase(dbName2);
    new DatabaseBuilder()
            .setName(dbName1)
            .addParam("repl.source.for", "1, 2, 3")
            .create(client, hiveConf);

    new DatabaseBuilder()
            .setName(dbName2)
            .addParam("repl.source.for", "1, 2, 3")
            .create(client, hiveConf);

    client.dropType(typeName);
    Type typ1 = new Type();
    typ1.setName(typeName);
    typ1.setFields(new ArrayList<>(2));
    typ1.getFields().add(
            new FieldSchema("name", ColumnType.STRING_TYPE_NAME, ""));
    typ1.getFields().add(
            new FieldSchema("income", ColumnType.INT_TYPE_NAME, ""));
    client.createType(typ1);

    Path dirDb1 = new Path(warehouse.getWhRoot(), dbName1 +".db");
    warehouseFs.mkdirs(dirDb1);
    EncryptionZoneUtils.createEncryptionZone(dirDb1, "test_key_db", conf);
    Path dirTbl1 = new Path(dirDb1, tblName1);
    warehouseFs.mkdirs(dirTbl1);
    Path part11 = new Path(dirTbl1, "part1");
    createFile(part11, "testClearer11");

    Path dirDb2 = new Path(warehouse.getWhRoot(), dbName2 +".db");
    warehouseFs.mkdirs(dirDb2);
    EncryptionZoneUtils.createEncryptionZone(dirDb2, "test_key_db", conf);
    Path dirTbl2 = new Path(dirDb2, tblName2);
    warehouseFs.mkdirs(dirTbl2);
    Path part12 = new Path(dirTbl2, "part1");
    createFile(part12, "testClearer12");

    new TableBuilder()
            .setDbName(dbName1)
            .setTableName(tblName1)
            .setCols(typ1.getFields())
            .setNumBuckets(1)
            .addBucketCol("name")
            .addStorageDescriptorParam("test_param_1", "Use this for comments etc")
            .create(client, hiveConf);

    Table tbl = client.getTable(dbName1, tblName1);
    Assert.assertNotNull(tbl);

    new TableBuilder()
            .setDbName(dbName2)
            .setTableName(tblName2)
            .setCols(typ1.getFields())
            .setNumBuckets(1)
            .addBucketCol("name")
            .addStorageDescriptorParam("test_param_1", "Use this for comments etc")
            .create(client, hiveConf);

    boolean exceptionThrown = false;
    try {
      client.truncateTable(dbName1, tblName1, null);
    } catch (MetaException e) {
      exceptionThrown = true;
      assertTrue(e.getMessage().contains("can't be moved from encryption zone"));
    }
    assertFalse(exceptionThrown);
    assertFalse(warehouseFs.exists(part11));
    assertNotNull(client.getTable(dbName1, tblName1));
    exceptionThrown = false;
    try {
      client.truncateTable(dbName2, tblName2, null);
    } catch (MetaException e) {
      exceptionThrown = true;
      assertTrue(e.getMessage().contains("can't be moved from encryption zone"));
    }
    assertFalse(exceptionThrown);
    assertFalse(warehouseFs.exists(part12));
    assertNotNull(client.getTable(dbName2, tblName2));
  }

  @Test
  public void truncateTableWithSameEncryptionZones() throws Throwable {
    String dbName = "encrdb9";
    String tblName1 = "encrtbl1";
    String tblName2 = "encrtbl2";
    String typeName = "Person";
    client.dropTable(dbName, tblName1);
    client.dropTable(dbName, tblName2);
    silentDropDatabase(dbName);
    new DatabaseBuilder()
            .setName(dbName)
            .addParam("repl.source.for", "1, 2, 3")
            .create(client, hiveConf);

    client.dropType(typeName);
    Type typ1 = new Type();
    typ1.setName(typeName);
    typ1.setFields(new ArrayList<>(2));
    typ1.getFields().add(
            new FieldSchema("name", ColumnType.STRING_TYPE_NAME, ""));
    typ1.getFields().add(
            new FieldSchema("income", ColumnType.INT_TYPE_NAME, ""));
    client.createType(typ1);

    new TableBuilder()
            .setDbName(dbName)
            .setTableName(tblName1)
            .setCols(typ1.getFields())
            .setNumBuckets(1)
            .addBucketCol("name")
            .addStorageDescriptorParam("test_param_1", "Use this for comments etc")
            .create(client, hiveConf);

    Table tbl = client.getTable(dbName, tblName1);
    Assert.assertNotNull(tbl);

    new TableBuilder()
            .setDbName(dbName)
            .setTableName(tblName2)
            .setCols(typ1.getFields())
            .setNumBuckets(1)
            .addBucketCol("name")
            .addStorageDescriptorParam("test_param_1", "Use this for comments etc")
            .create(client, hiveConf);

    Path dirDb = new Path(warehouse.getWhRoot(), dbName +".db");
    warehouseFs.delete(dirDb, true);
    warehouseFs.mkdirs(dirDb);
    EncryptionZoneUtils.createEncryptionZone(dirDb, "test_key_db", conf);
    Path dirTbl1 = new Path(dirDb, tblName1);
    warehouseFs.mkdirs(dirTbl1);
    Path part11 = new Path(dirTbl1, "part1");
    createFile(part11, "testClearer11");

    Path dirTbl2 = new Path(dirDb, tblName2);
    warehouseFs.mkdirs(dirTbl2);
    Path part12 = new Path(dirTbl2, "part1");
    createFile(part12, "testClearer12");

    boolean exceptionThrown = false;
    try {
      client.truncateTable(dbName, tblName1, null);
    } catch (MetaException e) {
      exceptionThrown = true;
      assertTrue(e.getMessage().contains("can't be moved from encryption zone"));
    }
    assertFalse(exceptionThrown);
    assertFalse(warehouseFs.exists(part11));
    try {
      client.getTable(dbName, tblName1);
    } catch (NoSuchObjectException e) {
      exceptionThrown = true;
    }
    assertFalse(exceptionThrown);

    try {
      client.truncateTable(dbName, tblName2, null);
    } catch (MetaException e) {
      exceptionThrown = true;
      assertTrue(e.getMessage().contains("can't be moved from encryption zone"));
    }
    assertFalse(exceptionThrown);
    assertFalse(warehouseFs.exists(part12));
    try {
      client.getTable(dbName, tblName2);
    } catch (NoSuchObjectException e) {
      exceptionThrown = true;
    }
    assertFalse(exceptionThrown);
  }

  @Test
  public void truncateTableWithoutEncryptionZonesForCm() throws Throwable {
    String dbName = "simpdb3";
    String tblName = "simptbl";
    String typeName = "Person";
    client.dropTable(dbName, tblName);
    silentDropDatabase(dbName);

    new DatabaseBuilder()
            .setName(dbName)
            .addParam("repl.source.for", "1, 2, 3")
            .create(client, hiveConf);

    client.dropType(typeName);
    Type typ1 = new Type();
    typ1.setName(typeName);
    typ1.setFields(new ArrayList<>(2));
    typ1.getFields().add(
            new FieldSchema("name", ColumnType.STRING_TYPE_NAME, ""));
    typ1.getFields().add(
            new FieldSchema("income", ColumnType.INT_TYPE_NAME, ""));
    client.createType(typ1);

    new TableBuilder()
            .setDbName(dbName)
            .setTableName(tblName)
            .setCols(typ1.getFields())
            .setNumBuckets(1)
            .addBucketCol("name")
            .addStorageDescriptorParam("test_param_1", "Use this for comments etc")
            .create(client, hiveConf);

    Table tbl2 = client.getTable(dbName, tblName);
    Assert.assertNotNull(tbl2);

    Path dirDb = new Path(warehouse.getWhRoot(), dbName +".db");
    warehouseFs.mkdirs(dirDb);
    Path dirTbl1 = new Path(dirDb, tblName);
    warehouseFs.mkdirs(dirTbl1);
    Path part11 = new Path(dirTbl1, "part1");
    createFile(part11, "testClearer11");

    boolean exceptionThrown = false;
    try {
      client.truncateTable(dbName, tblName, null);
    } catch (Exception e) {
      exceptionThrown = true;
    }
    assertFalse(exceptionThrown);
    assertFalse(warehouseFs.exists(part11));
    try {
      client.getTable(dbName, tblName);
    } catch (NoSuchObjectException e) {
      exceptionThrown = true;
    }
    assertFalse(exceptionThrown);
  }

  @Test
  public void recycleFailureWithDifferentEncryptionZonesForCm() throws Throwable {
    Path dirDb = new Path(warehouse.getWhRoot(), "db2");
    warehouseFs.delete(dirDb, true);
    warehouseFs.mkdirs(dirDb);
    Path dirTbl1 = new Path(dirDb, "tbl1");
    warehouseFs.mkdirs(dirTbl1);
    EncryptionZoneUtils.createEncryptionZone(dirTbl1, "test_key_db", conf);
    Path part11 = new Path(dirTbl1, "part1");
    createFile(part11, "testClearer11");

    boolean exceptionThrown = false;
    try {
      ReplChangeManager.getInstance(hiveConf).recycle(dirTbl1, RecycleType.MOVE, false);
    } catch (RemoteException e) {
      exceptionThrown = true;
      assertTrue(e.getMessage().contains("can't be moved from encryption zone"));
    }
    assertFalse(exceptionThrown);
  }

  @Test
  public void testClearerEncrypted() throws Exception {
    HiveConf hiveConfCmClearer = new HiveConf(TestReplChangeManager.class);
    hiveConfCmClearer.setBoolean(HiveConf.ConfVars.REPLCMENABLED.varname, true);
    hiveConfCmClearer.setInt(CommonConfigurationKeysPublic.FS_TRASH_INTERVAL_KEY, 60);
    hiveConfCmClearer.set(HiveConf.ConfVars.METASTOREWAREHOUSE.varname,
            "hdfs://" + miniDFSCluster.getNameNode().getHostAndPort()
                    + HiveConf.ConfVars.METASTOREWAREHOUSE.defaultStrVal);

    String cmrootCmClearer = "hdfs://" + miniDFSCluster.getNameNode().getHostAndPort() + "/cmrootClearer";
    hiveConfCmClearer.set(HiveConf.ConfVars.REPLCMDIR.varname, cmrootCmClearer);
    Warehouse warehouseCmClearer = new Warehouse(hiveConfCmClearer);
    FileSystem cmfs = new Path(cmrootCmClearer).getFileSystem(hiveConfCmClearer);
    cmfs.mkdirs(warehouseCmClearer.getWhRoot());

    FileSystem fsWarehouse = warehouseCmClearer.getWhRoot().getFileSystem(hiveConfCmClearer);
    long now = System.currentTimeMillis();
    Path dirDb = new Path(warehouseCmClearer.getWhRoot(), "db1");
    fsWarehouse.delete(dirDb, true);
    fsWarehouse.mkdirs(dirDb);
    Path dirTbl1 = new Path(dirDb, "tbl1");
    fsWarehouse.mkdirs(dirTbl1);
    EncryptionZoneUtils.createEncryptionZone(dirTbl1, "test_key_db", conf);
    Path part11 = new Path(dirTbl1, "part1");
    createFile(part11, "testClearer11");
    String fileChksum11 = ReplChangeManager.checksumFor(part11, fsWarehouse);
    Path part12 = new Path(dirTbl1, "part2");
    createFile(part12, "testClearer12");
    String fileChksum12 = ReplChangeManager.checksumFor(part12, fsWarehouse);
    Path dirTbl2 = new Path(dirDb, "tbl2");
    fsWarehouse.mkdirs(dirTbl2);
    EncryptionZoneUtils.createEncryptionZone(dirTbl2, "test_key_db", conf);
    Path part21 = new Path(dirTbl2, "part1");
    createFile(part21, "testClearer21");
    String fileChksum21 = ReplChangeManager.checksumFor(part21, fsWarehouse);
    Path part22 = new Path(dirTbl2, "part2");
    createFile(part22, "testClearer22");
    String fileChksum22 = ReplChangeManager.checksumFor(part22, fsWarehouse);
    Path dirTbl3 = new Path(dirDb, "tbl3");
    fsWarehouse.mkdirs(dirTbl3);
    EncryptionZoneUtils.createEncryptionZone(dirTbl3, "test_key_cm", conf);
    Path part31 = new Path(dirTbl3, "part1");
    createFile(part31, "testClearer31");
    String fileChksum31 = ReplChangeManager.checksumFor(part31, fsWarehouse);
    Path part32 = new Path(dirTbl3, "part2");
    createFile(part32, "testClearer32");
    String fileChksum32 = ReplChangeManager.checksumFor(part32, fsWarehouse);

    ReplChangeManager.getInstance(hiveConfCmClearer).recycle(dirTbl1, RecycleType.MOVE, false);
    ReplChangeManager.getInstance(hiveConfCmClearer).recycle(dirTbl2, RecycleType.MOVE, false);
    ReplChangeManager.getInstance(hiveConfCmClearer).recycle(dirTbl3, RecycleType.MOVE, true);

    assertTrue(fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfCmClearer, part11.getName(), fileChksum11,
            ReplChangeManager.getInstance(conf).getCmRoot(part11).toString())));
    assertTrue(fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfCmClearer, part12.getName(), fileChksum12,
            ReplChangeManager.getInstance(conf).getCmRoot(part12).toString())));
    assertTrue(fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfCmClearer, part21.getName(), fileChksum21,
            ReplChangeManager.getInstance(conf).getCmRoot(part21).toString())));
    assertTrue(fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfCmClearer, part22.getName(), fileChksum22,
            ReplChangeManager.getInstance(conf).getCmRoot(part22).toString())));
    assertTrue(fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfCmClearer, part31.getName(), fileChksum31,
            ReplChangeManager.getInstance(conf).getCmRoot(part31).toString())));
    assertTrue(fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfCmClearer, part32.getName(), fileChksum32,
            ReplChangeManager.getInstance(conf).getCmRoot(part32).toString())));

    fsWarehouse.setTimes(ReplChangeManager.getCMPath(hiveConfCmClearer, part11.getName(), fileChksum11,
            ReplChangeManager.getInstance(conf).getCmRoot(part11).toString()),
            now - 7 * 86400 * 1000 * 2, now - 7 * 86400 * 1000 * 2);
    fsWarehouse.setTimes(ReplChangeManager.getCMPath(hiveConfCmClearer, part21.getName(), fileChksum21,
            ReplChangeManager.getInstance(conf).getCmRoot(part21).toString()),
            now - 7 * 86400 * 1000 * 2, now - 7 * 86400 * 1000 * 2);
    fsWarehouse.setTimes(ReplChangeManager.getCMPath(hiveConfCmClearer, part31.getName(), fileChksum31,
            ReplChangeManager.getInstance(conf).getCmRoot(part31).toString()),
            now - 7 * 86400 * 1000 * 2, now - 7 * 86400 * 1000 * 2);
    fsWarehouse.setTimes(ReplChangeManager.getCMPath(hiveConfCmClearer, part32.getName(), fileChksum32,
            ReplChangeManager.getInstance(conf).getCmRoot(part32).toString()),
            now - 7 * 86400 * 1000 * 2, now - 7 * 86400 * 1000 * 2);

    ReplChangeManager.scheduleCMClearer(hiveConfCmClearer);

    long start = System.currentTimeMillis();
    long end;
    boolean cleared = false;
    do {
      Thread.sleep(200);
      end = System.currentTimeMillis();
      if (end - start > 5000) {
        Assert.fail("timeout, cmroot has not been cleared");
      }
      if (!fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfCmClearer, part11.getName(), fileChksum11,
              ReplChangeManager.getInstance(conf).getCmRoot(part11).toString())) &&
              fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfCmClearer, part12.getName(), fileChksum12,
                      ReplChangeManager.getInstance(conf).getCmRoot(part12).toString())) &&
              !fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfCmClearer, part21.getName(), fileChksum21,
                      ReplChangeManager.getInstance(conf).getCmRoot(part21).toString())) &&
              fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfCmClearer, part22.getName(), fileChksum22,
                      ReplChangeManager.getInstance(conf).getCmRoot(part22).toString())) &&
              !fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfCmClearer, part31.getName(), fileChksum31,
                      ReplChangeManager.getInstance(conf).getCmRoot(part31).toString())) &&
              !fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfCmClearer, part32.getName(), fileChksum32,
                      ReplChangeManager.getInstance(conf).getCmRoot(part32).toString()))) {
        cleared = true;
      }
    } while (!cleared);
  }

  @Test
  public void testCmRootAclPermissions() throws Exception {
    HiveConf hiveConfAclPermissions = new HiveConf(TestReplChangeManager.class);
    hiveConfAclPermissions.setBoolean(HiveConf.ConfVars.REPLCMENABLED.varname, true);
    hiveConfAclPermissions.setInt(CommonConfigurationKeysPublic.FS_TRASH_INTERVAL_KEY, 60);
    hiveConfAclPermissions.set(HiveConf.ConfVars.METASTOREWAREHOUSE.varname,
            "hdfs://" + miniDFSCluster.getNameNode().getHostAndPort()
                    + HiveConf.ConfVars.METASTOREWAREHOUSE.defaultStrVal);

    String cmRootAclPermissions = "hdfs://" + miniDFSCluster.getNameNode().getHostAndPort() + "/cmRootAclPermissions";
    hiveConfAclPermissions.set(HiveConf.ConfVars.REPLCMDIR.varname, cmRootAclPermissions);
    Warehouse warehouseCmPermissions = new Warehouse(hiveConfAclPermissions);
    FileSystem cmfs = new Path(cmRootAclPermissions).getFileSystem(hiveConfAclPermissions);
    cmfs.mkdirs(warehouseCmPermissions.getWhRoot());

    FileSystem fsWarehouse = warehouseCmPermissions.getWhRoot().getFileSystem(hiveConfAclPermissions);
    //change the group of warehouse for testing
    Path warehouse = new Path(hiveConfAclPermissions.get(HiveConf.ConfVars.METASTOREWAREHOUSE.varname));
    fsWarehouse.setOwner(warehouse, null, "testgroup");

    long now = System.currentTimeMillis();
    Path dirDb = new Path(warehouseCmPermissions.getWhRoot(), "db_perm");
    fsWarehouse.delete(dirDb, true);
    fsWarehouse.mkdirs(dirDb);
    Path dirTbl1 = new Path(dirDb, "tbl1");
    fsWarehouse.mkdirs(dirTbl1);
    EncryptionZoneUtils.createEncryptionZone(dirTbl1, "test_key_db", conf);
    Path part11 = new Path(dirTbl1, "part1");
    createFile(part11, "testClearer11");
    String fileChksum11 = ReplChangeManager.checksumFor(part11, fsWarehouse);
    Path part12 = new Path(dirTbl1, "part2");
    createFile(part12, "testClearer12");
    String fileChksum12 = ReplChangeManager.checksumFor(part12, fsWarehouse);
    Path dirTbl2 = new Path(dirDb, "tbl2");
    fsWarehouse.mkdirs(dirTbl2);
    EncryptionZoneUtils.createEncryptionZone(dirTbl2, "test_key_db", conf);
    Path part21 = new Path(dirTbl2, "part1");
    createFile(part21, "testClearer21");
    String fileChksum21 = ReplChangeManager.checksumFor(part21, fsWarehouse);
    Path part22 = new Path(dirTbl2, "part2");
    createFile(part22, "testClearer22");
    String fileChksum22 = ReplChangeManager.checksumFor(part22, fsWarehouse);
    Path dirTbl3 = new Path(dirDb, "tbl3");
    fsWarehouse.mkdirs(dirTbl3);
    EncryptionZoneUtils.createEncryptionZone(dirTbl3, "test_key_cm", conf);
    Path part31 = new Path(dirTbl3, "part1");
    createFile(part31, "testClearer31");
    String fileChksum31 = ReplChangeManager.checksumFor(part31, fsWarehouse);
    Path part32 = new Path(dirTbl3, "part2");
    createFile(part32, "testClearer32");
    String fileChksum32 = ReplChangeManager.checksumFor(part32, fsWarehouse);

    final UserGroupInformation proxyUserUgi =
            UserGroupInformation.createUserForTesting("impala", new String[] {"testgroup"});

    fsWarehouse.setOwner(dirDb, "impala", "default");
    fsWarehouse.setOwner(dirTbl1, "impala", "default");
    fsWarehouse.setOwner(dirTbl2, "impala", "default");
    fsWarehouse.setOwner(dirTbl3, "impala", "default");
    fsWarehouse.setOwner(part11, "impala", "default");
    fsWarehouse.setOwner(part12, "impala", "default");
    fsWarehouse.setOwner(part21, "impala", "default");
    fsWarehouse.setOwner(part22, "impala", "default");
    fsWarehouse.setOwner(part31, "impala", "default");
    fsWarehouse.setOwner(part32, "impala", "default");

    proxyUserUgi.doAs((PrivilegedExceptionAction<Void>) () -> {
      try {
        //impala doesn't have access but it belongs to a group which has access through acl.
        ReplChangeManager.getInstance(hiveConfAclPermissions).recycle(dirTbl1, RecycleType.MOVE, false);
        ReplChangeManager.getInstance(hiveConfAclPermissions).recycle(dirTbl2, RecycleType.MOVE, false);
        ReplChangeManager.getInstance(hiveConfAclPermissions).recycle(dirTbl3, RecycleType.MOVE, true);
      } catch (Exception e) {
        Assert.fail();
      }
      return null;
    });

    String cmEncrypted = hiveConf.get(HiveConf.ConfVars.REPLCMENCRYPTEDDIR.varname, cmrootEncrypted);
    AclStatus aclStatus = fsWarehouse.getAclStatus(new Path(dirTbl1 + Path.SEPARATOR + cmEncrypted));
    AclStatus aclStatus2 = fsWarehouse.getAclStatus(new Path(dirTbl2 + Path.SEPARATOR + cmEncrypted));
    AclStatus aclStatus3 = fsWarehouse.getAclStatus(new Path(dirTbl3 + Path.SEPARATOR + cmEncrypted));
    AclEntry expectedAcl = new AclEntry.Builder().setScope(ACCESS).setType(GROUP).setName("testgroup").
            setPermission(fsWarehouse.getFileStatus(warehouse).getPermission().getGroupAction()).build();
    Assert.assertTrue(aclStatus.getEntries().contains(expectedAcl));
    Assert.assertTrue(aclStatus2.getEntries().contains(expectedAcl));
    Assert.assertTrue(aclStatus3.getEntries().contains(expectedAcl));

    assertTrue(fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfAclPermissions, part11.getName(), fileChksum11,
            ReplChangeManager.getInstance(conf).getCmRoot(part11).toString())));
    assertTrue(fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfAclPermissions, part12.getName(), fileChksum12,
            ReplChangeManager.getInstance(conf).getCmRoot(part12).toString())));
    assertTrue(fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfAclPermissions, part21.getName(), fileChksum21,
            ReplChangeManager.getInstance(conf).getCmRoot(part21).toString())));
    assertTrue(fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfAclPermissions, part22.getName(), fileChksum22,
            ReplChangeManager.getInstance(conf).getCmRoot(part22).toString())));
    assertTrue(fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfAclPermissions, part31.getName(), fileChksum31,
            ReplChangeManager.getInstance(conf).getCmRoot(part31).toString())));
    assertTrue(fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfAclPermissions, part32.getName(), fileChksum32,
            ReplChangeManager.getInstance(conf).getCmRoot(part32).toString())));

    fsWarehouse.setTimes(ReplChangeManager.getCMPath(hiveConfAclPermissions, part11.getName(), fileChksum11,
            ReplChangeManager.getInstance(conf).getCmRoot(part11).toString()),
            now - 7 * 86400 * 1000 * 2, now - 7 * 86400 * 1000 * 2);
    fsWarehouse.setTimes(ReplChangeManager.getCMPath(hiveConfAclPermissions, part21.getName(), fileChksum21,
            ReplChangeManager.getInstance(conf).getCmRoot(part21).toString()),
            now - 7 * 86400 * 1000 * 2, now - 7 * 86400 * 1000 * 2);
    fsWarehouse.setTimes(ReplChangeManager.getCMPath(hiveConfAclPermissions, part31.getName(), fileChksum31,
            ReplChangeManager.getInstance(conf).getCmRoot(part31).toString()),
            now - 7 * 86400 * 1000 * 2, now - 7 * 86400 * 1000 * 2);
    fsWarehouse.setTimes(ReplChangeManager.getCMPath(hiveConfAclPermissions, part32.getName(), fileChksum32,
            ReplChangeManager.getInstance(conf).getCmRoot(part32).toString()),
            now - 7 * 86400 * 1000 * 2, now - 7 * 86400 * 1000 * 2);

    ReplChangeManager.scheduleCMClearer(hiveConfAclPermissions);

    long start = System.currentTimeMillis();
    long end;
    boolean cleared = false;
    do {
      Thread.sleep(200);
      end = System.currentTimeMillis();
      if (end - start > 5000) {
        Assert.fail("timeout, cmroot has not been cleared");
      }
      if (!fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfAclPermissions, part11.getName(), fileChksum11,
              ReplChangeManager.getInstance(conf).getCmRoot(part11).toString())) &&
              fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfAclPermissions, part12.getName(), fileChksum12,
                      ReplChangeManager.getInstance(conf).getCmRoot(part12).toString())) &&
              !fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfAclPermissions, part21.getName(), fileChksum21,
                      ReplChangeManager.getInstance(conf).getCmRoot(part21).toString())) &&
              fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfAclPermissions, part22.getName(), fileChksum22,
                      ReplChangeManager.getInstance(conf).getCmRoot(part22).toString())) &&
              !fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfAclPermissions, part31.getName(), fileChksum31,
                      ReplChangeManager.getInstance(conf).getCmRoot(part31).toString())) &&
              !fsWarehouse.exists(ReplChangeManager.getCMPath(hiveConfAclPermissions, part32.getName(), fileChksum32,
                      ReplChangeManager.getInstance(conf).getCmRoot(part32).toString()))) {
        cleared = true;
      }
    } while (!cleared);
  }

  @Test
  public void testCmrootEncrypted() throws Exception {
    HiveConf encryptedHiveConf = new HiveConf(TestReplChangeManager.class);
    encryptedHiveConf.setBoolean(HiveConf.ConfVars.REPLCMENABLED.varname, true);
    encryptedHiveConf.setInt(CommonConfigurationKeysPublic.FS_TRASH_INTERVAL_KEY, 60);
    encryptedHiveConf.set(HiveConf.ConfVars.METASTOREWAREHOUSE.varname,
            "hdfs://" + miniDFSCluster.getNameNode().getHostAndPort()
                    + HiveConf.ConfVars.METASTOREWAREHOUSE.defaultStrVal);

    String cmrootdirEncrypted = "hdfs://" + miniDFSCluster.getNameNode().getHostAndPort() + "/cmrootDirEncrypted";
    encryptedHiveConf.set(HiveConf.ConfVars.REPLCMDIR.varname, cmrootdirEncrypted);
    FileSystem cmrootdirEncryptedFs = new Path(cmrootdirEncrypted).getFileSystem(hiveConf);
    cmrootdirEncryptedFs.mkdirs(new Path(cmrootdirEncrypted));
    encryptedHiveConf.set(HiveConf.ConfVars.REPLCMFALLBACKNONENCRYPTEDDIR.varname, cmrootFallBack);

    //Create cm in encrypted zone
    EncryptionZoneUtils.createEncryptionZone(new Path(cmrootdirEncrypted), "test_key_db", conf);
    ReplChangeManager.resetReplChangeManagerInstance();
    Warehouse warehouseEncrypted = new Warehouse(encryptedHiveConf);
    FileSystem warehouseFsEncrypted = warehouseEncrypted.getWhRoot().getFileSystem(encryptedHiveConf);
    FileSystem fsCmEncrypted = new Path(cmrootdirEncrypted).getFileSystem(encryptedHiveConf);
    fsCmEncrypted.mkdirs(warehouseEncrypted.getWhRoot());

    Path dirDb = new Path(warehouseEncrypted.getWhRoot(), "db3");
    warehouseFsEncrypted.delete(dirDb, true);
    warehouseFsEncrypted.mkdirs(dirDb);
    Path dirTbl1 = new Path(dirDb, "tbl1");
    warehouseFsEncrypted.mkdirs(dirTbl1);
    EncryptionZoneUtils.createEncryptionZone(dirTbl1, "test_key_db", conf);
    Path part11 = new Path(dirTbl1, "part1");
    createFile(part11, "testClearer11");

    boolean exceptionThrown = false;
    try {
      ReplChangeManager.getInstance(encryptedHiveConf).recycle(dirTbl1, RecycleType.MOVE, false);
    } catch (RemoteException e) {
      exceptionThrown = true;
      assertTrue(e.getMessage().contains("can't be moved from encryption zone"));
    }
    assertFalse(exceptionThrown);

    Path dirDbUnEncrypted = new Path(warehouseEncrypted.getWhRoot(), "db3en");
    warehouseFsEncrypted.delete(dirDbUnEncrypted, true);
    warehouseFsEncrypted.mkdirs(dirDbUnEncrypted);
    Path dirTblun1 = new Path(dirDbUnEncrypted, "tbl1");
    warehouseFsEncrypted.mkdirs(dirTblun1);
    Path partun11 = new Path(dirTblun1, "part1");
    createFile(partun11, "testClearer11");

    exceptionThrown = false;
    try {
      ReplChangeManager.getInstance(encryptedHiveConf).recycle(dirDbUnEncrypted, RecycleType.MOVE, false);
    } catch (IOException e) {
      exceptionThrown = true;
    }
    assertFalse(exceptionThrown);
    cmrootdirEncryptedFs.delete(new Path(cmrootdirEncrypted), true);
    ReplChangeManager.resetReplChangeManagerInstance();
    initReplChangeManager();
  }

  @Test
  public void testCmrootFallbackEncrypted() throws Exception {
    HiveConf encryptedHiveConf = new HiveConf(TestReplChangeManager.class);
    encryptedHiveConf.setBoolean(HiveConf.ConfVars.REPLCMENABLED.varname, true);
    encryptedHiveConf.setInt(CommonConfigurationKeysPublic.FS_TRASH_INTERVAL_KEY, 60);
    encryptedHiveConf.set(HiveConf.ConfVars.METASTOREWAREHOUSE.varname,
            "hdfs://" + miniDFSCluster.getNameNode().getHostAndPort()
                    + HiveConf.ConfVars.METASTOREWAREHOUSE.defaultStrVal);
    String cmrootdirEncrypted = "hdfs://" + miniDFSCluster.getNameNode().getHostAndPort() + "/cmrootIsEncrypted";
    String cmRootFallbackEncrypted = "hdfs://" + miniDFSCluster.getNameNode().getHostAndPort()
            + "/cmrootFallbackEncrypted";
    FileSystem cmrootdirEncryptedFs = new Path(cmrootdirEncrypted).getFileSystem(encryptedHiveConf);
    try {
      cmrootdirEncryptedFs.mkdirs(new Path(cmrootdirEncrypted));
      cmrootdirEncryptedFs.mkdirs(new Path(cmRootFallbackEncrypted));
      encryptedHiveConf.set(HiveConf.ConfVars.REPLCMDIR.varname, cmrootdirEncrypted);
      encryptedHiveConf.set(HiveConf.ConfVars.REPLCMFALLBACKNONENCRYPTEDDIR.varname, cmRootFallbackEncrypted);

      //Create cm in encrypted zone
      EncryptionZoneUtils.createEncryptionZone(new Path(cmrootdirEncrypted), "test_key_db", conf);
      EncryptionZoneUtils.createEncryptionZone(new Path(cmRootFallbackEncrypted), "test_key_db", conf);
      ReplChangeManager.resetReplChangeManagerInstance();
      boolean exceptionThrown = false;
      try {
        new Warehouse(encryptedHiveConf);
      } catch (MetaException e) {
        exceptionThrown = true;
        assertTrue(e.getMessage().contains("should not be encrypted"));
      }
      assertTrue(exceptionThrown);
    } finally {
      cmrootdirEncryptedFs.delete(new Path(cmrootdirEncrypted), true);
      cmrootdirEncryptedFs.delete(new Path(cmRootFallbackEncrypted), true);
      ReplChangeManager.resetReplChangeManagerInstance();
      initReplChangeManager();
    }
  }

  @Test
  public void testCmrootFallbackRelative() throws Exception {
    HiveConf encryptedHiveConf = new HiveConf(TestReplChangeManager.class);
    encryptedHiveConf.setBoolean(HiveConf.ConfVars.REPLCMENABLED.varname, true);
    encryptedHiveConf.setInt(CommonConfigurationKeysPublic.FS_TRASH_INTERVAL_KEY, 60);
    encryptedHiveConf.set(HiveConf.ConfVars.METASTOREWAREHOUSE.varname,
            "hdfs://" + miniDFSCluster.getNameNode().getHostAndPort()
                    + HiveConf.ConfVars.METASTOREWAREHOUSE.defaultStrVal);
    String cmrootdirEncrypted = "hdfs://" + miniDFSCluster.getNameNode().getHostAndPort() + "/cmrootIsEncrypted";
    String cmRootFallbackEncrypted = "cmrootFallbackEncrypted";
    FileSystem cmrootdirEncryptedFs = new Path(cmrootdirEncrypted).getFileSystem(encryptedHiveConf);
    try {
      cmrootdirEncryptedFs.mkdirs(new Path(cmrootdirEncrypted));
      cmrootdirEncryptedFs.mkdirs(new Path(cmRootFallbackEncrypted));
      encryptedHiveConf.set(HiveConf.ConfVars.REPLCMDIR.varname, cmrootdirEncrypted);
      encryptedHiveConf.set(HiveConf.ConfVars.REPLCMFALLBACKNONENCRYPTEDDIR.varname, cmRootFallbackEncrypted);

      //Create cm in encrypted zone
      EncryptionZoneUtils.createEncryptionZone(new Path(cmrootdirEncrypted), "test_key_db", conf);

      ReplChangeManager.resetReplChangeManagerInstance();
      boolean exceptionThrown = false;
      try {
        new Warehouse(encryptedHiveConf);
      } catch (MetaException e) {
        exceptionThrown = true;
        assertTrue(e.getMessage().contains("should be absolute"));
      }
      assertTrue(exceptionThrown);
    } finally {
      cmrootdirEncryptedFs.delete(new Path(cmrootdirEncrypted), true);
      cmrootdirEncryptedFs.delete(new Path(cmRootFallbackEncrypted), true);
      ReplChangeManager.resetReplChangeManagerInstance();
      initReplChangeManager();
    }
  }



  private void createFile(Path path, String content) throws IOException {
    FSDataOutputStream output = path.getFileSystem(hiveConf).create(path);
    output.writeChars(content);
    output.close();
  }

  private void silentDropDatabase(String dbName) throws TException {
    try {
      for (String tableName : client.getTables(dbName, "*")) {
        client.dropTable(dbName, tableName);
      }
      client.dropDatabase(dbName);
    } catch (NoSuchObjectException|InvalidOperationException|MetaException e) {
      // NOP
    }
  }
}
