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.thrift2;
019
020import static org.apache.hadoop.hbase.thrift.Constants.THRIFT_INFO_SERVER_PORT;
021import static org.junit.Assert.assertEquals;
022import static org.junit.Assert.assertFalse;
023import static org.junit.Assert.assertNotNull;
024import static org.junit.Assert.assertNull;
025import static org.junit.Assert.assertTrue;
026
027import java.io.IOException;
028import java.util.ArrayList;
029import java.util.Collections;
030import java.util.Iterator;
031import java.util.List;
032
033import org.apache.hadoop.conf.Configuration;
034import org.apache.hadoop.hbase.Cell;
035import org.apache.hadoop.hbase.CellUtil;
036import org.apache.hadoop.hbase.CompareOperator;
037import org.apache.hadoop.hbase.HBaseClassTestRule;
038import org.apache.hadoop.hbase.HBaseConfiguration;
039import org.apache.hadoop.hbase.HBaseTestingUtility;
040import org.apache.hadoop.hbase.HConstants;
041import org.apache.hadoop.hbase.NamespaceDescriptor;
042import org.apache.hadoop.hbase.TableName;
043import org.apache.hadoop.hbase.client.Admin;
044import org.apache.hadoop.hbase.client.ClusterConnection;
045import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
046import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
047import org.apache.hadoop.hbase.client.Connection;
048import org.apache.hadoop.hbase.client.ConnectionFactory;
049import org.apache.hadoop.hbase.client.Delete;
050import org.apache.hadoop.hbase.client.Durability;
051import org.apache.hadoop.hbase.client.Get;
052import org.apache.hadoop.hbase.client.Put;
053import org.apache.hadoop.hbase.client.Result;
054import org.apache.hadoop.hbase.client.ResultScanner;
055import org.apache.hadoop.hbase.client.Scan;
056import org.apache.hadoop.hbase.client.Table;
057import org.apache.hadoop.hbase.client.TableDescriptor;
058import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
059import org.apache.hadoop.hbase.filter.ColumnCountGetFilter;
060import org.apache.hadoop.hbase.filter.ColumnValueFilter;
061import org.apache.hadoop.hbase.filter.FilterList;
062import org.apache.hadoop.hbase.filter.PrefixFilter;
063import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding;
064import org.apache.hadoop.hbase.testclassification.MediumTests;
065import org.apache.hadoop.hbase.testclassification.RestTests;
066import org.apache.hadoop.hbase.thrift.Constants;
067import org.apache.hadoop.hbase.thrift2.client.ThriftConnection;
068import org.apache.hadoop.hbase.util.Bytes;
069import org.junit.AfterClass;
070import org.junit.BeforeClass;
071import org.junit.ClassRule;
072import org.junit.Test;
073import org.junit.experimental.categories.Category;
074import org.slf4j.Logger;
075import org.slf4j.LoggerFactory;
076
077@Category({ RestTests.class, MediumTests.class})
078
079public class TestThriftConnection {
080  private static final Logger LOG =
081      LoggerFactory.getLogger(TestThriftConnection.class);
082
083  @ClassRule
084  public static final HBaseClassTestRule CLASS_RULE =
085      HBaseClassTestRule.forClass(TestThriftConnection.class);
086
087  private static final byte[] FAMILYA = Bytes.toBytes("fa");
088  private static final byte[] FAMILYB = Bytes.toBytes("fb");
089  private static final byte[] FAMILYC = Bytes.toBytes("fc");
090  private static final byte[] FAMILYD = Bytes.toBytes("fd");
091
092  private static final byte[] ROW_1 = Bytes.toBytes("testrow1");
093  private static final byte[] ROW_2 = Bytes.toBytes("testrow2");
094  private static final byte[] ROW_3 = Bytes.toBytes("testrow3");
095  private static final byte[] ROW_4 = Bytes.toBytes("testrow4");
096
097  private static final byte[] QUALIFIER_1 = Bytes.toBytes("1");
098  private static final byte[] QUALIFIER_2 = Bytes.toBytes("2");
099  private static final byte[] VALUE_1 = Bytes.toBytes("testvalue1");
100  private static final byte[] VALUE_2 = Bytes.toBytes("testvalue2");
101
102  private static final long ONE_HOUR = 60 * 60 * 1000;
103  private static final long TS_2 = System.currentTimeMillis();
104  private static final long TS_1 = TS_2 - ONE_HOUR;
105
106
107  protected static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
108
109  protected static ThriftServer thriftServer;
110
111  protected static ThriftServer thriftHttpServer;
112
113  protected static int thriftPort;
114  protected static int httpPort;
115
116  protected static Connection thriftConnection;
117  protected static Connection thriftHttpConnection;
118
119  private static Admin thriftAdmin;
120
121  private static ThriftServer startThriftServer(int port, boolean useHttp) {
122    Configuration thriftServerConf = HBaseConfiguration.create(TEST_UTIL.getConfiguration());
123    thriftServerConf.setInt(Constants.PORT_CONF_KEY, port);
124    if (useHttp) {
125      thriftServerConf.setBoolean(Constants.USE_HTTP_CONF_KEY, true);
126    }
127    ThriftServer server = new ThriftServer(thriftServerConf);
128    Thread thriftServerThread = new Thread(() -> {
129      try{
130        server.run();
131      } catch (Exception t) {
132        LOG.error("Thrift Server failed", t);
133      }
134    });
135    thriftServerThread.setDaemon(true);
136    thriftServerThread.start();
137    if (useHttp) {
138      TEST_UTIL.waitFor(10000, () -> server.getHttpServer() != null);
139    } else {
140      TEST_UTIL.waitFor(10000, () -> server.getTserver() != null);
141    }
142    return server;
143  }
144
145  private static Connection createConnection(int port, boolean useHttp) throws IOException {
146    Configuration conf = HBaseConfiguration.create(TEST_UTIL.getConfiguration());
147    conf.set(ClusterConnection.HBASE_CLIENT_CONNECTION_IMPL,
148        ThriftConnection.class.getName());
149    if (useHttp) {
150      conf.set(Constants.HBASE_THRIFT_CLIENT_BUIDLER_CLASS,
151          ThriftConnection.HTTPThriftClientBuilder.class.getName());
152    }
153    String host = HConstants.LOCALHOST;
154    if (useHttp) {
155      host = "http://" + host;
156    }
157    conf.set(Constants.HBASE_THRIFT_SERVER_NAME, host);
158    conf.setInt(Constants.HBASE_THRIFT_SERVER_PORT, port);
159    return ConnectionFactory.createConnection(conf);
160  }
161
162
163  @BeforeClass
164  public static void setUp() throws Exception {
165    // Do not start info server
166    TEST_UTIL.getConfiguration().setInt(THRIFT_INFO_SERVER_PORT , -1);
167    TEST_UTIL.startMiniCluster();
168    thriftPort = HBaseTestingUtility.randomFreePort();
169    httpPort = HBaseTestingUtility.randomFreePort();
170    // Start a thrift server
171    thriftServer = startThriftServer(thriftPort, false);
172    // Start an HTTP thrift server
173    thriftHttpServer = startThriftServer(httpPort, true);
174    thriftConnection = createConnection(thriftPort, false);
175    thriftHttpConnection = createConnection(httpPort, true);
176    thriftAdmin = thriftConnection.getAdmin();
177    LOG.info("TS_1=" + TS_1);
178    LOG.info("TS_2=" + TS_1);
179
180  }
181
182  @AfterClass
183  public static void shutdown() throws Exception {
184    if (thriftAdmin != null) {
185      thriftAdmin.close();
186    }
187    if (thriftHttpConnection != null) {
188      thriftHttpConnection.close();
189    }
190    if (thriftConnection != null) {
191      thriftConnection.close();
192    }
193    if (thriftHttpServer != null) {
194      thriftHttpServer.stop();
195    }
196    TEST_UTIL.shutdownMiniCluster();
197  }
198
199  @Test
200  public void testThrfitAdmin() throws Exception {
201    testThriftAdmin(thriftConnection, "testThrfitAdminNamesapce", "testThrfitAdminTable");
202    testThriftAdmin(thriftHttpConnection, "testThrfitHttpAdminNamesapce",
203        "testThrfitHttpAdminTable");
204  }
205
206  @Test
207  public void testGet() throws Exception {
208    testGet(thriftConnection, "testGetTable");
209    testGet(thriftHttpConnection, "testGetHttpTable");
210
211  }
212
213  public void testGet(Connection connection, String tableName) throws IOException {
214    createTable(thriftAdmin, tableName);
215    try (Table table = connection.getTable(TableName.valueOf(tableName))){
216      Get get = new Get(ROW_1);
217      Result result = table.get(get);
218      byte[] value1 = result.getValue(FAMILYA, QUALIFIER_1);
219      byte[] value2 = result.getValue(FAMILYB, QUALIFIER_2);
220      assertNotNull(value1);
221      assertTrue(Bytes.equals(VALUE_1, value1));
222      assertNull(value2);
223
224      get = new Get(ROW_1);
225      get.addFamily(FAMILYC);
226      result = table.get(get);
227      value1 = result.getValue(FAMILYA, QUALIFIER_1);
228      value2 = result.getValue(FAMILYB, QUALIFIER_2);
229      assertNull(value1);
230      assertNull(value2);
231
232      get = new Get(ROW_1);
233      get.addColumn(FAMILYA, QUALIFIER_1);
234      get.addColumn(FAMILYB, QUALIFIER_2);
235      result = table.get(get);
236      value1 = result.getValue(FAMILYA, QUALIFIER_1);
237      value2 = result.getValue(FAMILYB, QUALIFIER_2);
238      assertNotNull(value1);
239      assertTrue(Bytes.equals(VALUE_1, value1));
240      assertNull(value2);
241
242      get = new Get(ROW_2);
243      result = table.get(get);
244      value1 = result.getValue(FAMILYA, QUALIFIER_1);
245      value2 = result.getValue(FAMILYB, QUALIFIER_2);
246      assertNotNull(value1);
247      assertTrue(Bytes.equals(VALUE_2, value1)); // @TS_2
248      assertNotNull(value2);
249      assertTrue(Bytes.equals(VALUE_2, value2));
250
251      get = new Get(ROW_2);
252      get.addFamily(FAMILYA);
253      result = table.get(get);
254      value1 = result.getValue(FAMILYA, QUALIFIER_1);
255      value2 = result.getValue(FAMILYB, QUALIFIER_2);
256      assertNotNull(value1);
257      assertTrue(Bytes.equals(VALUE_2, value1)); // @TS_2
258      assertNull(value2);
259
260      get = new Get(ROW_2);
261      get.addColumn(FAMILYA, QUALIFIER_1);
262      get.addColumn(FAMILYB, QUALIFIER_2);
263      result = table.get(get);
264      value1 = result.getValue(FAMILYA, QUALIFIER_1);
265      value2 = result.getValue(FAMILYB, QUALIFIER_2);
266      assertNotNull(value1);
267      assertTrue(Bytes.equals(VALUE_2, value1)); // @TS_2
268      assertNotNull(value2);
269      assertTrue(Bytes.equals(VALUE_2, value2));
270
271      // test timestamp
272
273      get = new Get(ROW_2);
274      get.addFamily(FAMILYA);
275      get.addFamily(FAMILYB);
276      get.setTimestamp(TS_1);
277      result = table.get(get);
278      value1 = result.getValue(FAMILYA, QUALIFIER_1);
279      value2 = result.getValue(FAMILYB, QUALIFIER_2);
280      assertNotNull(value1);
281      assertTrue(Bytes.equals(VALUE_1, value1)); // @TS_1
282      assertNull(value2);
283
284      // test timerange
285
286      get = new Get(ROW_2);
287      get.addFamily(FAMILYA);
288      get.addFamily(FAMILYB);
289      get.setTimeRange(0, TS_1 + 1);
290      result = table.get(get);
291      value1 = result.getValue(FAMILYA, QUALIFIER_1);
292      value2 = result.getValue(FAMILYB, QUALIFIER_2);
293      assertNotNull(value1);
294      assertTrue(Bytes.equals(VALUE_1, value1)); // @TS_1
295      assertNull(value2);
296
297      // test maxVersions
298
299      get = new Get(ROW_2);
300      get.addFamily(FAMILYA);
301      get.setMaxVersions(2);
302      result = table.get(get);
303      int count = 0;
304      for (Cell kv: result.listCells()) {
305        if (CellUtil.matchingFamily(kv, FAMILYA) && TS_1 == kv.getTimestamp()) {
306          assertTrue(CellUtil.matchingValue(kv, VALUE_1)); // @TS_1
307          count++;
308        }
309        if (CellUtil.matchingFamily(kv, FAMILYA) && TS_2 == kv.getTimestamp()) {
310          assertTrue(CellUtil.matchingValue(kv, VALUE_2)); // @TS_2
311          count++;
312        }
313      }
314      assertEquals(2, count);
315    }
316
317  }
318
319  @Test
320  public void testHBASE22011()throws Exception{
321    testHBASE22011(thriftConnection, "testHBASE22011Table");
322    testHBASE22011(thriftHttpConnection, "testHBASE22011HttpTable");
323  }
324
325  public void testHBASE22011(Connection connection, String tableName) throws IOException {
326    createTable(thriftAdmin, tableName);
327    try (Table table = connection.getTable(TableName.valueOf(tableName))){
328      Get get = new Get(ROW_2);
329      Result result = table.get(get);
330      assertEquals(2, result.listCells().size());
331
332      ColumnCountGetFilter filter = new ColumnCountGetFilter(1);
333      get.setFilter(filter);
334      result = table.get(get);
335      assertEquals(1, result.listCells().size());
336    }
337  }
338
339  @Test
340  public void testMultiGet() throws Exception {
341    testMultiGet(thriftConnection, "testMultiGetTable");
342    testMultiGet(thriftHttpConnection, "testMultiGetHttpTable");
343  }
344
345  public void testMultiGet(Connection connection, String tableName) throws Exception {
346    createTable(thriftAdmin, tableName);
347    try (Table table = connection.getTable(TableName.valueOf(tableName))){
348      ArrayList<Get> gets = new ArrayList<>(2);
349      gets.add(new Get(ROW_1));
350      gets.add(new Get(ROW_2));
351      Result[] results = table.get(gets);
352      assertNotNull(results);
353      assertEquals(2, results.length);
354      assertEquals(1, results[0].size());
355      assertEquals(2, results[1].size());
356
357      //Test Versions
358      gets = new ArrayList<>(2);
359      Get g = new Get(ROW_1);
360      g.setMaxVersions(3);
361      gets.add(g);
362      Get get2 = new Get(ROW_2);
363      get2.setMaxVersions(3);
364      gets.add(get2);
365      results = table.get(gets);
366      assertNotNull(results);
367      assertEquals(2, results.length);
368      assertEquals(1, results[0].size());
369      assertEquals(3, results[1].size());
370
371      gets = new ArrayList<>(1);
372      gets.add(new Get(Bytes.toBytes("RESALLYREALLYNOTTHERE")));
373      results = table.get(gets);
374      assertNotNull(results);
375      assertTrue(results[0].isEmpty());
376
377      gets = new ArrayList<>(3);
378      gets.add(new Get(Bytes.toBytes("RESALLYREALLYNOTTHERE")));
379      gets.add(new Get(ROW_1));
380      gets.add(new Get(ROW_2));
381      results = table.get(gets);
382      assertNotNull(results);
383      assertEquals(3, results.length);
384      assertTrue(results[0].isEmpty());
385    }
386
387  }
388
389  @Test
390  public void testPut() throws Exception {
391    testPut(thriftConnection, "testPutTable");
392    testPut(thriftHttpConnection, "testPutHttpTable");
393  }
394
395  public void testPut(Connection connection, String tableName) throws IOException {
396    createTable(thriftAdmin, tableName);
397    try (Table table = connection.getTable(TableName.valueOf(tableName))){
398      Put put = new Put(ROW_3);
399      put.addColumn(FAMILYA, QUALIFIER_1, VALUE_1);
400      table.put(put);
401
402      Get get = new Get(ROW_3);
403      get.addFamily(FAMILYA);
404      Result result = table.get(get);
405      byte[] value = result.getValue(FAMILYA, QUALIFIER_1);
406      assertNotNull(value);
407      assertTrue(Bytes.equals(VALUE_1, value));
408
409      // multiput
410
411      List<Put> puts = new ArrayList<>(3);
412      put = new Put(ROW_3);
413      put.addColumn(FAMILYB, QUALIFIER_2, VALUE_2);
414      puts.add(put);
415      put = new Put(ROW_4);
416      put.addColumn(FAMILYA, QUALIFIER_1, VALUE_1);
417      puts.add(put);
418      put = new Put(ROW_4);
419      put.addColumn(FAMILYB, QUALIFIER_2, VALUE_2);
420      puts.add(put);
421      table.put(puts);
422
423      get = new Get(ROW_3);
424      get.addFamily(FAMILYB);
425      result = table.get(get);
426      value = result.getValue(FAMILYB, QUALIFIER_2);
427      assertNotNull(value);
428      assertTrue(Bytes.equals(VALUE_2, value));
429      get = new Get(ROW_4);
430      result = table.get(get);
431      value = result.getValue(FAMILYA, QUALIFIER_1);
432      assertNotNull(value);
433      assertTrue(Bytes.equals(VALUE_1, value));
434      value = result.getValue(FAMILYB, QUALIFIER_2);
435      assertNotNull(value);
436      assertTrue(Bytes.equals(VALUE_2, value));
437    }
438  }
439
440  @Test
441  public void testDelete() throws Exception {
442    testDelete(thriftConnection, "testDeleteTable");
443    testDelete(thriftHttpConnection, "testDeleteHttpTable");
444  }
445
446  public void testDelete(Connection connection, String tableName) throws IOException {
447    createTable(thriftAdmin, tableName);
448    try (Table table = connection.getTable(TableName.valueOf(tableName))){
449      Put put = new Put(ROW_3);
450      put.addColumn(FAMILYA, QUALIFIER_1, VALUE_1);
451      put.addColumn(FAMILYB, QUALIFIER_2, VALUE_2);
452      put.addColumn(FAMILYC, QUALIFIER_1, VALUE_1);
453      put.addColumn(FAMILYC, QUALIFIER_2, VALUE_2);
454      table.put(put);
455
456      Get get = new Get(ROW_3);
457      get.addFamily(FAMILYA);
458      get.addFamily(FAMILYB);
459      get.addFamily(FAMILYC);
460      Result result = table.get(get);
461      byte[] value1 = result.getValue(FAMILYA, QUALIFIER_1);
462      byte[] value2 = result.getValue(FAMILYB, QUALIFIER_2);
463      byte[] value3 = result.getValue(FAMILYC, QUALIFIER_1);
464      byte[] value4 = result.getValue(FAMILYC, QUALIFIER_2);
465      assertNotNull(value1);
466      assertTrue(Bytes.equals(VALUE_1, value1));
467      assertNotNull(value2);
468      assertTrue(Bytes.equals(VALUE_2, value2));
469      assertNotNull(value3);
470      assertTrue(Bytes.equals(VALUE_1, value3));
471      assertNotNull(value4);
472      assertTrue(Bytes.equals(VALUE_2, value4));
473
474      Delete delete = new Delete(ROW_3);
475      delete.addColumn(FAMILYB, QUALIFIER_2);
476      table.delete(delete);
477
478      get = new Get(ROW_3);
479      get.addFamily(FAMILYA);
480      get.addFamily(FAMILYB);
481      result = table.get(get);
482      value1 = result.getValue(FAMILYA, QUALIFIER_1);
483      value2 = result.getValue(FAMILYB, QUALIFIER_2);
484      assertNotNull(value1);
485      assertTrue(Bytes.equals(VALUE_1, value1));
486      assertNull(value2);
487
488      delete = new Delete(ROW_3);
489      delete.setTimestamp(1L);
490      table.delete(delete);
491
492      get = new Get(ROW_3);
493      get.addFamily(FAMILYA);
494      get.addFamily(FAMILYB);
495      result = table.get(get);
496      value1 = result.getValue(FAMILYA, QUALIFIER_1);
497      value2 = result.getValue(FAMILYB, QUALIFIER_2);
498      assertNotNull(value1);
499      assertTrue(Bytes.equals(VALUE_1, value1));
500      assertNull(value2);
501
502      // Delete column family from row
503      delete = new Delete(ROW_3);
504      delete.addFamily(FAMILYC);
505      table.delete(delete);
506
507      get = new Get(ROW_3);
508      get.addFamily(FAMILYC);
509      result = table.get(get);
510      value3 = result.getValue(FAMILYC, QUALIFIER_1);
511      value4 = result.getValue(FAMILYC, QUALIFIER_2);
512      assertNull(value3);
513      assertNull(value4);
514
515      delete = new Delete(ROW_3);
516      table.delete(delete);
517
518      get = new Get(ROW_3);
519      get.addFamily(FAMILYA);
520      get.addFamily(FAMILYB);
521      result = table.get(get);
522      value1 = result.getValue(FAMILYA, QUALIFIER_1);
523      value2 = result.getValue(FAMILYB, QUALIFIER_2);
524      assertNull(value1);
525      assertNull(value2);
526    }
527
528  }
529
530  @Test
531  public void testScanner() throws Exception {
532    testScanner(thriftConnection, "testScannerTable");
533    testScanner(thriftHttpConnection, "testScannerHttpTable");
534  }
535
536  public void testScanner(Connection connection, String tableName) throws IOException {
537    createTable(thriftAdmin, tableName);
538    try (Table table = connection.getTable(TableName.valueOf(tableName))){
539      List<Put> puts = new ArrayList<>(4);
540      Put put = new Put(ROW_1);
541      put.addColumn(FAMILYA, QUALIFIER_1, VALUE_1);
542      puts.add(put);
543      put = new Put(ROW_2);
544      put.addColumn(FAMILYA, QUALIFIER_1, VALUE_1);
545      puts.add(put);
546      put = new Put(ROW_3);
547      put.addColumn(FAMILYA, QUALIFIER_1, VALUE_1);
548      puts.add(put);
549      put = new Put(ROW_4);
550      put.addColumn(FAMILYA, QUALIFIER_1, VALUE_1);
551      puts.add(put);
552      table.put(puts);
553
554      ResultScanner scanner = table.getScanner(new Scan());
555
556      Result[] results = scanner.next(1);
557      assertNotNull(results);
558      assertEquals(1, results.length);
559      assertTrue(Bytes.equals(ROW_1, results[0].getRow()));
560
561      Result result = scanner.next();
562      assertNotNull(result);
563      assertTrue(Bytes.equals(ROW_2, result.getRow()));
564
565      results = scanner.next(2);
566      assertNotNull(results);
567      assertEquals(2, results.length);
568      assertTrue(Bytes.equals(ROW_3, results[0].getRow()));
569      assertTrue(Bytes.equals(ROW_4, results[1].getRow()));
570
571      results = scanner.next(1);
572      assertTrue(results == null || results.length == 0);
573      scanner.close();
574
575      scanner = table.getScanner(FAMILYA);
576      results = scanner.next(4);
577      assertNotNull(results);
578      assertEquals(4, results.length);
579      assertTrue(Bytes.equals(ROW_1, results[0].getRow()));
580      assertTrue(Bytes.equals(ROW_2, results[1].getRow()));
581      assertTrue(Bytes.equals(ROW_3, results[2].getRow()));
582      assertTrue(Bytes.equals(ROW_4, results[3].getRow()));
583
584      scanner.close();
585
586      scanner = table.getScanner(FAMILYA,QUALIFIER_1);
587      results = scanner.next(4);
588      assertNotNull(results);
589      assertEquals(4, results.length);
590      assertTrue(Bytes.equals(ROW_1, results[0].getRow()));
591      assertTrue(Bytes.equals(ROW_2, results[1].getRow()));
592      assertTrue(Bytes.equals(ROW_3, results[2].getRow()));
593      assertTrue(Bytes.equals(ROW_4, results[3].getRow()));
594      scanner.close();
595    }
596
597  }
598
599  @Test
600  public void testCheckAndDelete() throws Exception {
601    testCheckAndDelete(thriftConnection, "testCheckAndDeleteTable");
602    testCheckAndDelete(thriftHttpConnection, "testCheckAndDeleteHttpTable");
603  }
604
605
606  public void testCheckAndDelete(Connection connection, String tableName) throws IOException {
607    createTable(thriftAdmin, tableName);
608    try (Table table = connection.getTable(TableName.valueOf(tableName))){
609      Get get = new Get(ROW_1);
610      Result result = table.get(get);
611      byte[] value1 = result.getValue(FAMILYA, QUALIFIER_1);
612      byte[] value2 = result.getValue(FAMILYB, QUALIFIER_2);
613      assertNotNull(value1);
614      assertTrue(Bytes.equals(VALUE_1, value1));
615      assertNull(value2);
616      assertTrue(table.exists(get));
617      assertEquals(1, table.existsAll(Collections.singletonList(get)).length);
618      Delete delete = new Delete(ROW_1);
619
620      table.checkAndMutate(ROW_1, FAMILYA).qualifier(QUALIFIER_1)
621          .ifEquals(VALUE_1).thenDelete(delete);
622      assertFalse(table.exists(get));
623
624      Put put = new Put(ROW_1);
625      put.addColumn(FAMILYA, QUALIFIER_1, VALUE_1);
626      table.put(put);
627
628      assertTrue(table.checkAndMutate(ROW_1, FAMILYA).qualifier(QUALIFIER_1)
629          .ifEquals(VALUE_1).thenPut(put));
630      assertFalse(table.checkAndMutate(ROW_1, FAMILYA).qualifier(QUALIFIER_1)
631          .ifEquals(VALUE_2).thenPut(put));
632    }
633
634  }
635
636  @Test
637  public void testIteratorScaner() throws Exception {
638    testIteratorScanner(thriftConnection, "testIteratorScanerTable");
639    testIteratorScanner(thriftHttpConnection, "testIteratorScanerHttpTable");
640  }
641
642  public void testIteratorScanner(Connection connection, String tableName) throws IOException {
643    createTable(thriftAdmin, tableName);
644    try (Table table = connection.getTable(TableName.valueOf(tableName))){
645      List<Put> puts = new ArrayList<>(4);
646      Put put = new Put(ROW_1);
647      put.addColumn(FAMILYA, QUALIFIER_1, VALUE_1);
648      puts.add(put);
649      put = new Put(ROW_2);
650      put.addColumn(FAMILYA, QUALIFIER_1, VALUE_1);
651      puts.add(put);
652      put = new Put(ROW_3);
653      put.addColumn(FAMILYA, QUALIFIER_1, VALUE_1);
654      puts.add(put);
655      put = new Put(ROW_4);
656      put.addColumn(FAMILYA, QUALIFIER_1, VALUE_1);
657      puts.add(put);
658      table.put(puts);
659      Scan scan = new Scan();
660      scan.setCaching(1);
661      ResultScanner scanner = table.getScanner(scan);
662      Iterator<Result> iterator = scanner.iterator();
663      assertTrue(iterator.hasNext());
664      int counter = 0;
665      while (iterator.hasNext()) {
666        iterator.next();
667        counter++;
668      }
669      assertEquals(4, counter);
670    }
671
672  }
673
674  @Test
675  public void testReverseScan() throws Exception {
676    testReverseScan(thriftConnection, "testReverseScanTable");
677    testReverseScan(thriftHttpConnection, "testReverseScanHttpTable");
678  }
679
680  public void testReverseScan(Connection connection, String tableName) throws IOException {
681    createTable(thriftAdmin, tableName);
682    try (Table table = connection.getTable(TableName.valueOf(tableName))){
683      List<Put> puts = new ArrayList<>(4);
684      Put put = new Put(ROW_1);
685      put.addColumn(FAMILYA, QUALIFIER_1, VALUE_1);
686      puts.add(put);
687      put = new Put(ROW_2);
688      put.addColumn(FAMILYA, QUALIFIER_1, VALUE_1);
689      puts.add(put);
690      put = new Put(ROW_3);
691      put.addColumn(FAMILYA, QUALIFIER_1, VALUE_1);
692      puts.add(put);
693      put = new Put(ROW_4);
694      put.addColumn(FAMILYA, QUALIFIER_1, VALUE_1);
695      puts.add(put);
696      table.put(puts);
697      Scan scan = new Scan();
698      scan.setReversed(true);
699      scan.setCaching(1);
700      ResultScanner scanner = table.getScanner(scan);
701      Iterator<Result> iterator = scanner.iterator();
702      assertTrue(iterator.hasNext());
703      int counter = 0;
704      Result lastResult = null;
705      while (iterator.hasNext()) {
706        Result current = iterator.next();
707        if (lastResult != null) {
708          assertTrue(Bytes.compareTo(lastResult.getRow(), current.getRow()) > 0);
709        }
710        lastResult = current;
711        counter++;
712      }
713      assertEquals(4, counter);
714    }
715
716  }
717
718
719  @Test
720  public void testScanWithFilters() throws Exception {
721    testScanWithFilters(thriftConnection, "testScanWithFiltersTable");
722    testScanWithFilters(thriftHttpConnection, "testScanWithFiltersHttpTable");
723  }
724
725  private void testScanWithFilters(Connection connection, String tableName) throws IOException {
726    createTable(thriftAdmin, tableName);
727    try (Table table = connection.getTable(TableName.valueOf(tableName))){
728      FilterList filterList = new FilterList();
729      PrefixFilter prefixFilter = new PrefixFilter(Bytes.toBytes("testrow"));
730      ColumnValueFilter columnValueFilter = new ColumnValueFilter(FAMILYA, QUALIFIER_1,
731          CompareOperator.EQUAL, VALUE_1);
732      filterList.addFilter(prefixFilter);
733      filterList.addFilter(columnValueFilter);
734      Scan scan = new Scan();
735      scan.setMaxVersions(2);
736      scan.setFilter(filterList);
737      ResultScanner scanner = table.getScanner(scan);
738      Iterator<Result> iterator = scanner.iterator();
739      assertTrue(iterator.hasNext());
740      int counter = 0;
741      while (iterator.hasNext()) {
742        Result result = iterator.next();
743        counter += result.size();
744      }
745      assertEquals(2, counter);
746    }
747  }
748
749
750  private TableDescriptor createTable(Admin admin, String tableName) throws IOException {
751    TableDescriptorBuilder builder = TableDescriptorBuilder
752        .newBuilder(TableName.valueOf(tableName));
753    ColumnFamilyDescriptorBuilder familyABuilder = ColumnFamilyDescriptorBuilder
754        .newBuilder(FAMILYA);
755    familyABuilder.setMaxVersions(3);
756    ColumnFamilyDescriptorBuilder familyBBuilder = ColumnFamilyDescriptorBuilder
757        .newBuilder(FAMILYB);
758    familyBBuilder.setMaxVersions(3);
759    ColumnFamilyDescriptorBuilder familyCBuilder = ColumnFamilyDescriptorBuilder
760        .newBuilder(FAMILYC);
761    familyCBuilder.setMaxVersions(3);
762    builder.setColumnFamily(familyABuilder.build());
763    builder.setColumnFamily(familyBBuilder.build());
764    builder.setColumnFamily(familyCBuilder.build());
765    TableDescriptor tableDescriptor = builder.build();
766    admin.createTable(tableDescriptor);
767    try (Table table = TEST_UTIL.getConnection().getTable(TableName.valueOf(tableName))) {
768      Put put = new Put(ROW_1);
769      put.addColumn(FAMILYA, QUALIFIER_1, TS_2, VALUE_1);
770      table.put(put);
771      put = new Put(ROW_2);
772      put.addColumn(FAMILYA, QUALIFIER_1, TS_1, VALUE_1);
773      put.addColumn(FAMILYA, QUALIFIER_1, TS_2, VALUE_2);
774      put.addColumn(FAMILYB, QUALIFIER_2, TS_2, VALUE_2);
775      table.put(put);
776
777    }
778    return tableDescriptor;
779
780  }
781
782  private void testThriftAdmin(Connection connection, String namespace, String table)
783      throws Exception {
784    try (Admin admin = connection.getAdmin()){
785      //create name space
786      NamespaceDescriptor namespaceDescriptor = NamespaceDescriptor.create(namespace).build();
787      namespaceDescriptor.setConfiguration("key1", "value1");
788      namespaceDescriptor.setConfiguration("key2", "value2");
789      admin.createNamespace(namespaceDescriptor);
790      //list namespace
791      NamespaceDescriptor[] namespaceDescriptors = admin.listNamespaceDescriptors();
792      boolean found = false;
793      for (NamespaceDescriptor nd : namespaceDescriptors) {
794        if (nd.getName().equals(namespace)) {
795          found = true;
796          break;
797        }
798      }
799      assertTrue(found);
800      //modify namesapce
801      namespaceDescriptor.setConfiguration("kye3", "value3");
802      admin.modifyNamespace(namespaceDescriptor);
803      //get namespace
804      NamespaceDescriptor namespaceDescriptorReturned = admin.getNamespaceDescriptor(namespace);
805      assertTrue(namespaceDescriptorReturned.getConfiguration().size() == 3);
806      //create table
807      TableDescriptor tableDescriptor = createTable(admin, table);
808      //modify table
809      TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(tableDescriptor);
810      builder.setDurability(Durability.ASYNC_WAL);
811      admin.modifyTable(builder.build());
812      //modify column family
813      ColumnFamilyDescriptor familyA = tableDescriptor.getColumnFamily(FAMILYA);
814      ColumnFamilyDescriptorBuilder familyABuilder = ColumnFamilyDescriptorBuilder
815          .newBuilder(familyA);
816      familyABuilder.setInMemory(true);
817      admin.modifyColumnFamily(tableDescriptor.getTableName(), familyABuilder.build());
818      //add column family
819      ColumnFamilyDescriptorBuilder familyDBuilder = ColumnFamilyDescriptorBuilder
820          .newBuilder(FAMILYD);
821      familyDBuilder.setDataBlockEncoding(DataBlockEncoding.PREFIX);
822      admin.addColumnFamily(tableDescriptor.getTableName(), familyDBuilder.build());
823      //get table descriptor
824      TableDescriptor tableDescriptorReturned = admin.getDescriptor(tableDescriptor.getTableName());
825      assertTrue(tableDescriptorReturned.getColumnFamilies().length == 4);
826      assertTrue(tableDescriptorReturned.getDurability() ==  Durability.ASYNC_WAL);
827      ColumnFamilyDescriptor columnFamilyADescriptor1Returned = tableDescriptorReturned
828          .getColumnFamily(FAMILYA);
829      assertTrue(columnFamilyADescriptor1Returned.isInMemory() == true);
830      //delete column family
831      admin.deleteColumnFamily(tableDescriptor.getTableName(), FAMILYA);
832      tableDescriptorReturned = admin.getDescriptor(tableDescriptor.getTableName());
833      assertTrue(tableDescriptorReturned.getColumnFamilies().length == 3);
834      //disable table
835      admin.disableTable(tableDescriptor.getTableName());
836      assertTrue(admin.isTableDisabled(tableDescriptor.getTableName()));
837      //enable table
838      admin.enableTable(tableDescriptor.getTableName());
839      assertTrue(admin.isTableEnabled(tableDescriptor.getTableName()));
840      assertTrue(admin.isTableAvailable(tableDescriptor.getTableName()));
841      //truncate table
842      admin.disableTable(tableDescriptor.getTableName());
843      admin.truncateTable(tableDescriptor.getTableName(), true);
844      assertTrue(admin.isTableAvailable(tableDescriptor.getTableName()));
845      //delete table
846      admin.disableTable(tableDescriptor.getTableName());
847      admin.deleteTable(tableDescriptor.getTableName());
848      assertFalse(admin.tableExists(tableDescriptor.getTableName()));
849      //delete namespace
850      admin.deleteNamespace(namespace);
851      namespaceDescriptors = admin.listNamespaceDescriptors();
852      // should have 2 namespace, default and hbase
853      found = false;
854      for (NamespaceDescriptor nd : namespaceDescriptors) {
855        if (nd.getName().equals(namespace)) {
856          found = true;
857          break;
858        }
859      }
860      assertTrue(found == false);
861    }
862  }
863}