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 java.io.IOException;
021import java.util.Date;
022import java.util.List;
023import java.util.Random;
024import java.util.concurrent.ThreadLocalRandom;
025import org.apache.hadoop.conf.Configuration;
026import org.apache.hadoop.fs.FileSystem;
027import org.apache.hadoop.fs.Path;
028import org.apache.hadoop.hbase.Cell;
029import org.apache.hadoop.hbase.CellUtil;
030import org.apache.hadoop.hbase.HBaseTestingUtility;
031import org.apache.hadoop.hbase.KeyValue;
032import org.apache.hadoop.hbase.TableName;
033import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
034import org.apache.hadoop.hbase.client.Result;
035import org.apache.hadoop.hbase.client.ResultScanner;
036import org.apache.hadoop.hbase.client.Scan;
037import org.apache.hadoop.hbase.client.Table;
038import org.apache.hadoop.hbase.io.compress.Compression;
039import org.apache.hadoop.hbase.io.crypto.Encryption;
040import org.apache.hadoop.hbase.io.hfile.CacheConfig;
041import org.apache.hadoop.hbase.regionserver.StoreFileWriter;
042import org.apache.hadoop.hbase.util.Bytes;
043import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
044import org.junit.Assert;
045
046public class MobTestUtil {
047  protected static final char FIRST_CHAR = 'a';
048  protected static final char LAST_CHAR = 'z';
049
050  protected static String generateRandomString(int demoLength) {
051    String base = "abcdefghijklmnopqrstuvwxyz";
052    Random rand = ThreadLocalRandom.current();
053    StringBuilder sb = new StringBuilder();
054    for (int i = 0; i < demoLength; i++) {
055      int number = rand.nextInt(base.length());
056      sb.append(base.charAt(number));
057    }
058    return sb.toString();
059  }
060
061  protected static void writeStoreFile(final StoreFileWriter writer, String caseName)
062    throws IOException {
063    writeStoreFile(writer, Bytes.toBytes(caseName), Bytes.toBytes(caseName));
064  }
065
066  /*
067   * Writes HStoreKey and ImmutableBytes data to passed writer and then closes it. n * n
068   */
069  private static void writeStoreFile(final StoreFileWriter writer, byte[] fam, byte[] qualifier)
070    throws IOException {
071    long now = EnvironmentEdgeManager.currentTime();
072    try {
073      for (char d = FIRST_CHAR; d <= LAST_CHAR; d++) {
074        for (char e = FIRST_CHAR; e <= LAST_CHAR; e++) {
075          byte[] b = new byte[] { (byte) d, (byte) e };
076          writer.append(new KeyValue(b, fam, qualifier, now, b));
077        }
078      }
079    } finally {
080      writer.close();
081    }
082  }
083
084  /**
085   * Compare two Cells only for their row family qualifier value
086   */
087  public static void assertCellEquals(Cell firstKeyValue, Cell secondKeyValue) {
088    Assert.assertArrayEquals(CellUtil.cloneRow(firstKeyValue), CellUtil.cloneRow(secondKeyValue));
089    Assert.assertArrayEquals(CellUtil.cloneFamily(firstKeyValue),
090      CellUtil.cloneFamily(secondKeyValue));
091    Assert.assertArrayEquals(CellUtil.cloneQualifier(firstKeyValue),
092      CellUtil.cloneQualifier(secondKeyValue));
093    Assert.assertArrayEquals(CellUtil.cloneValue(firstKeyValue),
094      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        Assert.assertArrayEquals(expectedValue, CellUtil.cloneValue(cell));
106        count++;
107      }
108    }
109    results.close();
110    Assert.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(HBaseTestingUtility util, 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 util.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}