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.mob;
019
020import static org.junit.jupiter.api.Assertions.assertArrayEquals;
021import static org.junit.jupiter.api.Assertions.assertEquals;
022
023import java.io.IOException;
024import java.util.Date;
025import java.util.List;
026import java.util.Random;
027import java.util.concurrent.ThreadLocalRandom;
028import org.apache.hadoop.conf.Configuration;
029import org.apache.hadoop.fs.FileSystem;
030import org.apache.hadoop.fs.Path;
031import org.apache.hadoop.hbase.Cell;
032import org.apache.hadoop.hbase.CellUtil;
033import org.apache.hadoop.hbase.HBaseTestingUtil;
034import org.apache.hadoop.hbase.KeyValue;
035import org.apache.hadoop.hbase.TableName;
036import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
037import org.apache.hadoop.hbase.client.Result;
038import org.apache.hadoop.hbase.client.ResultScanner;
039import org.apache.hadoop.hbase.client.Scan;
040import org.apache.hadoop.hbase.client.Table;
041import org.apache.hadoop.hbase.io.compress.Compression;
042import org.apache.hadoop.hbase.io.crypto.Encryption;
043import org.apache.hadoop.hbase.io.hfile.CacheConfig;
044import org.apache.hadoop.hbase.regionserver.StoreFileWriter;
045import org.apache.hadoop.hbase.util.Bytes;
046import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
047
048public class MobTestUtil {
049  protected static final char FIRST_CHAR = 'a';
050  protected static final char LAST_CHAR = 'z';
051
052  protected static String generateRandomString(int demoLength) {
053    String base = "abcdefghijklmnopqrstuvwxyz";
054    Random rand = ThreadLocalRandom.current();
055    StringBuilder sb = new StringBuilder();
056    for (int i = 0; i < demoLength; i++) {
057      int number = rand.nextInt(base.length());
058      sb.append(base.charAt(number));
059    }
060    return sb.toString();
061  }
062
063  protected static void writeStoreFile(final StoreFileWriter writer, String caseName)
064    throws IOException {
065    writeStoreFile(writer, Bytes.toBytes(caseName), Bytes.toBytes(caseName));
066  }
067
068  /*
069   * Writes HStoreKey and ImmutableBytes data to passed writer and then closes it.
070   */
071  private static void writeStoreFile(final StoreFileWriter writer, byte[] fam, byte[] qualifier)
072    throws IOException {
073    long now = EnvironmentEdgeManager.currentTime();
074    try {
075      for (char d = FIRST_CHAR; d <= LAST_CHAR; d++) {
076        for (char e = FIRST_CHAR; e <= LAST_CHAR; e++) {
077          byte[] b = new byte[] { (byte) d, (byte) e };
078          writer.append(new KeyValue(b, fam, qualifier, now, b));
079        }
080      }
081    } finally {
082      writer.close();
083    }
084  }
085
086  /**
087   * Compare two Cells only for their row family qualifier value
088   */
089  public static void assertCellEquals(Cell firstKeyValue, Cell secondKeyValue) {
090    assertArrayEquals(CellUtil.cloneRow(firstKeyValue), CellUtil.cloneRow(secondKeyValue));
091    assertArrayEquals(CellUtil.cloneFamily(firstKeyValue), CellUtil.cloneFamily(secondKeyValue));
092    assertArrayEquals(CellUtil.cloneQualifier(firstKeyValue),
093      CellUtil.cloneQualifier(secondKeyValue));
094    assertArrayEquals(CellUtil.cloneValue(firstKeyValue), CellUtil.cloneValue(secondKeyValue));
095  }
096
097  public static void assertCellsValue(Table table, Scan scan, byte[] expectedValue,
098    int expectedCount) throws IOException {
099    ResultScanner results = table.getScanner(scan);
100    int count = 0;
101    for (Result res : results) {
102      List<Cell> cells = res.listCells();
103      for (Cell cell : cells) {
104        // Verify the value
105        assertArrayEquals(expectedValue, CellUtil.cloneValue(cell));
106        count++;
107      }
108    }
109    results.close();
110    assertEquals(expectedCount, count);
111  }
112
113  /**
114   * Gets the number of rows in the given table.
115   * @param table to get the scanner
116   * @return the number of rows
117   */
118  public static int countMobRows(final Table table) throws IOException {
119    Scan scan = new Scan();
120    // Do not retrieve the mob data when scanning
121    scan.setAttribute(MobConstants.MOB_SCAN_RAW, Bytes.toBytes(Boolean.TRUE));
122    return HBaseTestingUtil.countRows(table, scan);
123  }
124
125  public static Path generateMOBFileForRegion(Configuration conf, TableName tableName,
126    ColumnFamilyDescriptor familyDescriptor, String regionName) throws IOException {
127    Date date = new Date();
128    String dateStr = MobUtils.formatDate(date);
129    FileSystem fs = FileSystem.get(conf);
130    Path cfMOBDir = MobUtils.getMobFamilyPath(conf, tableName, familyDescriptor.getNameAsString());
131    StoreFileWriter writer = MobUtils.createWriter(conf, fs, familyDescriptor, dateStr, cfMOBDir,
132      1000L, Compression.Algorithm.NONE, "startKey", CacheConfig.DISABLED, Encryption.Context.NONE,
133      false, "");
134    writer.close();
135    return writer.getPath();
136  }
137}