001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase;
019
020import java.io.IOException;
021import org.apache.hadoop.conf.Configuration;
022import org.apache.hadoop.hbase.Waiter.Predicate;
023import org.apache.hadoop.hbase.client.Admin;
024import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
025import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
026import org.apache.hadoop.hbase.client.TableDescriptor;
027import org.apache.hadoop.hbase.io.crypto.MockAesKeyProvider;
028import org.apache.hadoop.hbase.io.hfile.HFile;
029import org.apache.hadoop.hbase.testclassification.IntegrationTests;
030import org.apache.hadoop.hbase.util.EncryptionTest;
031import org.apache.hadoop.util.ToolRunner;
032import org.junit.Before;
033import org.junit.experimental.categories.Category;
034import org.slf4j.Logger;
035import org.slf4j.LoggerFactory;
036
037@Category(IntegrationTests.class)
038public class IntegrationTestIngestWithEncryption extends IntegrationTestIngest {
039  private final static Logger LOG =
040    LoggerFactory.getLogger(IntegrationTestIngestWithEncryption.class);
041
042  boolean initialized = false;
043
044  @Override
045  public void setUpCluster() throws Exception {
046    util = getTestingUtil(null);
047    Configuration conf = util.getConfiguration();
048    if (!util.isDistributedCluster()) {
049      // Inject required configuration if we are not running in distributed mode
050      conf.setInt(HFile.FORMAT_VERSION_KEY, 3);
051      conf.set(HConstants.CRYPTO_KEYPROVIDER_CONF_KEY, MockAesKeyProvider.class.getName());
052      conf.set(HConstants.CRYPTO_MASTERKEY_NAME_CONF_KEY, "hbase");
053      conf.setBoolean(HConstants.ENABLE_WAL_ENCRYPTION, true);
054    }
055    // Check if the cluster configuration can support this test
056    try {
057      EncryptionTest.testEncryption(conf, "AES", null);
058    } catch (Exception e) {
059      LOG.warn("Encryption configuration test did not pass, skipping test", e);
060      return;
061    }
062    super.setUpCluster();
063    initialized = true;
064  }
065
066  @Before
067  @Override
068  public void setUp() throws Exception {
069    // Initialize the cluster. This invokes LoadTestTool -init_only, which
070    // will create the test table, appropriately pre-split
071    super.setUp();
072
073    if (!initialized) {
074      return;
075    }
076
077    // Update the test table schema so HFiles from this point will be written with
078    // encryption features enabled.
079    final Admin admin = util.getAdmin();
080    TableDescriptor tableDescriptor = admin.getDescriptor(getTablename());
081    for (ColumnFamilyDescriptor columnDescriptor : tableDescriptor.getColumnFamilies()) {
082      ColumnFamilyDescriptor updatedColumn =
083        ColumnFamilyDescriptorBuilder.newBuilder(columnDescriptor).setEncryptionType("AES").build();
084      LOG.info(
085        "Updating CF schema for " + getTablename() + "." + columnDescriptor.getNameAsString());
086      admin.disableTable(getTablename());
087      admin.modifyColumnFamily(getTablename(), updatedColumn);
088      admin.enableTable(getTablename());
089      util.waitFor(30000, 1000, true, new Predicate<IOException>() {
090        @Override
091        public boolean evaluate() throws IOException {
092          return admin.isTableAvailable(getTablename());
093        }
094      });
095    }
096  }
097
098  @Override
099  public int runTestFromCommandLine() throws Exception {
100    if (!initialized) {
101      return 0;
102    }
103    return super.runTestFromCommandLine();
104  }
105
106  @Override
107  public void cleanUp() throws Exception {
108    if (!initialized) {
109      return;
110    }
111    super.cleanUp();
112  }
113
114  public static void main(String[] args) throws Exception {
115    Configuration conf = HBaseConfiguration.create();
116    IntegrationTestingUtility.setUseDistributedCluster(conf);
117    int ret = ToolRunner.run(conf, new IntegrationTestIngestWithEncryption(), args);
118    System.exit(ret);
119  }
120}