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.client; 019 020import java.io.IOException; 021import java.nio.file.Files; 022import java.nio.file.Path; 023import java.nio.file.Paths; 024import java.nio.file.StandardCopyOption; 025import org.apache.hadoop.hbase.HBaseTestingUtility; 026import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread; 027 028/** 029 * Base class to test Configuration Update logic. It wraps up things needed to 030 * test configuration change and provides utility methods for test cluster setup, 031 * updating/restoring configuration file. 032 */ 033public abstract class AbstractTestUpdateConfiguration { 034 private static final String SERVER_CONFIG = "hbase-site.xml"; 035 private static final String OVERRIDE_SERVER_CONFIG = "override-hbase-site.xml"; 036 private static final String BACKUP_SERVER_CONFIG = "backup-hbase-site.xml"; 037 038 private static Path configFileUnderTestDataDir; 039 private static Path overrideConfigFileUnderTestDataDir; 040 private static Path backupConfigFileUnderTestDataDir; 041 042 protected static void setUpConfigurationFiles(final HBaseTestingUtility testUtil) 043 throws Exception { 044 // Before this change, the test will update hbase-site.xml under target/test-classes and 045 // trigger a config reload. Since target/test-classes/hbase-site.xml is being used by 046 // other testing cases at the same time, this update will break other testing cases so it will 047 // be flakey in nature. 048 // To avoid this, the change is to make target/test-classes/hbase-site.xml immutable. A new 049 // hbase-site.xml will be created under its test data directory, i.e, 050 // hbase-server/target/test-data/UUID, this new file will be added as a resource for the 051 // config, new update will be applied to this new file and only visible to this specific test 052 // case. The target/test-classes/hbase-site.xml will not be changed during the test. 053 054 String absoluteDataPath = testUtil.getDataTestDir().toString(); 055 056 // Create test-data directories. 057 Files.createDirectories(Paths.get(absoluteDataPath)); 058 059 // Copy hbase-site.xml from target/test-class to target/test-data/UUID directory. 060 Path configFile = Paths.get("target", "test-classes", SERVER_CONFIG); 061 configFileUnderTestDataDir = Paths.get(absoluteDataPath, SERVER_CONFIG); 062 Files.copy(configFile, configFileUnderTestDataDir); 063 064 // Copy override config file overrider-hbase-site.xml from target/test-class to 065 // target/test-data/UUID directory. 066 Path overrideConfigFile = Paths.get("target", "test-classes", 067 OVERRIDE_SERVER_CONFIG); 068 overrideConfigFileUnderTestDataDir = Paths.get(absoluteDataPath, OVERRIDE_SERVER_CONFIG); 069 Files.copy(overrideConfigFile, overrideConfigFileUnderTestDataDir); 070 071 backupConfigFileUnderTestDataDir = Paths.get(absoluteDataPath, BACKUP_SERVER_CONFIG); 072 073 // Add the new custom config file to Configuration 074 testUtil.getConfiguration().addResource(testUtil.getDataTestDir(SERVER_CONFIG)); 075 } 076 077 protected static void addResourceToRegionServerConfiguration(final HBaseTestingUtility testUtil) { 078 // When RegionServer is created in MiniHBaseCluster, it uses HBaseConfiguration.create(conf) of 079 // the master Configuration. The create() just copies config params over, it does not do 080 // a clone for a historic reason. Properties such as resources are lost during this process. 081 // Exposing a new method in HBaseConfiguration causes confusion. Instead, the new hbase-site.xml 082 // under test-data directory is added to RegionServer's configuration as a workaround. 083 for (RegionServerThread rsThread : testUtil.getMiniHBaseCluster().getRegionServerThreads()) { 084 rsThread.getRegionServer().getConfiguration().addResource( 085 testUtil.getDataTestDir(SERVER_CONFIG)); 086 } 087 } 088 089 /** 090 * Replace the hbase-site.xml file under this test's data directory with the content of the 091 * override-hbase-site.xml file. Stashes the current existing file so that it can be restored 092 * using {@link #restoreHBaseSiteXML()}. 093 * 094 * @throws IOException if an I/O error occurs 095 */ 096 protected void replaceHBaseSiteXML() throws IOException { 097 // make a backup of hbase-site.xml 098 Files.copy(configFileUnderTestDataDir, 099 backupConfigFileUnderTestDataDir, StandardCopyOption.REPLACE_EXISTING); 100 // update hbase-site.xml by overwriting it 101 Files.copy(overrideConfigFileUnderTestDataDir, 102 configFileUnderTestDataDir, StandardCopyOption.REPLACE_EXISTING); 103 } 104 105 /** 106 * Restores the hbase-site.xml file that was stashed by a previous call to 107 * {@link #replaceHBaseSiteXML()}. 108 * 109 * @throws IOException if an I/O error occurs 110 */ 111 protected void restoreHBaseSiteXML() throws IOException { 112 // restore hbase-site.xml 113 Files.copy(backupConfigFileUnderTestDataDir, 114 configFileUnderTestDataDir, StandardCopyOption.REPLACE_EXISTING); 115 } 116}