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 static org.apache.hadoop.hbase.HConstants.HBASE_CLIENT_RETRIES_NUMBER;
021
022import java.io.IOException;
023import java.util.Arrays;
024import java.util.List;
025import java.util.stream.Collectors;
026import org.apache.hadoop.conf.Configuration;
027import org.apache.hadoop.hbase.client.Admin;
028import org.apache.hadoop.hbase.master.HMaster;
029import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;
030import org.apache.hadoop.hbase.master.procedure.RefreshHFilesTableProcedure;
031import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
032import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility;
033import org.apache.hadoop.hbase.regionserver.HRegionServer;
034import org.apache.hadoop.hbase.util.Bytes;
035import org.apache.hadoop.hbase.util.JVMClusterUtil;
036import org.slf4j.Logger;
037import org.slf4j.LoggerFactory;
038
039public class TestRefreshHFilesBase {
040
041  private static final Logger LOG = LoggerFactory.getLogger(TestRefreshHFilesBase.class);
042
043  protected static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
044  protected Admin admin;
045  protected HMaster master;
046  List<HRegionServer> regionServers;
047  protected SingleProcessHBaseCluster cluster;
048  protected ProcedureExecutor<MasterProcedureEnv> procExecutor;
049  protected static Configuration conf;
050  protected static final TableName TEST_TABLE = TableName.valueOf("testRefreshHFilesTable");
051  protected static final String TEST_NAMESPACE = "testRefreshHFilesNamespace";
052  protected static final byte[] TEST_FAMILY = Bytes.toBytes("testRefreshHFilesCF1");
053
054  protected void createTableAndWait(TableName table, byte[] cf)
055    throws IOException, InterruptedException {
056    TEST_UTIL.createTable(table, cf);
057    TEST_UTIL.waitTableAvailable(table);
058  }
059
060  protected void createTableInNamespaceAndWait(String namespace, TableName table, byte[] cf)
061    throws IOException, InterruptedException {
062    TableName fqTableName = TableName.valueOf(namespace + table.getNameAsString());
063    TEST_UTIL.createTable(fqTableName, cf);
064    TEST_UTIL.waitTableAvailable(fqTableName);
065  }
066
067  protected void deleteTable(TableName table) throws IOException {
068    TEST_UTIL.deleteTableIfAny(table);
069  }
070
071  protected void createNamespace(String namespace) throws RuntimeException {
072    try {
073      final NamespaceDescriptor nsd = NamespaceDescriptor.create(namespace).build();
074      // Create the namespace if it doesn’t exist
075      if (
076        Arrays.stream(admin.listNamespaceDescriptors())
077          .noneMatch(ns -> ns.getName().equals(namespace))
078      ) {
079        admin.createNamespace(nsd);
080      }
081    } catch (Exception e) {
082      throw new RuntimeException(e);
083    }
084  }
085
086  protected void deleteNamespace(String namespace) {
087    try {
088      // List table in namespace
089      TableName[] tables = admin.listTableNamesByNamespace(namespace);
090      for (TableName t : tables) {
091        TEST_UTIL.deleteTableIfAny(t);
092      }
093      // Now delete the namespace
094      admin.deleteNamespace(namespace);
095    } catch (Exception e) {
096      LOG.debug(
097        "Unable to delete namespace " + namespace + " post test execution. This isn't a failure");
098    }
099  }
100
101  protected void submitProcedureAndAssertNotFailed(RefreshHFilesTableProcedure procedure) {
102    long procId = procExecutor.submitProcedure(procedure);
103    ProcedureTestingUtility.waitProcedure(procExecutor, procId);
104    ProcedureTestingUtility.assertProcNotFailed(procExecutor.getResult(procId));
105  }
106
107  protected void setReadOnlyMode(boolean isReadOnly) {
108    conf.setBoolean(HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY, isReadOnly);
109    notifyConfigurationObservers();
110  }
111
112  private void notifyConfigurationObservers() {
113    master.getConfigurationManager().notifyAllObservers(TEST_UTIL.getConfiguration());
114    for (HRegionServer rs : regionServers) {
115      rs.getConfigurationManager().notifyAllObservers(TEST_UTIL.getConfiguration());
116    }
117  }
118
119  private void setupReadOnlyConf(boolean addReadOnlyConf) {
120    if (!addReadOnlyConf) return;
121    // Keep ReadOnly property to false at the beginning so that create table succeed.
122    conf.setBoolean(HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY, false);
123  }
124
125  protected void baseSetup(boolean addReadOnlyConf) throws Exception {
126    conf = TEST_UTIL.getConfiguration();
127    // Shorten the run time of failed unit tests by limiting retries and the session timeout
128    // threshold
129    conf.setInt(HBASE_CLIENT_RETRIES_NUMBER, 1);
130    conf.setInt(HConstants.ZK_SESSION_TIMEOUT, 1000);
131    conf.setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, 60000);
132    conf.setInt(HConstants.HBASE_CLIENT_OPERATION_TIMEOUT, 120000);
133
134    setupReadOnlyConf(addReadOnlyConf);
135
136    try {
137      // Start the test cluster
138      cluster = TEST_UTIL.startMiniCluster(1);
139      admin = TEST_UTIL.getAdmin();
140      procExecutor = TEST_UTIL.getHBaseCluster().getMaster().getMasterProcedureExecutor();
141      master = TEST_UTIL.getHBaseCluster().getMaster();
142      regionServers = cluster.getRegionServerThreads().stream()
143        .map(JVMClusterUtil.RegionServerThread::getRegionServer).collect(Collectors.toList());
144    } catch (Exception e) {
145      TEST_UTIL.shutdownMiniCluster();
146      throw new RuntimeException(e);
147    }
148  }
149
150  protected void baseTearDown() throws Exception {
151    if (admin != null) {
152      admin.close();
153    }
154    TEST_UTIL.shutdownMiniCluster();
155  }
156
157}