View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.hadoop.hbase.client;
20  
21  import org.apache.hadoop.conf.Configuration;
22  import org.apache.hadoop.hbase.HBaseTestingUtility;
23  import org.apache.hadoop.hbase.HColumnDescriptor;
24  import org.apache.hadoop.hbase.HTableDescriptor;
25  import org.apache.hadoop.hbase.TableName;
26  import org.apache.hadoop.hbase.testclassification.MediumTests;
27  import org.apache.hadoop.hbase.util.Bytes;
28  import org.apache.log4j.Logger;
29  import org.junit.After;
30  import org.junit.AfterClass;
31  import org.junit.Assert;
32  import org.junit.Before;
33  import org.junit.BeforeClass;
34  import org.junit.Test;
35  import org.junit.experimental.categories.Category;
36  
37  import java.io.IOException;
38  import java.util.Random;
39  
40  @Category({ MediumTests.class })
41  public class TestFromClientGetWithClosestRowBefore {
42  
43    private static final Logger LOG = Logger.getLogger(TestFromClientGetWithClosestRowBefore.class);
44    private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
45    private static Configuration CONF;
46    private static final TableName TEST_TABLE = TableName.valueOf("test_table");
47    private static final byte[] COLUMN_FAMILY = Bytes.toBytes("f1");
48    private static final Random RANDOM = new Random();
49  
50    @BeforeClass
51    public static void setup() throws Exception {
52      CONF = UTIL.getConfiguration();
53      UTIL.startMiniCluster();
54    }
55  
56    @AfterClass
57    public static void teardown() throws Exception {
58      UTIL.shutdownMiniCluster();
59    }
60  
61    @Before
62    public void setUp() throws Exception {
63      HTableDescriptor htd = new HTableDescriptor(TEST_TABLE);
64      HColumnDescriptor hcd = new HColumnDescriptor(COLUMN_FAMILY);
65      htd.addFamily(hcd);
66  
67      UTIL.getHBaseAdmin().createTable(htd);
68    }
69  
70    @After
71    public void tearDown() throws Exception {
72      for (HTableDescriptor htd : UTIL.getHBaseAdmin().listTables()) {
73        UTIL.deleteTable(htd.getTableName());
74      }
75    }
76  
77    @Test
78    public void testGetWithClosestRowBeforeWhenSplitRegion() throws Exception {
79      Thread t = new Thread() {
80        public void run() {
81          try {
82            Thread.sleep(100);
83            UTIL.getHBaseAdmin().split(TEST_TABLE);
84          } catch (Exception e) {
85            LOG.error("split region failed: ", e);
86          }
87        }
88      };
89  
90      try (Connection conn = ConnectionFactory.createConnection(CONF)) {
91        try (Table table = conn.getTable(TEST_TABLE)) {
92          for (int i = 0; i < 1000; i++) {
93            byte[] data = Bytes.toBytes(String.format("%026d", i));
94            Put put = new Put(data).addColumn(COLUMN_FAMILY, null, data);
95            table.put(put);
96          }
97        }
98        try (Table table = conn.getTable(TableName.META_TABLE_NAME)) {
99          t.start();
100         for (int i = 0; i < 10000; i++) {
101           Get get = new Get(Bytes.toBytes(TEST_TABLE + ",,:")).addFamily(Bytes.toBytes("info"))
102               .setClosestRowBefore(true);
103           Result result = table.get(get);
104           if (Result.getTotalSizeOfCells(result) == 0) {
105             Assert.fail("Get with closestRowBefore return NONE result.");
106           }
107         }
108       }
109     }
110   }
111 
112   @Test
113   public void testClosestRowIsLatestPutRow() throws IOException {
114     final int[] initialRowkeys = new int[] { 1, 1000 };
115 
116     Thread t = new Thread() {
117       public void run() {
118         try {
119           // a huge value to slow down transaction committing.
120           byte[] value = new byte[512 * 1024];
121           for (int i = 0; i < value.length; i++) {
122             value[i] = (byte) RANDOM.nextInt(256);
123           }
124 
125           // Put rowKey= 2,3,4,...,(initialRowkeys[1]-1) into table, let the rowkey returned by a
126           // Get with closestRowBefore to be exactly the latest put rowkey.
127           try (Connection conn = ConnectionFactory.createConnection(CONF)) {
128             try (Table table = conn.getTable(TEST_TABLE)) {
129               for (int i = initialRowkeys[0] + 1; i < initialRowkeys[1]; i++) {
130                 byte[] data = Bytes.toBytes(String.format("%026d", i));
131                 Put put = new Put(data).addColumn(COLUMN_FAMILY, null, value);
132                 table.put(put);
133               }
134             }
135           }
136         } catch (Exception e) {
137           LOG.error("Put huge value into table failed: ", e);
138         }
139       }
140     };
141 
142     try (Connection conn = ConnectionFactory.createConnection(CONF)) {
143       try (Table table = conn.getTable(TEST_TABLE)) {
144 
145         // Put the boundary into table firstly.
146         for (int i = 0; i < initialRowkeys.length; i++) {
147           byte[] rowKey = Bytes.toBytes(String.format("%026d", initialRowkeys[i]));
148           Put put = new Put(rowKey).addColumn(COLUMN_FAMILY, null, rowKey);
149           table.put(put);
150         }
151 
152         t.start();
153         byte[] rowKey = Bytes.toBytes(String.format("%026d", initialRowkeys[1] - 1));
154         for (int i = 0; i < 1000; i++) {
155           Get get = new Get(rowKey).addFamily(COLUMN_FAMILY).setClosestRowBefore(true);
156           Result result = table.get(get);
157           if (Result.getTotalSizeOfCells(result) == 0) {
158             Assert.fail("Get with closestRowBefore return NONE result.");
159           }
160         }
161       }
162     }
163   }
164 }