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 static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertTrue; 022 023import java.util.ArrayList; 024import java.util.List; 025import org.apache.hadoop.hbase.HBaseClassTestRule; 026import org.apache.hadoop.hbase.HBaseTestingUtility; 027import org.apache.hadoop.hbase.TableName; 028import org.apache.hadoop.hbase.testclassification.ClientTests; 029import org.apache.hadoop.hbase.testclassification.LargeTests; 030import org.apache.hadoop.hbase.util.Bytes; 031import org.junit.AfterClass; 032import org.junit.BeforeClass; 033import org.junit.ClassRule; 034import org.junit.Rule; 035import org.junit.Test; 036import org.junit.experimental.categories.Category; 037import org.junit.rules.TestName; 038import org.slf4j.Logger; 039import org.slf4j.LoggerFactory; 040 041@Category({ LargeTests.class, ClientTests.class }) 042public class TestHTableMultiplexer { 043 044 @ClassRule 045 public static final HBaseClassTestRule CLASS_RULE = 046 HBaseClassTestRule.forClass(TestHTableMultiplexer.class); 047 048 private static final Logger LOG = LoggerFactory.getLogger(TestHTableMultiplexer.class); 049 private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); 050 private static byte[] FAMILY = Bytes.toBytes("testFamily"); 051 private static byte[] QUALIFIER = Bytes.toBytes("testQualifier"); 052 private static byte[] VALUE1 = Bytes.toBytes("testValue1"); 053 private static byte[] VALUE2 = Bytes.toBytes("testValue2"); 054 private static int SLAVES = 3; 055 private static int PER_REGIONSERVER_QUEUE_SIZE = 100000; 056 057 @Rule 058 public TestName name = new TestName(); 059 060 /** 061 * @throws java.lang.Exception 062 */ 063 @BeforeClass 064 public static void setUpBeforeClass() throws Exception { 065 TEST_UTIL.startMiniCluster(SLAVES); 066 } 067 068 /** 069 * @throws java.lang.Exception 070 */ 071 @AfterClass 072 public static void tearDownAfterClass() throws Exception { 073 TEST_UTIL.shutdownMiniCluster(); 074 } 075 076 private static void checkExistence(Table htable, byte[] row, byte[] family, byte[] quality) 077 throws Exception { 078 // verify that the Get returns the correct result 079 Result r; 080 Get get = new Get(row); 081 get.addColumn(FAMILY, QUALIFIER); 082 int nbTry = 0; 083 do { 084 assertTrue("Fail to get from " + htable.getName() + " after " + nbTry + " tries", nbTry < 50); 085 nbTry++; 086 Thread.sleep(100); 087 r = htable.get(get); 088 } while (r == null || r.getValue(FAMILY, QUALIFIER) == null); 089 assertEquals("value", Bytes.toStringBinary(VALUE1), 090 Bytes.toStringBinary(r.getValue(FAMILY, QUALIFIER))); 091 } 092 093 @Test 094 public void testHTableMultiplexer() throws Exception { 095 final TableName tableName1 = TableName.valueOf(name.getMethodName() + "_1"); 096 final TableName tableName2 = TableName.valueOf(name.getMethodName() + "_2"); 097 final int NUM_REGIONS = 10; 098 final int VERSION = 3; 099 List<Put> failedPuts; 100 boolean success; 101 102 HTableMultiplexer multiplexer = 103 new HTableMultiplexer(TEST_UTIL.getConfiguration(), PER_REGIONSERVER_QUEUE_SIZE); 104 105 Table htable1 = TEST_UTIL.createTable(tableName1, new byte[][] { FAMILY }, VERSION, 106 Bytes.toBytes("aaaaa"), Bytes.toBytes("zzzzz"), NUM_REGIONS); 107 Table htable2 = TEST_UTIL.createTable(tableName2, new byte[][] { FAMILY }, VERSION, 108 Bytes.toBytes("aaaaa"), Bytes.toBytes("zzzzz"), NUM_REGIONS); 109 TEST_UTIL.waitUntilAllRegionsAssigned(tableName1); 110 TEST_UTIL.waitUntilAllRegionsAssigned(tableName2); 111 112 try (RegionLocator rl = TEST_UTIL.getConnection().getRegionLocator(tableName1)) { 113 byte[][] startRows = rl.getStartKeys(); 114 byte[][] endRows = rl.getEndKeys(); 115 116 // SinglePut case 117 for (int i = 0; i < NUM_REGIONS; i++) { 118 byte[] row = startRows[i]; 119 if (row == null || row.length <= 0) continue; 120 Put put = new Put(row).addColumn(FAMILY, QUALIFIER, VALUE1); 121 success = multiplexer.put(tableName1, put); 122 assertTrue("multiplexer.put returns", success); 123 124 put = new Put(row).addColumn(FAMILY, QUALIFIER, VALUE1); 125 success = multiplexer.put(tableName2, put); 126 assertTrue("multiplexer.put failed", success); 127 128 LOG.info("Put for " + Bytes.toStringBinary(startRows[i]) + " @ iteration " + (i + 1)); 129 130 // verify that the Get returns the correct result 131 checkExistence(htable1, startRows[i], FAMILY, QUALIFIER); 132 checkExistence(htable2, startRows[i], FAMILY, QUALIFIER); 133 } 134 135 // MultiPut case 136 List<Put> multiput = new ArrayList<>(); 137 for (int i = 0; i < NUM_REGIONS; i++) { 138 byte[] row = endRows[i]; 139 if (row == null || row.length <= 0) continue; 140 Put put = new Put(row); 141 put.addColumn(FAMILY, QUALIFIER, VALUE2); 142 multiput.add(put); 143 } 144 failedPuts = multiplexer.put(tableName1, multiput); 145 assertTrue(failedPuts == null); 146 147 // verify that the Get returns the correct result 148 for (int i = 0; i < NUM_REGIONS; i++) { 149 byte[] row = endRows[i]; 150 if (row == null || row.length <= 0) continue; 151 Get get = new Get(row); 152 get.addColumn(FAMILY, QUALIFIER); 153 Result r; 154 int nbTry = 0; 155 do { 156 assertTrue(nbTry++ < 50); 157 Thread.sleep(100); 158 r = htable1.get(get); 159 } while ( 160 r == null || r.getValue(FAMILY, QUALIFIER) == null 161 || Bytes.compareTo(VALUE2, r.getValue(FAMILY, QUALIFIER)) != 0 162 ); 163 } 164 } 165 } 166}