View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase;
19  
20  import java.io.IOException;
21  
22  import org.apache.hadoop.conf.Configuration;
23  import org.apache.hadoop.hbase.Waiter.Predicate;
24  import org.apache.hadoop.hbase.client.Admin;
25  import org.apache.hadoop.hbase.io.crypto.KeyProviderForTesting;
26  import org.apache.hadoop.hbase.io.hfile.HFile;
27  import org.apache.hadoop.hbase.io.hfile.HFileReaderV3;
28  import org.apache.hadoop.hbase.io.hfile.HFileWriterV3;
29  import org.apache.hadoop.hbase.testclassification.IntegrationTests;
30  import org.apache.hadoop.hbase.wal.WAL.Reader;
31  import org.apache.hadoop.hbase.wal.WALProvider.Writer;
32  import org.apache.hadoop.hbase.regionserver.wal.SecureProtobufLogReader;
33  import org.apache.hadoop.hbase.regionserver.wal.SecureProtobufLogWriter;
34  import org.apache.hadoop.hbase.util.EncryptionTest;
35  import org.apache.hadoop.util.ToolRunner;
36  import org.apache.log4j.Level;
37  import org.apache.log4j.Logger;
38  
39  import org.junit.Before;
40  import org.junit.experimental.categories.Category;
41  
42  @Category(IntegrationTests.class)
43  public class IntegrationTestIngestWithEncryption extends IntegrationTestIngest {
44    boolean initialized = false;
45  
46    static {
47      // These log level changes are only useful when running on a localhost
48      // cluster.
49      Logger.getLogger(HFileReaderV3.class).setLevel(Level.TRACE);
50      Logger.getLogger(HFileWriterV3.class).setLevel(Level.TRACE);
51      Logger.getLogger(SecureProtobufLogReader.class).setLevel(Level.TRACE);
52      Logger.getLogger(SecureProtobufLogWriter.class).setLevel(Level.TRACE);
53    }
54  
55    @Override
56    public void setUpCluster() throws Exception {
57      util = getTestingUtil(null);
58      Configuration conf = util.getConfiguration();
59      if (!util.isDistributedCluster()) {
60        // Inject required configuration if we are not running in distributed mode
61        conf.setInt(HFile.FORMAT_VERSION_KEY, 3);
62        conf.set(HConstants.CRYPTO_KEYPROVIDER_CONF_KEY, KeyProviderForTesting.class.getName());
63        conf.set(HConstants.CRYPTO_MASTERKEY_NAME_CONF_KEY, "hbase");
64        conf.setClass("hbase.regionserver.hlog.reader.impl", SecureProtobufLogReader.class,
65          Reader.class);
66        conf.setClass("hbase.regionserver.hlog.writer.impl", SecureProtobufLogWriter.class,
67          Writer.class);
68        conf.setBoolean(HConstants.ENABLE_WAL_ENCRYPTION, true);
69      }
70      // Check if the cluster configuration can support this test
71      try {
72        EncryptionTest.testEncryption(conf, "AES", null);
73      } catch (Exception e) {
74        LOG.warn("Encryption configuration test did not pass, skipping test");
75        return;
76      }
77      super.setUpCluster();
78      initialized = true;
79    }
80  
81    @Before
82    @Override
83    public void setUp() throws Exception {
84      // Initialize the cluster. This invokes LoadTestTool -init_only, which
85      // will create the test table, appropriately pre-split
86      super.setUp();
87  
88      if (!initialized) {
89        return;
90      }
91  
92      // Update the test table schema so HFiles from this point will be written with
93      // encryption features enabled.
94      final Admin admin = util.getHBaseAdmin();
95      HTableDescriptor tableDescriptor =
96          new HTableDescriptor(admin.getTableDescriptor(getTablename()));
97      for (HColumnDescriptor columnDescriptor: tableDescriptor.getColumnFamilies()) {
98        columnDescriptor.setEncryptionType("AES");
99        LOG.info("Updating CF schema for " + getTablename() + "." +
100         columnDescriptor.getNameAsString());
101       admin.disableTable(getTablename());
102       admin.modifyColumn(getTablename(), columnDescriptor);
103       admin.enableTable(getTablename());
104       util.waitFor(30000, 1000, true, new Predicate<IOException>() {
105         @Override
106         public boolean evaluate() throws IOException {
107           return admin.isTableAvailable(getTablename());
108         }
109       });
110     }
111   }
112 
113   @Override
114   public int runTestFromCommandLine() throws Exception {
115     if (!initialized) {
116       return 0;
117     }
118     return super.runTestFromCommandLine();
119   }
120 
121   @Override
122   public void cleanUp() throws Exception {
123     if (!initialized) {
124       return;
125     }
126     super.cleanUp();
127   }
128 
129   public static void main(String[] args) throws Exception {
130     Configuration conf = HBaseConfiguration.create();
131     IntegrationTestingUtility.setUseDistributedCluster(conf);
132     int ret = ToolRunner.run(conf, new IntegrationTestIngestWithEncryption(), args);
133     System.exit(ret);
134   }
135 }