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.backup;
019
020import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_ENABLE_CONTINUOUS_BACKUP;
021import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_PITR_BACKUP_PATH;
022import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_TABLE;
023import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_TABLE_MAPPING;
024import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_TO_DATETIME;
025
026import java.io.IOException;
027import java.util.ArrayList;
028import java.util.Arrays;
029import java.util.List;
030import java.util.stream.Collectors;
031import org.apache.hadoop.conf.Configuration;
032import org.apache.hadoop.fs.FileSystem;
033import org.apache.hadoop.fs.Path;
034import org.apache.hadoop.hbase.HBaseTestingUtil;
035import org.apache.hadoop.hbase.TableName;
036import org.apache.hadoop.hbase.client.Connection;
037import org.apache.hadoop.hbase.client.Table;
038import org.apache.hadoop.hbase.tool.BulkLoadHFiles;
039import org.apache.hadoop.hbase.tool.BulkLoadHFilesTool;
040import org.apache.hadoop.hbase.util.Bytes;
041import org.apache.hadoop.hbase.util.HFileTestUtil;
042import org.apache.yetus.audience.InterfaceAudience;
043import org.slf4j.Logger;
044import org.slf4j.LoggerFactory;
045
046@InterfaceAudience.Private
047public final class PITRTestUtil {
048  private static final Logger LOG = LoggerFactory.getLogger(PITRTestUtil.class);
049  private static final int DEFAULT_WAIT_FOR_REPLICATION_MS = 30_000;
050
051  private PITRTestUtil() {
052    // Utility class
053  }
054
055  public static String[] buildPITRArgs(TableName[] sourceTables, TableName[] targetTables,
056    long endTime, String backupRootDir) {
057    String sourceTableNames =
058      Arrays.stream(sourceTables).map(TableName::getNameAsString).collect(Collectors.joining(","));
059    String targetTableNames =
060      Arrays.stream(targetTables).map(TableName::getNameAsString).collect(Collectors.joining(","));
061
062    List<String> args = new ArrayList<>();
063    args.add("-" + OPTION_TABLE);
064    args.add(sourceTableNames);
065    args.add("-" + OPTION_TABLE_MAPPING);
066    args.add(targetTableNames);
067    args.add("-" + OPTION_TO_DATETIME);
068    args.add(String.valueOf(endTime));
069
070    if (backupRootDir != null) {
071      args.add("-" + OPTION_PITR_BACKUP_PATH);
072      args.add(backupRootDir);
073    }
074
075    return args.toArray(new String[0]);
076  }
077
078  public static String[] buildBackupArgs(String backupType, TableName[] tables,
079    boolean continuousEnabled, String backupRootDir) {
080    String tableNames =
081      Arrays.stream(tables).map(TableName::getNameAsString).collect(Collectors.joining(","));
082
083    List<String> args = new ArrayList<>(
084      Arrays.asList("create", backupType, backupRootDir, "-" + OPTION_TABLE, tableNames));
085
086    if (continuousEnabled) {
087      args.add("-" + OPTION_ENABLE_CONTINUOUS_BACKUP);
088    }
089
090    return args.toArray(new String[0]);
091  }
092
093  public static void loadRandomData(HBaseTestingUtil testUtil, TableName tableName, byte[] family,
094    int totalRows) throws IOException {
095    try (Table table = testUtil.getConnection().getTable(tableName)) {
096      testUtil.loadRandomRows(table, family, 32, totalRows);
097    }
098  }
099
100  public static void waitForReplication() {
101    try {
102      LOG.info("Waiting for replication to complete for {} ms", DEFAULT_WAIT_FOR_REPLICATION_MS);
103      Thread.sleep(DEFAULT_WAIT_FOR_REPLICATION_MS);
104    } catch (InterruptedException e) {
105      Thread.currentThread().interrupt();
106      throw new RuntimeException("Interrupted while waiting for replication", e);
107    }
108  }
109
110  public static int getRowCount(HBaseTestingUtil testUtil, TableName tableName) throws IOException {
111    try (Table table = testUtil.getConnection().getTable(tableName)) {
112      return HBaseTestingUtil.countRows(table);
113    }
114  }
115
116  public static void generateHFiles(Path outputDir, Configuration conf, String cfName)
117    throws IOException {
118    String hFileName = "MyHFile";
119    int numRows = 1000;
120
121    FileSystem fs = FileSystem.get(conf);
122    outputDir = outputDir.makeQualified(fs.getUri(), fs.getWorkingDirectory());
123
124    byte[] from = Bytes.toBytes(cfName + "begin");
125    byte[] to = Bytes.toBytes(cfName + "end");
126
127    Path familyDir = new Path(outputDir, cfName);
128    HFileTestUtil.createHFile(conf, fs, new Path(familyDir, hFileName), Bytes.toBytes(cfName),
129      Bytes.toBytes("qualifier"), from, to, numRows);
130  }
131
132  public static void bulkLoadHFiles(TableName tableName, Path inputDir, Connection conn,
133    Configuration conf) throws IOException {
134    conf.setBoolean(BulkLoadHFilesTool.BULK_LOAD_HFILES_BY_FAMILY, true);
135
136    try (Table table = conn.getTable(tableName)) {
137      BulkLoadHFiles loader = new BulkLoadHFilesTool(conf);
138      loader.bulkLoad(table.getName(), inputDir);
139    } finally {
140      conf.setBoolean(BulkLoadHFilesTool.BULK_LOAD_HFILES_BY_FAMILY, false);
141    }
142  }
143}