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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 package org
.apache
.hadoop
.hbase
.thrift2
;
20 import static java
.nio
.ByteBuffer
.wrap
;
21 import static org
.apache
.hadoop
.hbase
.HConstants
.DEFAULT_HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD
;
22 import static org
.apache
.hadoop
.hbase
.HConstants
.HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD
;
23 import static org
.apache
.hadoop
.hbase
.thrift
.HBaseServiceHandler
.CLEANUP_INTERVAL
;
24 import static org
.apache
.hadoop
.hbase
.thrift
.HBaseServiceHandler
.MAX_IDLETIME
;
25 import static org
.apache
.hadoop
.hbase
.thrift2
.ThriftUtilities
.deleteFromThrift
;
26 import static org
.apache
.hadoop
.hbase
.thrift2
.ThriftUtilities
.getFromThrift
;
27 import static org
.apache
.hadoop
.hbase
.thrift2
.ThriftUtilities
.incrementFromThrift
;
28 import static org
.apache
.hadoop
.hbase
.thrift2
.ThriftUtilities
.putFromThrift
;
29 import static org
.apache
.hadoop
.hbase
.thrift2
.ThriftUtilities
.scanFromThrift
;
30 import static org
.junit
.Assert
.assertArrayEquals
;
31 import static org
.junit
.Assert
.assertEquals
;
32 import static org
.junit
.Assert
.assertFalse
;
33 import static org
.junit
.Assert
.assertNull
;
34 import static org
.junit
.Assert
.assertTrue
;
35 import static org
.junit
.Assert
.fail
;
37 import java
.io
.IOException
;
38 import java
.io
.InterruptedIOException
;
39 import java
.net
.InetAddress
;
40 import java
.nio
.ByteBuffer
;
41 import java
.util
.ArrayList
;
42 import java
.util
.Arrays
;
43 import java
.util
.Collection
;
44 import java
.util
.Collections
;
45 import java
.util
.Comparator
;
46 import java
.util
.HashMap
;
47 import java
.util
.HashSet
;
48 import java
.util
.List
;
50 import java
.util
.Optional
;
52 import java
.util
.concurrent
.TimeUnit
;
53 import org
.apache
.hadoop
.conf
.Configuration
;
54 import org
.apache
.hadoop
.hbase
.Cell
;
55 import org
.apache
.hadoop
.hbase
.CompatibilityFactory
;
56 import org
.apache
.hadoop
.hbase
.CoprocessorEnvironment
;
57 import org
.apache
.hadoop
.hbase
.HBaseClassTestRule
;
58 import org
.apache
.hadoop
.hbase
.HBaseTestingUtil
;
59 import org
.apache
.hadoop
.hbase
.ServerName
;
60 import org
.apache
.hadoop
.hbase
.TableName
;
61 import org
.apache
.hadoop
.hbase
.client
.Admin
;
62 import org
.apache
.hadoop
.hbase
.client
.ColumnFamilyDescriptor
;
63 import org
.apache
.hadoop
.hbase
.client
.ColumnFamilyDescriptorBuilder
;
64 import org
.apache
.hadoop
.hbase
.client
.Consistency
;
65 import org
.apache
.hadoop
.hbase
.client
.Delete
;
66 import org
.apache
.hadoop
.hbase
.client
.Durability
;
67 import org
.apache
.hadoop
.hbase
.client
.Get
;
68 import org
.apache
.hadoop
.hbase
.client
.Increment
;
69 import org
.apache
.hadoop
.hbase
.client
.LogQueryFilter
;
70 import org
.apache
.hadoop
.hbase
.client
.Put
;
71 import org
.apache
.hadoop
.hbase
.client
.Scan
;
72 import org
.apache
.hadoop
.hbase
.client
.Table
;
73 import org
.apache
.hadoop
.hbase
.client
.TableDescriptor
;
74 import org
.apache
.hadoop
.hbase
.client
.TableDescriptorBuilder
;
75 import org
.apache
.hadoop
.hbase
.coprocessor
.ObserverContext
;
76 import org
.apache
.hadoop
.hbase
.coprocessor
.RegionCoprocessor
;
77 import org
.apache
.hadoop
.hbase
.coprocessor
.RegionCoprocessorEnvironment
;
78 import org
.apache
.hadoop
.hbase
.coprocessor
.RegionObserver
;
79 import org
.apache
.hadoop
.hbase
.filter
.ParseFilter
;
80 import org
.apache
.hadoop
.hbase
.security
.UserProvider
;
81 import org
.apache
.hadoop
.hbase
.security
.access
.AccessControlClient
;
82 import org
.apache
.hadoop
.hbase
.security
.access
.Permission
;
83 import org
.apache
.hadoop
.hbase
.security
.access
.UserPermission
;
84 import org
.apache
.hadoop
.hbase
.test
.MetricsAssertHelper
;
85 import org
.apache
.hadoop
.hbase
.testclassification
.ClientTests
;
86 import org
.apache
.hadoop
.hbase
.testclassification
.MediumTests
;
87 import org
.apache
.hadoop
.hbase
.thrift
.ErrorThrowingGetObserver
;
88 import org
.apache
.hadoop
.hbase
.thrift
.HBaseThriftTestingUtility
;
89 import org
.apache
.hadoop
.hbase
.thrift
.HbaseHandlerMetricsProxy
;
90 import org
.apache
.hadoop
.hbase
.thrift
.ThriftMetrics
;
91 import org
.apache
.hadoop
.hbase
.thrift
.ThriftMetrics
.ThriftServerType
;
92 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TAccessControlEntity
;
93 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TAppend
;
94 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TColumn
;
95 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TColumnFamilyDescriptor
;
96 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TColumnIncrement
;
97 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TColumnValue
;
98 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TCompareOperator
;
99 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TConsistency
;
100 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TDataBlockEncoding
;
101 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TDelete
;
102 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TDeleteType
;
103 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TDurability
;
104 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TFilterByOperator
;
105 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TGet
;
106 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.THBaseService
;
107 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TIOError
;
108 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TIllegalArgument
;
109 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TIncrement
;
110 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TLogQueryFilter
;
111 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TMutation
;
112 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TNamespaceDescriptor
;
113 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TOnlineLogRecord
;
114 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TPermissionScope
;
115 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TPut
;
116 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TReadType
;
117 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TResult
;
118 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TRowMutations
;
119 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TScan
;
120 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TServerName
;
121 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TTableDescriptor
;
122 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TTableName
;
123 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TThriftServerType
;
124 import org
.apache
.hadoop
.hbase
.thrift2
.generated
.TTimeRange
;
125 import org
.apache
.hadoop
.hbase
.util
.Bytes
;
126 import org
.apache
.hadoop
.hbase
.util
.EnvironmentEdgeManager
;
127 import org
.apache
.thrift
.TException
;
128 import org
.apache
.thrift
.protocol
.TBinaryProtocol
;
129 import org
.apache
.thrift
.protocol
.TProtocol
;
130 import org
.apache
.thrift
.transport
.TSocket
;
131 import org
.apache
.thrift
.transport
.TTransport
;
132 import org
.junit
.AfterClass
;
133 import org
.junit
.Assert
;
134 import org
.junit
.Before
;
135 import org
.junit
.BeforeClass
;
136 import org
.junit
.ClassRule
;
137 import org
.junit
.Rule
;
138 import org
.junit
.Test
;
139 import org
.junit
.experimental
.categories
.Category
;
140 import org
.junit
.rules
.TestName
;
141 import org
.slf4j
.Logger
;
142 import org
.slf4j
.LoggerFactory
;
144 import org
.apache
.hbase
.thirdparty
.com
.google
.common
.collect
.Lists
;
145 import org
.apache
.hbase
.thirdparty
.org
.apache
.commons
.collections4
.CollectionUtils
;
148 * Unit testing for ThriftServer.HBaseServiceHandler, a part of the org.apache.hadoop.hbase.thrift2
151 @Category({ClientTests
.class, MediumTests
.class})
152 public class TestThriftHBaseServiceHandler
{
155 public static final HBaseClassTestRule CLASS_RULE
=
156 HBaseClassTestRule
.forClass(TestThriftHBaseServiceHandler
.class);
158 private static final Logger LOG
= LoggerFactory
.getLogger(TestThriftHBaseServiceHandler
.class);
159 private static final HBaseTestingUtil UTIL
= new HBaseTestingUtil();
161 // Static names for tables, columns, rows, and values
162 private static byte[] tableAname
= Bytes
.toBytes("tableA");
163 private static byte[] familyAname
= Bytes
.toBytes("familyA");
164 private static byte[] familyBname
= Bytes
.toBytes("familyB");
165 private static byte[] qualifierAname
= Bytes
.toBytes("qualifierA");
166 private static byte[] qualifierBname
= Bytes
.toBytes("qualifierB");
167 private static byte[] valueAname
= Bytes
.toBytes("valueA");
168 private static byte[] valueBname
= Bytes
.toBytes("valueB");
169 private static ColumnFamilyDescriptor
[] families
= new ColumnFamilyDescriptor
[] {
170 ColumnFamilyDescriptorBuilder
.newBuilder(familyAname
).setMaxVersions(3).build(),
171 ColumnFamilyDescriptorBuilder
.newBuilder(familyBname
).setMaxVersions(2).build() };
174 private static final MetricsAssertHelper metricsHelper
=
175 CompatibilityFactory
.getInstance(MetricsAssertHelper
.class);
178 public TestName name
= new TestName();
181 public void assertTColumnValuesEqual(List
<TColumnValue
> columnValuesA
,
182 List
<TColumnValue
> columnValuesB
) {
183 assertEquals(columnValuesA
.size(), columnValuesB
.size());
184 Comparator
<TColumnValue
> comparator
= new Comparator
<TColumnValue
>() {
186 public int compare(TColumnValue o1
, TColumnValue o2
) {
187 return Bytes
.compareTo(Bytes
.add(o1
.getFamily(), o1
.getQualifier()),
188 Bytes
.add(o2
.getFamily(), o2
.getQualifier()));
191 Collections
.sort(columnValuesA
, comparator
);
192 Collections
.sort(columnValuesB
, comparator
);
194 for (int i
= 0; i
< columnValuesA
.size(); i
++) {
195 TColumnValue a
= columnValuesA
.get(i
);
196 TColumnValue b
= columnValuesB
.get(i
);
197 assertTColumnValueEqual(a
, b
);
201 public void assertTColumnValueEqual(TColumnValue a
, TColumnValue b
) {
202 assertArrayEquals(a
.getFamily(), b
.getFamily());
203 assertArrayEquals(a
.getQualifier(), b
.getQualifier());
204 assertArrayEquals(a
.getValue(), b
.getValue());
208 public static void beforeClass() throws Exception
{
209 UTIL
.getConfiguration().set("hbase.client.retries.number", "3");
210 UTIL
.getConfiguration().setBoolean("hbase.regionserver.slowlog.buffer.enabled", true);
212 UTIL
.getConfiguration().set("hbase.client.retries.number", "3");
213 UTIL
.getConfiguration().setBoolean("hbase.security.authorization", true);
214 UTIL
.getConfiguration().set("hbase.coprocessor.master.classes",
215 "org.apache.hadoop.hbase.security.access.AccessController");
216 UTIL
.getConfiguration().set("hbase.coprocessor.region.classes",
217 "org.apache.hadoop.hbase.security.access.AccessController");
218 UTIL
.getConfiguration().set("hbase.coprocessor.regionserver.classes",
219 "org.apache.hadoop.hbase.security.access.AccessController");
221 // as we opened access control, we need to start as a superuser. Otherwise, we will not have
222 // sufficient permission to do operations.
223 UTIL
.getConfiguration().set("hbase.superuser", System
.getProperty("user.name"));
225 UTIL
.startMiniCluster();
226 TableDescriptor tableDescriptor
= TableDescriptorBuilder
227 .newBuilder(TableName
.valueOf(tableAname
)).setColumnFamilies(Arrays
.asList(families
)).build();
228 try (Admin admin
= UTIL
.getAdmin()) {
229 admin
.createTable(tableDescriptor
);
234 public static void afterClass() throws Exception
{
235 UTIL
.shutdownMiniCluster();
239 public void setup() throws Exception
{
243 private ThriftHBaseServiceHandler
createHandler() throws TException
{
245 Configuration conf
= UTIL
.getConfiguration();
246 return new ThriftHBaseServiceHandler(conf
, UserProvider
.instantiate(conf
));
247 } catch (IOException ie
) {
248 throw new TException(ie
);
253 public void testExists() throws TIOError
, TException
{
254 ThriftHBaseServiceHandler handler
= createHandler();
255 byte[] rowName
= Bytes
.toBytes("testExists");
256 ByteBuffer table
= wrap(tableAname
);
258 TGet get
= new TGet(wrap(rowName
));
259 assertFalse(handler
.exists(table
, get
));
261 List
<TColumnValue
> columnValues
= new ArrayList
<>(2);
262 columnValues
.add(new TColumnValue(wrap(familyAname
), wrap(qualifierAname
), wrap(valueAname
)));
263 columnValues
.add(new TColumnValue(wrap(familyBname
), wrap(qualifierBname
), wrap(valueBname
)));
264 TPut put
= new TPut(wrap(rowName
), columnValues
);
265 put
.setColumnValues(columnValues
);
267 handler
.put(table
, put
);
269 assertTrue(handler
.exists(table
, get
));
273 public void testExistsAll() throws TIOError
, TException
{
274 ThriftHBaseServiceHandler handler
= createHandler();
275 byte[] rowName1
= Bytes
.toBytes("testExistsAll1");
276 byte[] rowName2
= Bytes
.toBytes("testExistsAll2");
277 ByteBuffer table
= wrap(tableAname
);
279 List
<TGet
> gets
= new ArrayList
<>();
280 gets
.add(new TGet(wrap(rowName2
)));
281 gets
.add(new TGet(wrap(rowName2
)));
282 List
<Boolean
> existsResult1
= handler
.existsAll(table
, gets
);
283 assertFalse(existsResult1
.get(0));
284 assertFalse(existsResult1
.get(1));
286 List
<TColumnValue
> columnValues
= new ArrayList
<TColumnValue
>();
287 columnValues
.add(new TColumnValue(wrap(familyAname
), wrap(qualifierAname
), wrap(valueAname
)));
288 columnValues
.add(new TColumnValue(wrap(familyBname
), wrap(qualifierBname
), wrap(valueBname
)));
289 List
<TPut
> puts
= new ArrayList
<TPut
>();
290 puts
.add(new TPut(wrap(rowName1
), columnValues
));
291 puts
.add(new TPut(wrap(rowName2
), columnValues
));
293 handler
.putMultiple(table
, puts
);
294 List
<Boolean
> existsResult2
= handler
.existsAll(table
, gets
);
296 assertTrue(existsResult2
.get(0));
297 assertTrue(existsResult2
.get(1));
301 public void testPutGet() throws Exception
{
302 ThriftHBaseServiceHandler handler
= createHandler();
303 byte[] rowName
= Bytes
.toBytes("testPutGet");
304 ByteBuffer table
= wrap(tableAname
);
306 List
<TColumnValue
> columnValues
= new ArrayList
<>(2);
307 columnValues
.add(new TColumnValue(wrap(familyAname
), wrap(qualifierAname
), wrap(valueAname
)));
308 columnValues
.add(new TColumnValue(wrap(familyBname
), wrap(qualifierBname
), wrap(valueBname
)));
309 TPut put
= new TPut(wrap(rowName
), columnValues
);
311 put
.setColumnValues(columnValues
);
313 handler
.put(table
, put
);
315 TGet get
= new TGet(wrap(rowName
));
317 TResult result
= handler
.get(table
, get
);
318 assertArrayEquals(rowName
, result
.getRow());
319 List
<TColumnValue
> returnedColumnValues
= result
.getColumnValues();
320 assertTColumnValuesEqual(columnValues
, returnedColumnValues
);
324 public void testPutGetMultiple() throws Exception
{
325 ThriftHBaseServiceHandler handler
= createHandler();
326 ByteBuffer table
= wrap(tableAname
);
327 byte[] rowName1
= Bytes
.toBytes("testPutGetMultiple1");
328 byte[] rowName2
= Bytes
.toBytes("testPutGetMultiple2");
330 List
<TColumnValue
> columnValues
= new ArrayList
<>(2);
331 columnValues
.add(new TColumnValue(wrap(familyAname
), wrap(qualifierAname
), wrap(valueAname
)));
332 columnValues
.add(new TColumnValue(wrap(familyBname
), wrap(qualifierBname
), wrap(valueBname
)));
333 List
<TPut
> puts
= new ArrayList
<>(2);
334 puts
.add(new TPut(wrap(rowName1
), columnValues
));
335 puts
.add(new TPut(wrap(rowName2
), columnValues
));
337 handler
.putMultiple(table
, puts
);
339 List
<TGet
> gets
= new ArrayList
<>(2);
340 gets
.add(new TGet(wrap(rowName1
)));
341 gets
.add(new TGet(wrap(rowName2
)));
343 List
<TResult
> results
= handler
.getMultiple(table
, gets
);
344 assertEquals(2, results
.size());
346 assertArrayEquals(rowName1
, results
.get(0).getRow());
347 assertTColumnValuesEqual(columnValues
, results
.get(0).getColumnValues());
349 assertArrayEquals(rowName2
, results
.get(1).getRow());
350 assertTColumnValuesEqual(columnValues
, results
.get(1).getColumnValues());
354 public void testDeleteMultiple() throws Exception
{
355 ThriftHBaseServiceHandler handler
= createHandler();
356 ByteBuffer table
= wrap(tableAname
);
357 byte[] rowName1
= Bytes
.toBytes("testDeleteMultiple1");
358 byte[] rowName2
= Bytes
.toBytes("testDeleteMultiple2");
360 List
<TColumnValue
> columnValues
= new ArrayList
<>(2);
361 columnValues
.add(new TColumnValue(wrap(familyAname
), wrap(qualifierAname
), wrap(valueAname
)));
362 columnValues
.add(new TColumnValue(wrap(familyBname
), wrap(qualifierBname
), wrap(valueBname
)));
363 List
<TPut
> puts
= new ArrayList
<>(2);
364 puts
.add(new TPut(wrap(rowName1
), columnValues
));
365 puts
.add(new TPut(wrap(rowName2
), columnValues
));
367 handler
.putMultiple(table
, puts
);
369 List
<TDelete
> deletes
= new ArrayList
<>(2);
370 deletes
.add(new TDelete(wrap(rowName1
)));
371 deletes
.add(new TDelete(wrap(rowName2
)));
373 List
<TDelete
> deleteResults
= handler
.deleteMultiple(table
, deletes
);
374 // 0 means they were all successfully applies
375 assertEquals(0, deleteResults
.size());
377 assertFalse(handler
.exists(table
, new TGet(wrap(rowName1
))));
378 assertFalse(handler
.exists(table
, new TGet(wrap(rowName2
))));
382 public void testDelete() throws Exception
{
383 ThriftHBaseServiceHandler handler
= createHandler();
384 byte[] rowName
= Bytes
.toBytes("testDelete");
385 ByteBuffer table
= wrap(tableAname
);
387 List
<TColumnValue
> columnValues
= new ArrayList
<>(2);
388 TColumnValue columnValueA
= new TColumnValue(wrap(familyAname
), wrap(qualifierAname
),
390 TColumnValue columnValueB
= new TColumnValue(wrap(familyBname
), wrap(qualifierBname
),
392 columnValues
.add(columnValueA
);
393 columnValues
.add(columnValueB
);
394 TPut put
= new TPut(wrap(rowName
), columnValues
);
396 put
.setColumnValues(columnValues
);
398 handler
.put(table
, put
);
400 TDelete delete
= new TDelete(wrap(rowName
));
401 List
<TColumn
> deleteColumns
= new ArrayList
<>(1);
402 TColumn deleteColumn
= new TColumn(wrap(familyAname
));
403 deleteColumn
.setQualifier(qualifierAname
);
404 deleteColumns
.add(deleteColumn
);
405 delete
.setColumns(deleteColumns
);
407 handler
.deleteSingle(table
, delete
);
409 TGet get
= new TGet(wrap(rowName
));
410 TResult result
= handler
.get(table
, get
);
411 assertArrayEquals(rowName
, result
.getRow());
412 List
<TColumnValue
> returnedColumnValues
= result
.getColumnValues();
413 List
<TColumnValue
> expectedColumnValues
= new ArrayList
<>(1);
414 expectedColumnValues
.add(columnValueB
);
415 assertTColumnValuesEqual(expectedColumnValues
, returnedColumnValues
);
419 public void testDeleteAllTimestamps() throws Exception
{
420 ThriftHBaseServiceHandler handler
= createHandler();
421 byte[] rowName
= Bytes
.toBytes("testDeleteAllTimestamps");
422 ByteBuffer table
= wrap(tableAname
);
424 List
<TColumnValue
> columnValues
= new ArrayList
<>(1);
425 TColumnValue columnValueA
= new TColumnValue(wrap(familyAname
), wrap(qualifierAname
),
427 columnValueA
.setTimestamp(EnvironmentEdgeManager
.currentTime() - 10);
428 columnValues
.add(columnValueA
);
429 TPut put
= new TPut(wrap(rowName
), columnValues
);
431 put
.setColumnValues(columnValues
);
433 handler
.put(table
, put
);
434 columnValueA
.setTimestamp(EnvironmentEdgeManager
.currentTime());
435 handler
.put(table
, put
);
437 TGet get
= new TGet(wrap(rowName
));
438 get
.setMaxVersions(2);
439 TResult result
= handler
.get(table
, get
);
440 assertEquals(2, result
.getColumnValuesSize());
442 TDelete delete
= new TDelete(wrap(rowName
));
443 List
<TColumn
> deleteColumns
= new ArrayList
<>(1);
444 TColumn deleteColumn
= new TColumn(wrap(familyAname
));
445 deleteColumn
.setQualifier(qualifierAname
);
446 deleteColumns
.add(deleteColumn
);
447 delete
.setColumns(deleteColumns
);
448 delete
.setDeleteType(TDeleteType
.DELETE_COLUMNS
); // This is the default anyway.
450 handler
.deleteSingle(table
, delete
);
452 get
= new TGet(wrap(rowName
));
453 result
= handler
.get(table
, get
);
454 assertNull(result
.getRow());
455 assertEquals(0, result
.getColumnValuesSize());
459 public void testDeleteSingleTimestamp() throws Exception
{
460 ThriftHBaseServiceHandler handler
= createHandler();
461 byte[] rowName
= Bytes
.toBytes("testDeleteSingleTimestamp");
462 ByteBuffer table
= wrap(tableAname
);
464 long timestamp1
= EnvironmentEdgeManager
.currentTime() - 10;
465 long timestamp2
= EnvironmentEdgeManager
.currentTime();
467 List
<TColumnValue
> columnValues
= new ArrayList
<>(1);
468 TColumnValue columnValueA
= new TColumnValue(wrap(familyAname
), wrap(qualifierAname
),
470 columnValueA
.setTimestamp(timestamp1
);
471 columnValues
.add(columnValueA
);
472 TPut put
= new TPut(wrap(rowName
), columnValues
);
474 put
.setColumnValues(columnValues
);
476 handler
.put(table
, put
);
477 columnValueA
.setTimestamp(timestamp2
);
478 handler
.put(table
, put
);
480 TGet get
= new TGet(wrap(rowName
));
481 get
.setMaxVersions(2);
482 TResult result
= handler
.get(table
, get
);
483 assertEquals(2, result
.getColumnValuesSize());
485 TDelete delete
= new TDelete(wrap(rowName
));
486 List
<TColumn
> deleteColumns
= new ArrayList
<>(1);
487 TColumn deleteColumn
= new TColumn(wrap(familyAname
));
488 deleteColumn
.setQualifier(qualifierAname
);
489 deleteColumns
.add(deleteColumn
);
490 delete
.setColumns(deleteColumns
);
491 delete
.setDeleteType(TDeleteType
.DELETE_COLUMN
);
493 handler
.deleteSingle(table
, delete
);
495 get
= new TGet(wrap(rowName
));
496 result
= handler
.get(table
, get
);
497 assertArrayEquals(rowName
, result
.getRow());
498 assertEquals(1, result
.getColumnValuesSize());
499 // the older timestamp should remain.
500 assertEquals(timestamp1
, result
.getColumnValues().get(0).getTimestamp());
504 public void testDeleteFamily() throws Exception
{
505 ThriftHBaseServiceHandler handler
= createHandler();
506 byte[] rowName
= Bytes
.toBytes("testDeleteFamily");
507 ByteBuffer table
= wrap(tableAname
);
509 long timestamp1
= EnvironmentEdgeManager
.currentTime() - 10;
510 long timestamp2
= EnvironmentEdgeManager
.currentTime();
512 List
<TColumnValue
> columnValues
= new ArrayList
<>();
513 TColumnValue columnValueA
=
514 new TColumnValue(wrap(familyAname
), wrap(qualifierAname
), wrap(valueAname
));
515 columnValueA
.setTimestamp(timestamp1
);
516 columnValues
.add(columnValueA
);
517 TPut put
= new TPut(wrap(rowName
), columnValues
);
519 put
.setColumnValues(columnValues
);
521 handler
.put(table
, put
);
522 columnValueA
.setTimestamp(timestamp2
);
523 handler
.put(table
, put
);
525 TGet get
= new TGet(wrap(rowName
));
526 get
.setMaxVersions(2);
527 TResult result
= handler
.get(table
, get
);
528 assertEquals(2, result
.getColumnValuesSize());
530 TDelete delete
= new TDelete(wrap(rowName
));
531 List
<TColumn
> deleteColumns
= new ArrayList
<>();
532 TColumn deleteColumn
= new TColumn(wrap(familyAname
));
533 deleteColumns
.add(deleteColumn
);
534 delete
.setColumns(deleteColumns
);
535 delete
.setDeleteType(TDeleteType
.DELETE_FAMILY
);
537 handler
.deleteSingle(table
, delete
);
539 get
= new TGet(wrap(rowName
));
540 result
= handler
.get(table
, get
);
541 assertArrayEquals(null, result
.getRow());
542 assertEquals(0, result
.getColumnValuesSize());
546 public void testDeleteFamilyVersion() throws Exception
{
547 ThriftHBaseServiceHandler handler
= createHandler();
548 byte[] rowName
= Bytes
.toBytes("testDeleteFamilyVersion");
549 ByteBuffer table
= wrap(tableAname
);
551 long timestamp1
= EnvironmentEdgeManager
.currentTime() - 10;
552 long timestamp2
= EnvironmentEdgeManager
.currentTime();
554 List
<TColumnValue
> columnValues
= new ArrayList
<>();
555 TColumnValue columnValueA
=
556 new TColumnValue(wrap(familyAname
), wrap(qualifierAname
), wrap(valueAname
));
557 columnValueA
.setTimestamp(timestamp1
);
558 columnValues
.add(columnValueA
);
559 TPut put
= new TPut(wrap(rowName
), columnValues
);
561 put
.setColumnValues(columnValues
);
563 handler
.put(table
, put
);
564 columnValueA
.setTimestamp(timestamp2
);
565 handler
.put(table
, put
);
567 TGet get
= new TGet(wrap(rowName
));
568 get
.setMaxVersions(2);
569 TResult result
= handler
.get(table
, get
);
570 assertEquals(2, result
.getColumnValuesSize());
572 TDelete delete
= new TDelete(wrap(rowName
));
573 List
<TColumn
> deleteColumns
= new ArrayList
<>();
574 TColumn deleteColumn
= new TColumn(wrap(familyAname
));
575 deleteColumn
.setTimestamp(timestamp1
);
576 deleteColumns
.add(deleteColumn
);
577 delete
.setColumns(deleteColumns
);
578 delete
.setDeleteType(TDeleteType
.DELETE_FAMILY_VERSION
);
580 handler
.deleteSingle(table
, delete
);
582 get
= new TGet(wrap(rowName
));
583 result
= handler
.get(table
, get
);
584 assertArrayEquals(rowName
, result
.getRow());
585 assertEquals(1, result
.getColumnValuesSize());
586 assertEquals(timestamp2
, result
.getColumnValues().get(0).getTimestamp());
590 public void testIncrement() throws Exception
{
591 ThriftHBaseServiceHandler handler
= createHandler();
592 byte[] rowName
= Bytes
.toBytes("testIncrement");
593 ByteBuffer table
= wrap(tableAname
);
595 List
<TColumnValue
> columnValues
= new ArrayList
<>(1);
596 columnValues
.add(new TColumnValue(wrap(familyAname
), wrap(qualifierAname
),
597 wrap(Bytes
.toBytes(1L))));
598 TPut put
= new TPut(wrap(rowName
), columnValues
);
599 put
.setColumnValues(columnValues
);
600 handler
.put(table
, put
);
602 List
<TColumnIncrement
> incrementColumns
= new ArrayList
<>(1);
603 incrementColumns
.add(new TColumnIncrement(wrap(familyAname
), wrap(qualifierAname
)));
604 TIncrement increment
= new TIncrement(wrap(rowName
), incrementColumns
);
605 handler
.increment(table
, increment
);
607 TGet get
= new TGet(wrap(rowName
));
608 TResult result
= handler
.get(table
, get
);
610 assertArrayEquals(rowName
, result
.getRow());
611 assertEquals(1, result
.getColumnValuesSize());
612 TColumnValue columnValue
= result
.getColumnValues().get(0);
613 assertArrayEquals(Bytes
.toBytes(2L), columnValue
.getValue());
617 public void testAppend() throws Exception
{
618 ThriftHBaseServiceHandler handler
= createHandler();
619 byte[] rowName
= Bytes
.toBytes("testAppend");
620 ByteBuffer table
= wrap(tableAname
);
621 byte[] v1
= Bytes
.toBytes("42");
622 byte[] v2
= Bytes
.toBytes("23");
623 List
<TColumnValue
> columnValues
= new ArrayList
<>(1);
624 columnValues
.add(new TColumnValue(wrap(familyAname
), wrap(qualifierAname
), wrap(v1
)));
625 TPut put
= new TPut(wrap(rowName
), columnValues
);
626 put
.setColumnValues(columnValues
);
627 handler
.put(table
, put
);
629 List
<TColumnValue
> appendColumns
= new ArrayList
<>(1);
630 appendColumns
.add(new TColumnValue(wrap(familyAname
), wrap(qualifierAname
), wrap(v2
)));
631 TAppend append
= new TAppend(wrap(rowName
), appendColumns
);
632 handler
.append(table
, append
);
634 TGet get
= new TGet(wrap(rowName
));
635 TResult result
= handler
.get(table
, get
);
637 assertArrayEquals(rowName
, result
.getRow());
638 assertEquals(1, result
.getColumnValuesSize());
639 TColumnValue columnValue
= result
.getColumnValues().get(0);
640 assertArrayEquals(Bytes
.add(v1
, v2
), columnValue
.getValue());
644 * check that checkAndPut fails if the cell does not exist, then put in the cell, then check
645 * that the checkAndPut succeeds.
648 public void testCheckAndPut() throws Exception
{
649 ThriftHBaseServiceHandler handler
= createHandler();
650 byte[] rowName
= Bytes
.toBytes("testCheckAndPut");
651 ByteBuffer table
= wrap(tableAname
);
653 List
<TColumnValue
> columnValuesA
= new ArrayList
<>(1);
654 TColumnValue columnValueA
= new TColumnValue(wrap(familyAname
), wrap(qualifierAname
),
656 columnValuesA
.add(columnValueA
);
657 TPut putA
= new TPut(wrap(rowName
), columnValuesA
);
658 putA
.setColumnValues(columnValuesA
);
660 List
<TColumnValue
> columnValuesB
= new ArrayList
<>(1);
661 TColumnValue columnValueB
= new TColumnValue(wrap(familyBname
), wrap(qualifierBname
),
663 columnValuesB
.add(columnValueB
);
664 TPut putB
= new TPut(wrap(rowName
), columnValuesB
);
665 putB
.setColumnValues(columnValuesB
);
667 assertFalse(handler
.checkAndPut(table
, wrap(rowName
), wrap(familyAname
),
668 wrap(qualifierAname
), wrap(valueAname
), putB
));
670 TGet get
= new TGet(wrap(rowName
));
671 TResult result
= handler
.get(table
, get
);
672 assertEquals(0, result
.getColumnValuesSize());
674 handler
.put(table
, putA
);
676 assertTrue(handler
.checkAndPut(table
, wrap(rowName
), wrap(familyAname
),
677 wrap(qualifierAname
), wrap(valueAname
), putB
));
679 result
= handler
.get(table
, get
);
680 assertArrayEquals(rowName
, result
.getRow());
681 List
<TColumnValue
> returnedColumnValues
= result
.getColumnValues();
682 List
<TColumnValue
> expectedColumnValues
= new ArrayList
<>(2);
683 expectedColumnValues
.add(columnValueA
);
684 expectedColumnValues
.add(columnValueB
);
685 assertTColumnValuesEqual(expectedColumnValues
, returnedColumnValues
);
689 * check that checkAndDelete fails if the cell does not exist, then put in the cell, then
690 * check that the checkAndDelete succeeds.
693 public void testCheckAndDelete() throws Exception
{
694 ThriftHBaseServiceHandler handler
= createHandler();
695 byte[] rowName
= Bytes
.toBytes("testCheckAndDelete");
696 ByteBuffer table
= wrap(tableAname
);
698 List
<TColumnValue
> columnValuesA
= new ArrayList
<>(1);
699 TColumnValue columnValueA
= new TColumnValue(wrap(familyAname
), wrap(qualifierAname
),
701 columnValuesA
.add(columnValueA
);
702 TPut putA
= new TPut(wrap(rowName
), columnValuesA
);
703 putA
.setColumnValues(columnValuesA
);
705 List
<TColumnValue
> columnValuesB
= new ArrayList
<>(1);
706 TColumnValue columnValueB
= new TColumnValue(wrap(familyBname
), wrap(qualifierBname
),
708 columnValuesB
.add(columnValueB
);
709 TPut putB
= new TPut(wrap(rowName
), columnValuesB
);
710 putB
.setColumnValues(columnValuesB
);
712 // put putB so that we know whether the row has been deleted or not
713 handler
.put(table
, putB
);
715 TDelete delete
= new TDelete(wrap(rowName
));
717 assertFalse(handler
.checkAndDelete(table
, wrap(rowName
), wrap(familyAname
),
718 wrap(qualifierAname
), wrap(valueAname
), delete
));
720 TGet get
= new TGet(wrap(rowName
));
721 TResult result
= handler
.get(table
, get
);
722 assertArrayEquals(rowName
, result
.getRow());
723 assertTColumnValuesEqual(columnValuesB
, result
.getColumnValues());
725 handler
.put(table
, putA
);
727 assertTrue(handler
.checkAndDelete(table
, wrap(rowName
), wrap(familyAname
),
728 wrap(qualifierAname
), wrap(valueAname
), delete
));
730 result
= handler
.get(table
, get
);
731 assertFalse(result
.isSetRow());
732 assertEquals(0, result
.getColumnValuesSize());
736 public void testScan() throws Exception
{
737 ThriftHBaseServiceHandler handler
= createHandler();
738 ByteBuffer table
= wrap(tableAname
);
741 TColumnValue columnValue
= new TColumnValue(wrap(familyAname
), wrap(qualifierAname
),
743 List
<TColumnValue
> columnValues
= new ArrayList
<>(1);
744 columnValues
.add(columnValue
);
745 for (int i
= 0; i
< 10; i
++) {
746 TPut put
= new TPut(wrap(Bytes
.toBytes("testScan" + i
)), columnValues
);
747 handler
.put(table
, put
);
750 // create scan instance
751 TScan scan
= new TScan();
752 List
<TColumn
> columns
= new ArrayList
<>(1);
753 TColumn column
= new TColumn();
754 column
.setFamily(familyAname
);
755 column
.setQualifier(qualifierAname
);
757 scan
.setColumns(columns
);
758 scan
.setStartRow(Bytes
.toBytes("testScan"));
759 scan
.setStopRow(Bytes
.toBytes("testScan\uffff"));
761 // get scanner and rows
762 int scanId
= handler
.openScanner(table
, scan
);
763 List
<TResult
> results
= handler
.getScannerRows(scanId
, 10);
764 assertEquals(10, results
.size());
765 for (int i
= 0; i
< 10; i
++) {
766 // check if the rows are returned and in order
767 assertArrayEquals(Bytes
.toBytes("testScan" + i
), results
.get(i
).getRow());
770 // check that we are at the end of the scan
771 results
= handler
.getScannerRows(scanId
, 10);
772 assertEquals(0, results
.size());
774 // close scanner and check that it was indeed closed
775 handler
.closeScanner(scanId
);
777 handler
.getScannerRows(scanId
, 10);
778 fail("Scanner id should be invalid");
779 } catch (TIllegalArgument e
) {
784 * Tests keeping a HBase scanner alive for long periods of time. Each call to getScannerRow()
785 * should reset the ConnectionCache timeout for the scanner's connection.
787 @org.junit
.Ignore
@Test // Flakey. Diasabled by HBASE-24079. Renable with Fails with HBASE-24083.
788 // Caused by: java.util.concurrent.RejectedExecutionException:
789 // Task org.apache.hadoop.hbase.client.ResultBoundedCompletionService$QueueingFuture@e385431
790 // rejected from java.util.concurrent.ThreadPoolExecutor@ 52b027d[Terminated, pool size = 0,
791 // active threads = 0, queued tasks = 0, completed tasks = 1]
792 // at org.apache.hadoop.hbase.thrift2.TestThriftHBaseServiceHandler.
793 // testLongLivedScan(TestThriftHBaseServiceHandler.java:804)
794 public void testLongLivedScan() throws Exception
{
796 int trialPause
= 1000;
797 int cleanUpInterval
= 100;
798 Configuration conf
= new Configuration(UTIL
.getConfiguration());
799 // Set the ConnectionCache timeout to trigger halfway through the trials
800 conf
.setInt(MAX_IDLETIME
, (numTrials
/ 2) * trialPause
);
801 conf
.setInt(CLEANUP_INTERVAL
, cleanUpInterval
);
802 ThriftHBaseServiceHandler handler
= new ThriftHBaseServiceHandler(conf
,
803 UserProvider
.instantiate(conf
));
805 ByteBuffer table
= wrap(tableAname
);
807 TColumnValue columnValue
= new TColumnValue(wrap(familyAname
), wrap(qualifierAname
),
809 List
<TColumnValue
> columnValues
= new ArrayList
<>(1);
810 columnValues
.add(columnValue
);
811 for (int i
= 0; i
< numTrials
; i
++) {
812 TPut put
= new TPut(wrap(Bytes
.toBytes("testScan" + i
)), columnValues
);
813 handler
.put(table
, put
);
816 // create scan instance
817 TScan scan
= new TScan();
818 List
<TColumn
> columns
= new ArrayList
<>(1);
819 TColumn column
= new TColumn();
820 column
.setFamily(familyAname
);
821 column
.setQualifier(qualifierAname
);
823 scan
.setColumns(columns
);
824 scan
.setStartRow(Bytes
.toBytes("testScan"));
825 scan
.setStopRow(Bytes
.toBytes("testScan\uffff"));
826 // Prevent the scanner from caching results
829 // get scanner and rows
830 int scanId
= handler
.openScanner(table
, scan
);
831 for (int i
= 0; i
< numTrials
; i
++) {
832 // Make sure that the Scanner doesn't throw an exception after the ConnectionCache timeout
833 List
<TResult
> results
= handler
.getScannerRows(scanId
, 1);
834 assertArrayEquals(Bytes
.toBytes("testScan" + i
), results
.get(0).getRow());
835 Thread
.sleep(trialPause
);
840 public void testReverseScan() throws Exception
{
841 ThriftHBaseServiceHandler handler
= createHandler();
842 ByteBuffer table
= wrap(tableAname
);
845 TColumnValue columnValue
= new TColumnValue(wrap(familyAname
), wrap(qualifierAname
),
847 List
<TColumnValue
> columnValues
= new ArrayList
<>(1);
848 columnValues
.add(columnValue
);
849 for (int i
= 0; i
< 10; i
++) {
850 TPut put
= new TPut(wrap(Bytes
.toBytes("testReverseScan" + i
)), columnValues
);
851 handler
.put(table
, put
);
854 // create reverse scan instance
855 TScan scan
= new TScan();
856 scan
.setReversed(true);
857 List
<TColumn
> columns
= new ArrayList
<>(1);
858 TColumn column
= new TColumn();
859 column
.setFamily(familyAname
);
860 column
.setQualifier(qualifierAname
);
862 scan
.setColumns(columns
);
863 scan
.setStartRow(Bytes
.toBytes("testReverseScan\uffff"));
864 scan
.setStopRow(Bytes
.toBytes("testReverseScan"));
866 // get scanner and rows
867 int scanId
= handler
.openScanner(table
, scan
);
868 List
<TResult
> results
= handler
.getScannerRows(scanId
, 10);
869 assertEquals(10, results
.size());
870 for (int i
= 0; i
< 10; i
++) {
871 // check if the rows are returned and in order
872 assertArrayEquals(Bytes
.toBytes("testReverseScan" + (9 - i
)), results
.get(i
).getRow());
875 // check that we are at the end of the scan
876 results
= handler
.getScannerRows(scanId
, 10);
877 assertEquals(0, results
.size());
879 // close scanner and check that it was indeed closed
880 handler
.closeScanner(scanId
);
882 handler
.getScannerRows(scanId
, 10);
883 fail("Scanner id should be invalid");
884 } catch (TIllegalArgument e
) {
889 public void testScanWithFilter() throws Exception
{
890 ThriftHBaseServiceHandler handler
= createHandler();
891 ByteBuffer table
= wrap(tableAname
);
894 TColumnValue columnValue
= new TColumnValue(wrap(familyAname
), wrap(qualifierAname
),
896 List
<TColumnValue
> columnValues
= new ArrayList
<>(1);
897 columnValues
.add(columnValue
);
898 for (int i
= 0; i
< 10; i
++) {
899 TPut put
= new TPut(wrap(Bytes
.toBytes("testScanWithFilter" + i
)), columnValues
);
900 handler
.put(table
, put
);
903 // create scan instance with filter
904 TScan scan
= new TScan();
905 List
<TColumn
> columns
= new ArrayList
<>(1);
906 TColumn column
= new TColumn();
907 column
.setFamily(familyAname
);
908 column
.setQualifier(qualifierAname
);
910 scan
.setColumns(columns
);
911 scan
.setStartRow(Bytes
.toBytes("testScanWithFilter"));
912 scan
.setStopRow(Bytes
.toBytes("testScanWithFilter\uffff"));
913 // only get the key part
914 scan
.setFilterString(wrap(Bytes
.toBytes("KeyOnlyFilter()")));
916 // get scanner and rows
917 int scanId
= handler
.openScanner(table
, scan
);
918 List
<TResult
> results
= handler
.getScannerRows(scanId
, 10);
919 assertEquals(10, results
.size());
920 for (int i
= 0; i
< 10; i
++) {
921 // check if the rows are returned and in order
922 assertArrayEquals(Bytes
.toBytes("testScanWithFilter" + i
), results
.get(i
).getRow());
923 // check that the value is indeed stripped by the filter
924 assertEquals(0, results
.get(i
).getColumnValues().get(0).getValue().length
);
927 // check that we are at the end of the scan
928 results
= handler
.getScannerRows(scanId
, 10);
929 assertEquals(0, results
.size());
931 // close scanner and check that it was indeed closed
932 handler
.closeScanner(scanId
);
934 handler
.getScannerRows(scanId
, 10);
935 fail("Scanner id should be invalid");
936 } catch (TIllegalArgument e
) {
941 public void testScanWithColumnFamilyTimeRange() throws Exception
{
942 ThriftHBaseServiceHandler handler
= createHandler();
943 ByteBuffer table
= wrap(tableAname
);
946 TColumnValue familyAColumnValue
= new TColumnValue(wrap(familyAname
), wrap(qualifierAname
),
948 TColumnValue familyBColumnValue
= new TColumnValue(wrap(familyBname
), wrap(qualifierBname
),
950 long minTimestamp
= EnvironmentEdgeManager
.currentTime();
951 for (int i
= 0; i
< 10; i
++) {
952 familyAColumnValue
.setTimestamp(minTimestamp
+ i
);
953 familyBColumnValue
.setTimestamp(minTimestamp
+ i
);
954 List
<TColumnValue
> columnValues
= new ArrayList
<>(2);
955 columnValues
.add(familyAColumnValue
);
956 columnValues
.add(familyBColumnValue
);
957 TPut put
= new TPut(wrap(Bytes
.toBytes("testScanWithColumnFamilyTimeRange" + i
)),
959 handler
.put(table
, put
);
962 // create scan instance with column family time range
963 TScan scan
= new TScan();
964 Map
<ByteBuffer
,TTimeRange
> colFamTimeRangeMap
= new HashMap
<>(2);
965 colFamTimeRangeMap
.put(wrap(familyAname
), new TTimeRange(minTimestamp
+ 3, minTimestamp
+ 5));
966 colFamTimeRangeMap
.put(wrap(familyBname
), new TTimeRange(minTimestamp
+ 6, minTimestamp
+ 9));
967 scan
.setColFamTimeRangeMap(colFamTimeRangeMap
);
969 // get scanner and rows
970 int scanId
= handler
.openScanner(table
, scan
);
971 List
<TResult
> results
= handler
.getScannerRows(scanId
, 5);
972 assertEquals(5, results
.size());
973 int familyACount
= 0;
974 int familyBCount
= 0;
975 for (TResult result
: results
) {
976 List
<TColumnValue
> columnValues
= result
.getColumnValues();
977 if (CollectionUtils
.isNotEmpty(columnValues
)) {
978 if (Bytes
.equals(familyAname
, columnValues
.get(0).getFamily())) {
980 } else if (Bytes
.equals(familyBname
, columnValues
.get(0).getFamily())) {
985 assertEquals(2, familyACount
);
986 assertEquals(3, familyBCount
);
988 // check that we are at the end of the scan
989 results
= handler
.getScannerRows(scanId
, 1);
990 assertEquals(0, results
.size());
992 // close scanner and check that it was indeed closed
993 handler
.closeScanner(scanId
);
995 handler
.getScannerRows(scanId
, 1);
996 fail("Scanner id should be invalid");
997 } catch (TIllegalArgument e
) {
1002 public void testSmallScan() throws Exception
{
1003 ThriftHBaseServiceHandler handler
= createHandler();
1004 ByteBuffer table
= wrap(tableAname
);
1007 TColumnValue columnValue
= new TColumnValue(wrap(familyAname
), wrap(qualifierAname
),
1009 List
<TColumnValue
> columnValues
= new ArrayList
<>();
1010 columnValues
.add(columnValue
);
1011 for (int i
= 0; i
< 10; i
++) {
1012 TPut put
= new TPut(wrap(Bytes
.toBytes("testSmallScan" + i
)), columnValues
);
1013 handler
.put(table
, put
);
1016 // small scan instance
1017 TScan scan
= new TScan();
1018 scan
.setStartRow(Bytes
.toBytes("testSmallScan"));
1019 scan
.setStopRow(Bytes
.toBytes("testSmallScan\uffff"));
1020 scan
.setReadType(TReadType
.PREAD
);
1023 // get scanner and rows
1024 int scanId
= handler
.openScanner(table
, scan
);
1025 List
<TResult
> results
= handler
.getScannerRows(scanId
, 10);
1026 assertEquals(10, results
.size());
1027 for (int i
= 0; i
< 10; i
++) {
1028 // check if the rows are returned and in order
1029 assertArrayEquals(Bytes
.toBytes("testSmallScan" + i
), results
.get(i
).getRow());
1032 // check that we are at the end of the scan
1033 results
= handler
.getScannerRows(scanId
, 10);
1034 assertEquals(0, results
.size());
1036 // close scanner and check that it was indeed closed
1037 handler
.closeScanner(scanId
);
1039 handler
.getScannerRows(scanId
, 10);
1040 fail("Scanner id should be invalid");
1041 } catch (TIllegalArgument e
) {
1046 public void testExpiredScanner() throws Exception
{
1047 Configuration conf
= UTIL
.getConfiguration();
1048 conf
.setLong(HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD
, 1000);
1049 ThriftHBaseServiceHandler handler
=
1050 new ThriftHBaseServiceHandler(conf
, UserProvider
.instantiate(conf
));
1052 TScan scan
= new TScan();
1053 ByteBuffer table
= wrap(tableAname
);
1055 int scannerId
= handler
.openScanner(table
, scan
);
1056 handler
.getScannerRows(scannerId
, 1);
1060 handler
.getScannerRows(scannerId
, 1);
1061 fail("The scanner should be expired and have an TIllegalArgument exception here.");
1062 } catch (TIllegalArgument e
) {
1063 assertEquals("Invalid scanner Id", e
.getMessage());
1065 conf
.setLong(HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD
,
1066 DEFAULT_HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD
);
1071 public void testPutTTL() throws Exception
{
1072 ThriftHBaseServiceHandler handler
= createHandler();
1073 byte[] rowName
= Bytes
.toBytes("testPutTTL");
1074 ByteBuffer table
= wrap(tableAname
);
1075 List
<TColumnValue
> columnValues
= new ArrayList
<>(1);
1077 // Add some dummy data
1081 wrap(qualifierAname
),
1082 wrap(Bytes
.toBytes(1L))));
1085 TPut put
= new TPut(wrap(rowName
), columnValues
);
1086 put
.setColumnValues(columnValues
);
1088 Map
<ByteBuffer
, ByteBuffer
> attributes
= new HashMap
<>();
1090 // Time in ms for the kv's to live.
1091 long ttlTimeMs
= 2000L;
1093 // the _ttl attribute is a number of ms ttl for key values in this put.
1094 attributes
.put(wrap(Bytes
.toBytes("_ttl")), wrap(Bytes
.toBytes(ttlTimeMs
)));
1095 // Attach the attributes
1096 put
.setAttributes(attributes
);
1098 handler
.put(table
, put
);
1100 // Now get the data back
1101 TGet getOne
= new TGet(wrap(rowName
));
1102 TResult resultOne
= handler
.get(table
, getOne
);
1105 assertArrayEquals(rowName
, resultOne
.getRow());
1106 assertEquals(1, resultOne
.getColumnValuesSize());
1108 // Sleep 30 seconds just to make 100% sure that the key value should be expired.
1109 Thread
.sleep(ttlTimeMs
* 15);
1111 TGet getTwo
= new TGet(wrap(rowName
));
1112 TResult resultTwo
= handler
.get(table
, getTwo
);
1115 // Nothing should be there since it's ttl'd out.
1116 assertNull(resultTwo
.getRow());
1117 assertEquals(0, resultTwo
.getColumnValuesSize());
1121 * Padding numbers to make comparison of sort order easier in a for loop
1123 * @param n The number to pad.
1124 * @param pad The length to pad up to.
1125 * @return The padded number as a string.
1127 private String
pad(int n
, byte pad
) {
1128 String res
= Integer
.toString(n
);
1129 while (res
.length() < pad
) {
1136 public void testScanWithBatchSize() throws Exception
{
1137 ThriftHBaseServiceHandler handler
= createHandler();
1138 ByteBuffer table
= wrap(tableAname
);
1141 List
<TColumnValue
> columnValues
= new ArrayList
<>(100);
1142 for (int i
= 0; i
< 100; i
++) {
1143 String colNum
= pad(i
, (byte) 3);
1144 TColumnValue columnValue
= new TColumnValue(wrap(familyAname
),
1145 wrap(Bytes
.toBytes("col" + colNum
)), wrap(Bytes
.toBytes("val" + colNum
)));
1146 columnValues
.add(columnValue
);
1148 TPut put
= new TPut(wrap(Bytes
.toBytes("testScanWithBatchSize")), columnValues
);
1149 handler
.put(table
, put
);
1151 // create scan instance
1152 TScan scan
= new TScan();
1153 List
<TColumn
> columns
= new ArrayList
<>(1);
1154 TColumn column
= new TColumn();
1155 column
.setFamily(familyAname
);
1156 columns
.add(column
);
1157 scan
.setColumns(columns
);
1158 scan
.setStartRow(Bytes
.toBytes("testScanWithBatchSize"));
1159 scan
.setStopRow(Bytes
.toBytes("testScanWithBatchSize\uffff"));
1160 // set batch size to 10 columns per call
1161 scan
.setBatchSize(10);
1164 int scanId
= handler
.openScanner(table
, scan
);
1165 List
<TResult
> results
= null;
1166 for (int i
= 0; i
< 10; i
++) {
1167 // get batch for single row (10x10 is what we expect)
1168 results
= handler
.getScannerRows(scanId
, 1);
1169 assertEquals(1, results
.size());
1170 // check length of batch
1171 List
<TColumnValue
> cols
= results
.get(0).getColumnValues();
1172 assertEquals(10, cols
.size());
1173 // check if the columns are returned and in order
1174 for (int y
= 0; y
< 10; y
++) {
1175 int colNum
= y
+ (10 * i
);
1176 String colNumPad
= pad(colNum
, (byte) 3);
1177 assertArrayEquals(Bytes
.toBytes("col" + colNumPad
), cols
.get(y
).getQualifier());
1181 // check that we are at the end of the scan
1182 results
= handler
.getScannerRows(scanId
, 1);
1183 assertEquals(0, results
.size());
1185 // close scanner and check that it was indeed closed
1186 handler
.closeScanner(scanId
);
1188 handler
.getScannerRows(scanId
, 1);
1189 fail("Scanner id should be invalid");
1190 } catch (TIllegalArgument e
) {
1195 public void testGetScannerResults() throws Exception
{
1196 ThriftHBaseServiceHandler handler
= createHandler();
1197 ByteBuffer table
= wrap(tableAname
);
1200 TColumnValue columnValue
=
1201 new TColumnValue(wrap(familyAname
), wrap(qualifierAname
), wrap(valueAname
));
1202 List
<TColumnValue
> columnValues
= new ArrayList
<>(1);
1203 columnValues
.add(columnValue
);
1204 for (int i
= 0; i
< 20; i
++) {
1206 new TPut(wrap(Bytes
.toBytes("testGetScannerResults" + pad(i
, (byte) 2))), columnValues
);
1207 handler
.put(table
, put
);
1210 // create scan instance
1211 TScan scan
= new TScan();
1212 List
<TColumn
> columns
= new ArrayList
<>(1);
1213 TColumn column
= new TColumn();
1214 column
.setFamily(familyAname
);
1215 column
.setQualifier(qualifierAname
);
1216 columns
.add(column
);
1217 scan
.setColumns(columns
);
1218 scan
.setStartRow(Bytes
.toBytes("testGetScannerResults"));
1220 // get 5 rows and check the returned results
1221 scan
.setStopRow(Bytes
.toBytes("testGetScannerResults05"));
1222 List
<TResult
> results
= handler
.getScannerResults(table
, scan
, 5);
1223 assertEquals(5, results
.size());
1224 for (int i
= 0; i
< 5; i
++) {
1225 // check if the rows are returned and in order
1226 assertArrayEquals(Bytes
.toBytes("testGetScannerResults" + pad(i
, (byte) 2)), results
.get(i
)
1230 // get 10 rows and check the returned results
1231 scan
.setStopRow(Bytes
.toBytes("testGetScannerResults10"));
1232 results
= handler
.getScannerResults(table
, scan
, 10);
1233 assertEquals(10, results
.size());
1234 for (int i
= 0; i
< 10; i
++) {
1235 // check if the rows are returned and in order
1236 assertArrayEquals(Bytes
.toBytes("testGetScannerResults" + pad(i
, (byte) 2)), results
.get(i
)
1240 // get 20 rows and check the returned results
1241 scan
.setStopRow(Bytes
.toBytes("testGetScannerResults20"));
1242 results
= handler
.getScannerResults(table
, scan
, 20);
1243 assertEquals(20, results
.size());
1244 for (int i
= 0; i
< 20; i
++) {
1245 // check if the rows are returned and in order
1246 assertArrayEquals(Bytes
.toBytes("testGetScannerResults" + pad(i
, (byte) 2)), results
.get(i
)
1252 scan
.setColumns(columns
);
1253 scan
.setReversed(true);
1254 scan
.setStartRow(Bytes
.toBytes("testGetScannerResults20"));
1255 scan
.setStopRow(Bytes
.toBytes("testGetScannerResults"));
1256 results
= handler
.getScannerResults(table
, scan
, 20);
1257 assertEquals(20, results
.size());
1258 for (int i
= 0; i
< 20; i
++) {
1259 // check if the rows are returned and in order
1260 assertArrayEquals(Bytes
.toBytes("testGetScannerResults" + pad(19 - i
, (byte) 2)),
1261 results
.get(i
).getRow());
1266 public void testFilterRegistration() throws Exception
{
1267 Configuration conf
= UTIL
.getConfiguration();
1268 conf
.set("hbase.thrift.filters", "MyFilter:filterclass");
1269 ThriftServer
.registerFilters(conf
);
1270 Map
<String
, String
> registeredFilters
= ParseFilter
.getAllFilters();
1271 assertEquals("filterclass", registeredFilters
.get("MyFilter"));
1275 public void testMetrics() throws Exception
{
1276 Configuration conf
= UTIL
.getConfiguration();
1277 ThriftMetrics metrics
= getMetrics(conf
);
1278 ThriftHBaseServiceHandler hbaseHandler
= createHandler();
1279 THBaseService
.Iface handler
=
1280 HbaseHandlerMetricsProxy
.newInstance(hbaseHandler
, metrics
, conf
);
1281 byte[] rowName
= Bytes
.toBytes("testMetrics");
1282 ByteBuffer table
= wrap(tableAname
);
1284 TGet get
= new TGet(wrap(rowName
));
1285 assertFalse(handler
.exists(table
, get
));
1287 List
<TColumnValue
> columnValues
= new ArrayList
<>(2);
1288 columnValues
.add(new TColumnValue(wrap(familyAname
), wrap(qualifierAname
), wrap(valueAname
)));
1289 columnValues
.add(new TColumnValue(wrap(familyBname
), wrap(qualifierBname
), wrap(valueBname
)));
1290 TPut put
= new TPut(wrap(rowName
), columnValues
);
1291 put
.setColumnValues(columnValues
);
1293 handler
.put(table
, put
);
1295 assertTrue(handler
.exists(table
, get
));
1296 metricsHelper
.assertCounter("put_num_ops", 1, metrics
.getSource());
1297 metricsHelper
.assertCounter("exists_num_ops", 2, metrics
.getSource());
1300 private static ThriftMetrics
getMetrics(Configuration conf
) throws Exception
{
1301 ThriftMetrics m
= new ThriftMetrics(conf
, ThriftMetrics
.ThriftServerType
.TWO
);
1302 m
.getSource().init(); //Clear all the metrics
1307 public void testMetricsWithException() throws Exception
{
1308 byte[] rowkey
= Bytes
.toBytes("row1");
1309 byte[] family
= Bytes
.toBytes("f");
1310 byte[] col
= Bytes
.toBytes("c");
1311 // create a table which will throw exceptions for requests
1312 TableName tableName
= TableName
.valueOf(name
.getMethodName());
1313 TableDescriptor tableDesc
= TableDescriptorBuilder
.newBuilder(tableName
)
1314 .setCoprocessor(ErrorThrowingGetObserver
.class.getName())
1315 .setColumnFamily(ColumnFamilyDescriptorBuilder
.of(family
)).build();
1317 Table table
= UTIL
.createTable(tableDesc
, null);
1318 table
.put(new Put(rowkey
).addColumn(family
, col
, Bytes
.toBytes("val1")));
1320 ThriftHBaseServiceHandler hbaseHandler
= createHandler();
1321 ThriftMetrics metrics
= getMetrics(UTIL
.getConfiguration());
1322 THBaseService
.Iface handler
=
1323 HbaseHandlerMetricsProxy
.newInstance(hbaseHandler
, metrics
, null);
1324 ByteBuffer tTableName
= wrap(tableName
.getName());
1326 // check metrics increment with a successful get
1327 long preGetCounter
= metricsHelper
.checkCounterExists("get_num_ops", metrics
.getSource()) ?
1328 metricsHelper
.getCounter("get_num_ops", metrics
.getSource()) :
1330 TGet tGet
= new TGet(wrap(rowkey
));
1331 TResult tResult
= handler
.get(tTableName
, tGet
);
1333 List
<TColumnValue
> expectedColumnValues
= Lists
.newArrayList(
1334 new TColumnValue(wrap(family
), wrap(col
), wrap(Bytes
.toBytes("val1")))
1336 assertArrayEquals(rowkey
, tResult
.getRow());
1337 List
<TColumnValue
> returnedColumnValues
= tResult
.getColumnValues();
1338 assertTColumnValuesEqual(expectedColumnValues
, returnedColumnValues
);
1340 metricsHelper
.assertCounter("get_num_ops", preGetCounter
+ 1, metrics
.getSource());
1342 // check metrics increment when the get throws each exception type
1343 for (ErrorThrowingGetObserver
.ErrorType type
: ErrorThrowingGetObserver
.ErrorType
.values()) {
1344 testExceptionType(handler
, metrics
, tTableName
, rowkey
, type
);
1348 private void testExceptionType(THBaseService
.Iface handler
, ThriftMetrics metrics
,
1349 ByteBuffer tTableName
, byte[] rowkey
, ErrorThrowingGetObserver
.ErrorType errorType
) {
1350 long preGetCounter
= metricsHelper
.getCounter("get_num_ops", metrics
.getSource());
1351 String exceptionKey
= errorType
.getMetricName();
1352 long preExceptionCounter
= metricsHelper
.checkCounterExists(exceptionKey
, metrics
.getSource()) ?
1353 metricsHelper
.getCounter(exceptionKey
, metrics
.getSource()) :
1355 TGet tGet
= new TGet(wrap(rowkey
));
1356 Map
<ByteBuffer
, ByteBuffer
> attributes
= new HashMap
<>();
1357 attributes
.put(wrap(Bytes
.toBytes(ErrorThrowingGetObserver
.SHOULD_ERROR_ATTRIBUTE
)),
1358 wrap(Bytes
.toBytes(errorType
.name())));
1359 tGet
.setAttributes(attributes
);
1361 TResult tResult
= handler
.get(tTableName
, tGet
);
1362 fail("Get with error attribute should have thrown an exception");
1363 } catch (TException e
) {
1364 LOG
.info("Received exception: ", e
);
1365 metricsHelper
.assertCounter("get_num_ops", preGetCounter
+ 1, metrics
.getSource());
1366 metricsHelper
.assertCounter(exceptionKey
, preExceptionCounter
+ 1, metrics
.getSource());
1374 * Latency metrics were capped at ~ 2 seconds due to the use of an int variable to capture the
1378 public void testMetricsPrecision() throws Exception
{
1379 byte[] rowkey
= Bytes
.toBytes("row1");
1380 byte[] family
= Bytes
.toBytes("f");
1381 byte[] col
= Bytes
.toBytes("c");
1382 // create a table which will throw exceptions for requests
1383 TableName tableName
= TableName
.valueOf("testMetricsPrecision");
1384 TableDescriptor tableDescriptor
= TableDescriptorBuilder
.newBuilder(tableName
)
1385 .setCoprocessor(DelayingRegionObserver
.class.getName())
1386 .setColumnFamily(ColumnFamilyDescriptorBuilder
.of(family
)).build();
1390 table
= UTIL
.createTable(tableDescriptor
, null);
1392 table
.put(new Put(rowkey
).addColumn(family
, col
, Bytes
.toBytes("val1")));
1394 ThriftHBaseServiceHandler hbaseHandler
= createHandler();
1395 ThriftMetrics metrics
= getMetrics(UTIL
.getConfiguration());
1396 THBaseService
.Iface handler
=
1397 HbaseHandlerMetricsProxy
.newInstance(hbaseHandler
, metrics
, null);
1398 ByteBuffer tTableName
= wrap(tableName
.getName());
1400 // check metrics latency with a successful get
1401 TGet tGet
= new TGet(wrap(rowkey
));
1402 TResult tResult
= handler
.get(tTableName
, tGet
);
1404 List
<TColumnValue
> expectedColumnValues
= Lists
.newArrayList(
1405 new TColumnValue(wrap(family
), wrap(col
), wrap(Bytes
.toBytes("val1")))
1407 assertArrayEquals(rowkey
, tResult
.getRow());
1408 List
<TColumnValue
> returnedColumnValues
= tResult
.getColumnValues();
1409 assertTColumnValuesEqual(expectedColumnValues
, returnedColumnValues
);
1411 metricsHelper
.assertGaugeGt("get_max", 3000L, metrics
.getSource());
1413 if (table
!= null) {
1416 } catch (IOException ignored
) {
1418 UTIL
.deleteTable(tableName
);
1425 public void testAttribute() throws Exception
{
1426 byte[] rowName
= Bytes
.toBytes("testAttribute");
1427 byte[] attributeKey
= Bytes
.toBytes("attribute1");
1428 byte[] attributeValue
= Bytes
.toBytes("value1");
1429 Map
<ByteBuffer
, ByteBuffer
> attributes
= new HashMap
<>();
1430 attributes
.put(wrap(attributeKey
), wrap(attributeValue
));
1432 TGet tGet
= new TGet(wrap(rowName
));
1433 tGet
.setAttributes(attributes
);
1434 Get get
= getFromThrift(tGet
);
1435 assertArrayEquals(get
.getAttribute("attribute1"), attributeValue
);
1437 List
<TColumnValue
> columnValues
= new ArrayList
<>(1);
1438 columnValues
.add(new TColumnValue(wrap(familyAname
), wrap(qualifierAname
), wrap(valueAname
)));
1439 TPut tPut
= new TPut(wrap(rowName
) , columnValues
);
1440 tPut
.setAttributes(attributes
);
1441 Put put
= putFromThrift(tPut
);
1442 assertArrayEquals(put
.getAttribute("attribute1"), attributeValue
);
1444 TScan tScan
= new TScan();
1445 tScan
.setAttributes(attributes
);
1446 Scan scan
= scanFromThrift(tScan
);
1447 assertArrayEquals(scan
.getAttribute("attribute1"), attributeValue
);
1449 List
<TColumnIncrement
> incrementColumns
= new ArrayList
<>(1);
1450 incrementColumns
.add(new TColumnIncrement(wrap(familyAname
), wrap(qualifierAname
)));
1451 TIncrement tIncrement
= new TIncrement(wrap(rowName
), incrementColumns
);
1452 tIncrement
.setAttributes(attributes
);
1453 Increment increment
= incrementFromThrift(tIncrement
);
1454 assertArrayEquals(increment
.getAttribute("attribute1"), attributeValue
);
1456 TDelete tDelete
= new TDelete(wrap(rowName
));
1457 tDelete
.setAttributes(attributes
);
1458 Delete delete
= deleteFromThrift(tDelete
);
1459 assertArrayEquals(delete
.getAttribute("attribute1"), attributeValue
);
1463 * Put valueA to a row, make sure put has happened, then create a mutation object to put valueB
1464 * and delete ValueA, then check that the row value is only valueB.
1467 public void testMutateRow() throws Exception
{
1468 ThriftHBaseServiceHandler handler
= createHandler();
1469 byte[] rowName
= Bytes
.toBytes("testMutateRow");
1470 ByteBuffer table
= wrap(tableAname
);
1472 List
<TColumnValue
> columnValuesA
= new ArrayList
<>(1);
1473 TColumnValue columnValueA
= new TColumnValue(wrap(familyAname
), wrap(qualifierAname
),
1475 columnValuesA
.add(columnValueA
);
1476 TPut putA
= new TPut(wrap(rowName
), columnValuesA
);
1477 putA
.setColumnValues(columnValuesA
);
1479 handler
.put(table
,putA
);
1481 TGet get
= new TGet(wrap(rowName
));
1482 TResult result
= handler
.get(table
, get
);
1483 assertArrayEquals(rowName
, result
.getRow());
1484 List
<TColumnValue
> returnedColumnValues
= result
.getColumnValues();
1486 List
<TColumnValue
> expectedColumnValues
= new ArrayList
<>(1);
1487 expectedColumnValues
.add(columnValueA
);
1488 assertTColumnValuesEqual(expectedColumnValues
, returnedColumnValues
);
1490 List
<TColumnValue
> columnValuesB
= new ArrayList
<>(1);
1491 TColumnValue columnValueB
= new TColumnValue(wrap(familyAname
), wrap(qualifierBname
),
1493 columnValuesB
.add(columnValueB
);
1494 TPut putB
= new TPut(wrap(rowName
), columnValuesB
);
1495 putB
.setColumnValues(columnValuesB
);
1497 TDelete delete
= new TDelete(wrap(rowName
));
1498 List
<TColumn
> deleteColumns
= new ArrayList
<>(1);
1499 TColumn deleteColumn
= new TColumn(wrap(familyAname
));
1500 deleteColumn
.setQualifier(qualifierAname
);
1501 deleteColumns
.add(deleteColumn
);
1502 delete
.setColumns(deleteColumns
);
1504 List
<TMutation
> mutations
= new ArrayList
<>(2);
1505 TMutation mutationA
= TMutation
.put(putB
);
1506 mutations
.add(mutationA
);
1508 TMutation mutationB
= TMutation
.deleteSingle(delete
);
1509 mutations
.add(mutationB
);
1511 TRowMutations tRowMutations
= new TRowMutations(wrap(rowName
),mutations
);
1512 handler
.mutateRow(table
,tRowMutations
);
1514 result
= handler
.get(table
, get
);
1515 assertArrayEquals(rowName
, result
.getRow());
1516 returnedColumnValues
= result
.getColumnValues();
1518 expectedColumnValues
= new ArrayList
<>(1);
1519 expectedColumnValues
.add(columnValueB
);
1520 assertTColumnValuesEqual(expectedColumnValues
, returnedColumnValues
);
1524 * Create TPut, TDelete , TIncrement objects, set durability then call ThriftUtility
1525 * functions to get Put , Delete and Increment respectively. Use getDurability to make sure
1526 * the returned objects have the appropriate durability setting.
1529 public void testDurability() throws Exception
{
1530 byte[] rowName
= Bytes
.toBytes("testDurability");
1531 List
<TColumnValue
> columnValues
= new ArrayList
<>(1);
1532 columnValues
.add(new TColumnValue(wrap(familyAname
), wrap(qualifierAname
), wrap(valueAname
)));
1534 List
<TColumnIncrement
> incrementColumns
= new ArrayList
<>(1);
1535 incrementColumns
.add(new TColumnIncrement(wrap(familyAname
), wrap(qualifierAname
)));
1537 TDelete tDelete
= new TDelete(wrap(rowName
));
1538 tDelete
.setDurability(TDurability
.SKIP_WAL
);
1539 Delete delete
= deleteFromThrift(tDelete
);
1540 assertEquals(Durability
.SKIP_WAL
, delete
.getDurability());
1542 tDelete
.setDurability(TDurability
.ASYNC_WAL
);
1543 delete
= deleteFromThrift(tDelete
);
1544 assertEquals(Durability
.ASYNC_WAL
, delete
.getDurability());
1546 tDelete
.setDurability(TDurability
.SYNC_WAL
);
1547 delete
= deleteFromThrift(tDelete
);
1548 assertEquals(Durability
.SYNC_WAL
, delete
.getDurability());
1550 tDelete
.setDurability(TDurability
.FSYNC_WAL
);
1551 delete
= deleteFromThrift(tDelete
);
1552 assertEquals(Durability
.FSYNC_WAL
, delete
.getDurability());
1554 TPut tPut
= new TPut(wrap(rowName
), columnValues
);
1555 tPut
.setDurability(TDurability
.SKIP_WAL
);
1556 Put put
= putFromThrift(tPut
);
1557 assertEquals(Durability
.SKIP_WAL
, put
.getDurability());
1559 tPut
.setDurability(TDurability
.ASYNC_WAL
);
1560 put
= putFromThrift(tPut
);
1561 assertEquals(Durability
.ASYNC_WAL
, put
.getDurability());
1563 tPut
.setDurability(TDurability
.SYNC_WAL
);
1564 put
= putFromThrift(tPut
);
1565 assertEquals(Durability
.SYNC_WAL
, put
.getDurability());
1567 tPut
.setDurability(TDurability
.FSYNC_WAL
);
1568 put
= putFromThrift(tPut
);
1569 assertEquals(Durability
.FSYNC_WAL
, put
.getDurability());
1571 TIncrement tIncrement
= new TIncrement(wrap(rowName
), incrementColumns
);
1573 tIncrement
.setDurability(TDurability
.SKIP_WAL
);
1574 Increment increment
= incrementFromThrift(tIncrement
);
1575 assertEquals(Durability
.SKIP_WAL
, increment
.getDurability());
1577 tIncrement
.setDurability(TDurability
.ASYNC_WAL
);
1578 increment
= incrementFromThrift(tIncrement
);
1579 assertEquals(Durability
.ASYNC_WAL
, increment
.getDurability());
1581 tIncrement
.setDurability(TDurability
.SYNC_WAL
);
1582 increment
= incrementFromThrift(tIncrement
);
1583 assertEquals(Durability
.SYNC_WAL
, increment
.getDurability());
1585 tIncrement
.setDurability(TDurability
.FSYNC_WAL
);
1586 increment
= incrementFromThrift(tIncrement
);
1587 assertEquals(Durability
.FSYNC_WAL
, increment
.getDurability());
1591 public void testCheckAndMutate() throws Exception
{
1592 ThriftHBaseServiceHandler handler
= createHandler();
1593 ByteBuffer table
= wrap(tableAname
);
1594 ByteBuffer row
= wrap(Bytes
.toBytes("row"));
1595 ByteBuffer family
= wrap(familyAname
);
1596 ByteBuffer qualifier
= wrap(qualifierAname
);
1597 ByteBuffer value
= wrap(valueAname
);
1599 // Create a mutation to write to 'B', our "mutate" of "checkAndMutate"
1600 List
<TColumnValue
> columnValuesB
= new ArrayList
<>(1);
1601 TColumnValue columnValueB
= new TColumnValue(family
, wrap(qualifierBname
), wrap(valueBname
));
1602 columnValuesB
.add(columnValueB
);
1603 TPut putB
= new TPut(row
, columnValuesB
);
1604 putB
.setColumnValues(columnValuesB
);
1606 TRowMutations tRowMutations
= new TRowMutations(row
,
1607 Arrays
.<TMutation
> asList(TMutation
.put(putB
)));
1609 // Empty table when we begin
1610 TResult result
= handler
.get(table
, new TGet(row
));
1611 assertEquals(0, result
.getColumnValuesSize());
1613 // checkAndMutate -- condition should fail because the value doesn't exist.
1614 assertFalse("Expected condition to not pass",
1615 handler
.checkAndMutate(table
, row
, family
, qualifier
, TCompareOperator
.EQUAL
, value
,
1618 List
<TColumnValue
> columnValuesA
= new ArrayList
<>(1);
1619 TColumnValue columnValueA
= new TColumnValue(family
, qualifier
, value
);
1620 columnValuesA
.add(columnValueA
);
1622 // Put an update 'A'
1623 handler
.put(table
, new TPut(row
, columnValuesA
));
1625 // Verify that the update is there
1626 result
= handler
.get(table
, new TGet(row
));
1627 assertEquals(1, result
.getColumnValuesSize());
1628 assertTColumnValueEqual(columnValueA
, result
.getColumnValues().get(0));
1630 // checkAndMutate -- condition should pass since we added the value
1631 assertTrue("Expected condition to pass",
1632 handler
.checkAndMutate(table
, row
, family
, qualifier
, TCompareOperator
.EQUAL
, value
,
1635 result
= handler
.get(table
, new TGet(row
));
1636 assertEquals(2, result
.getColumnValuesSize());
1637 assertTColumnValueEqual(columnValueA
, result
.getColumnValues().get(0));
1638 assertTColumnValueEqual(columnValueB
, result
.getColumnValues().get(1));
1642 public void testConsistency() throws Exception
{
1643 byte[] rowName
= Bytes
.toBytes("testConsistency");
1644 TGet tGet
= new TGet(wrap(rowName
));
1645 tGet
.setConsistency(TConsistency
.STRONG
);
1646 Get get
= getFromThrift(tGet
);
1647 assertEquals(Consistency
.STRONG
, get
.getConsistency());
1649 tGet
.setConsistency(TConsistency
.TIMELINE
);
1650 tGet
.setTargetReplicaId(1);
1651 get
= getFromThrift(tGet
);
1652 assertEquals(Consistency
.TIMELINE
, get
.getConsistency());
1653 assertEquals(1, get
.getReplicaId());
1655 TScan tScan
= new TScan();
1656 tScan
.setConsistency(TConsistency
.STRONG
);
1657 Scan scan
= scanFromThrift(tScan
);
1658 assertEquals(Consistency
.STRONG
, scan
.getConsistency());
1660 tScan
.setConsistency(TConsistency
.TIMELINE
);
1661 tScan
.setTargetReplicaId(1);
1662 scan
= scanFromThrift(tScan
);
1663 assertEquals(Consistency
.TIMELINE
, scan
.getConsistency());
1664 assertEquals(1, scan
.getReplicaId());
1666 TResult tResult
= new TResult();
1667 assertFalse(tResult
.isSetStale());
1668 tResult
.setStale(true);
1669 assertTrue(tResult
.isSetStale());
1673 public void testDDLOpertions() throws Exception
{
1674 String namespace
= "testDDLOpertionsNamespace";
1675 String table
= "testDDLOpertionsTable";
1676 TTableName tTableName
= new TTableName();
1677 tTableName
.setNs(Bytes
.toBytes(namespace
));
1678 tTableName
.setQualifier(Bytes
.toBytes(table
));
1679 ThriftHBaseServiceHandler handler
= createHandler();
1681 TNamespaceDescriptor namespaceDescriptor
= new TNamespaceDescriptor();
1682 namespaceDescriptor
.setName(namespace
);
1683 namespaceDescriptor
.putToConfiguration("key1", "value1");
1684 namespaceDescriptor
.putToConfiguration("key2", "value2");
1685 handler
.createNamespace(namespaceDescriptor
);
1687 List
<TNamespaceDescriptor
> namespaceDescriptors
= handler
.listNamespaceDescriptors();
1688 // should have 3 namespace, default hbase and testDDLOpertionsNamespace
1689 assertTrue(namespaceDescriptors
.size() == 3);
1691 namespaceDescriptor
.putToConfiguration("kye3", "value3");
1692 handler
.modifyNamespace(namespaceDescriptor
);
1694 TNamespaceDescriptor namespaceDescriptorReturned
= handler
.getNamespaceDescriptor(namespace
);
1695 assertTrue(namespaceDescriptorReturned
.getConfiguration().size() == 3);
1697 TTableDescriptor tableDescriptor
= new TTableDescriptor();
1698 tableDescriptor
.setTableName(tTableName
);
1699 TColumnFamilyDescriptor columnFamilyDescriptor1
= new TColumnFamilyDescriptor();
1700 columnFamilyDescriptor1
.setName(familyAname
);
1701 columnFamilyDescriptor1
.setDataBlockEncoding(TDataBlockEncoding
.DIFF
);
1702 tableDescriptor
.addToColumns(columnFamilyDescriptor1
);
1703 List
<ByteBuffer
> splitKeys
= new ArrayList
<>();
1704 splitKeys
.add(ByteBuffer
.wrap(Bytes
.toBytes(5)));
1705 handler
.createTable(tableDescriptor
, splitKeys
);
1707 tableDescriptor
.setDurability(TDurability
.ASYNC_WAL
);
1708 handler
.modifyTable(tableDescriptor
);
1709 //modify column family
1710 columnFamilyDescriptor1
.setInMemory(true);
1711 handler
.modifyColumnFamily(tTableName
, columnFamilyDescriptor1
);
1713 TColumnFamilyDescriptor columnFamilyDescriptor2
= new TColumnFamilyDescriptor();
1714 columnFamilyDescriptor2
.setName(familyBname
);
1715 columnFamilyDescriptor2
.setDataBlockEncoding(TDataBlockEncoding
.PREFIX
);
1716 handler
.addColumnFamily(tTableName
, columnFamilyDescriptor2
);
1717 //get table descriptor
1718 TTableDescriptor tableDescriptorReturned
= handler
.getTableDescriptor(tTableName
);
1719 assertTrue(tableDescriptorReturned
.getColumns().size() == 2);
1720 assertTrue(tableDescriptorReturned
.getDurability() == TDurability
.ASYNC_WAL
);
1721 TColumnFamilyDescriptor columnFamilyDescriptor1Returned
= tableDescriptorReturned
.getColumns()
1722 .stream().filter(desc
-> Bytes
.equals(desc
.getName(), familyAname
)).findFirst().get();
1723 assertTrue(columnFamilyDescriptor1Returned
.isInMemory() == true);
1724 //delete column family
1725 handler
.deleteColumnFamily(tTableName
, ByteBuffer
.wrap(familyBname
));
1726 tableDescriptorReturned
= handler
.getTableDescriptor(tTableName
);
1727 assertTrue(tableDescriptorReturned
.getColumns().size() == 1);
1729 handler
.disableTable(tTableName
);
1730 assertTrue(handler
.isTableDisabled(tTableName
));
1732 handler
.enableTable(tTableName
);
1733 assertTrue(handler
.isTableEnabled(tTableName
));
1734 assertTrue(handler
.isTableAvailable(tTableName
));
1736 handler
.disableTable(tTableName
);
1737 handler
.truncateTable(tTableName
, true);
1738 assertTrue(handler
.isTableAvailable(tTableName
));
1740 handler
.disableTable(tTableName
);
1741 handler
.deleteTable(tTableName
);
1742 assertFalse(handler
.tableExists(tTableName
));
1744 handler
.deleteNamespace(namespace
);
1745 namespaceDescriptors
= handler
.listNamespaceDescriptors();
1746 // should have 2 namespace, default and hbase
1747 assertTrue(namespaceDescriptors
.size() == 2);
1751 public void testGetTableDescriptor() throws Exception
{
1752 ThriftHBaseServiceHandler handler
= createHandler();
1753 TTableDescriptor tableDescriptor
= handler
1754 .getTableDescriptor(ThriftUtilities
.tableNameFromHBase(TableName
.valueOf(tableAname
)));
1755 TableDescriptor table
= ThriftUtilities
.tableDescriptorFromThrift(tableDescriptor
);
1756 assertTrue(table
.getTableName().equals(TableName
.valueOf(tableAname
)));
1757 assertTrue(table
.getColumnFamilies().length
== 2);
1758 assertTrue(table
.getColumnFamily(familyAname
).getMaxVersions() == 3);
1759 assertTrue(table
.getColumnFamily(familyBname
).getMaxVersions() == 2);
1763 public void testGetThriftServerType() throws Exception
{
1764 ThriftHBaseServiceHandler handler
= createHandler();
1765 assertEquals(TThriftServerType
.TWO
, handler
.getThriftServerType());
1769 * Verify that thrift2 client calling thrift server can get the thrift server type correctly.
1772 public void testGetThriftServerOneType() throws Exception
{
1774 // start a thrift server
1775 HBaseThriftTestingUtility THRIFT_TEST_UTIL
= new HBaseThriftTestingUtility();
1777 LOG
.info("Starting HBase Thrift server One");
1778 THRIFT_TEST_UTIL
.startThriftServer(UTIL
.getConfiguration(), ThriftServerType
.ONE
);
1779 try (TTransport transport
= new TSocket(InetAddress
.getLocalHost().getHostName(),
1780 THRIFT_TEST_UTIL
.getServerPort())){
1781 TProtocol protocol
= new TBinaryProtocol(transport
);
1782 // This is our thrift2 client.
1783 THBaseService
.Iface client
= new THBaseService
.Client(protocol
);
1784 // open the transport
1786 assertEquals(TThriftServerType
.ONE
.name(), client
.getThriftServerType().name());
1788 THRIFT_TEST_UTIL
.stopThriftServer();
1793 public void testSlowLogResponses() throws Exception
{
1795 // start a thrift server
1796 HBaseThriftTestingUtility THRIFT_TEST_UTIL
= new HBaseThriftTestingUtility();
1797 Configuration configuration
= UTIL
.getConfiguration();
1798 configuration
.setBoolean("hbase.regionserver.slowlog.buffer.enabled", true);
1800 THRIFT_TEST_UTIL
.startThriftServer(configuration
, ThriftServerType
.ONE
);
1801 ThriftHBaseServiceHandler thriftHBaseServiceHandler
=
1802 new ThriftHBaseServiceHandler(configuration
,
1803 UserProvider
.instantiate(configuration
));
1804 Collection
<ServerName
> serverNames
= UTIL
.getAdmin().getRegionServers();
1805 Set
<TServerName
> tServerNames
=
1806 ThriftUtilities
.getServerNamesFromHBase(new HashSet
<>(serverNames
));
1807 List
<Boolean
> clearedResponses
=
1808 thriftHBaseServiceHandler
.clearSlowLogResponses(tServerNames
);
1809 clearedResponses
.forEach(Assert
::assertTrue
);
1810 TLogQueryFilter tLogQueryFilter
= new TLogQueryFilter();
1811 tLogQueryFilter
.setLimit(15);
1812 Assert
.assertEquals(tLogQueryFilter
.getFilterByOperator(), TFilterByOperator
.OR
);
1813 LogQueryFilter logQueryFilter
= ThriftUtilities
.getSlowLogQueryFromThrift(tLogQueryFilter
);
1814 Assert
.assertEquals(logQueryFilter
.getFilterByOperator(), LogQueryFilter
.FilterByOperator
.OR
);
1815 tLogQueryFilter
.setFilterByOperator(TFilterByOperator
.AND
);
1816 logQueryFilter
= ThriftUtilities
.getSlowLogQueryFromThrift(tLogQueryFilter
);
1817 Assert
.assertEquals(logQueryFilter
.getFilterByOperator(), LogQueryFilter
.FilterByOperator
.AND
);
1818 List
<TOnlineLogRecord
> tLogRecords
=
1819 thriftHBaseServiceHandler
.getSlowLogResponses(tServerNames
, tLogQueryFilter
);
1820 assertEquals(tLogRecords
.size(), 0);
1824 public void testPerformTablePermissions() throws Throwable
{
1825 // initialize fake objects.
1826 String fakeUser
= "user";
1827 TAccessControlEntity tce
= new TAccessControlEntity();
1828 tce
.setActions("R");
1829 tce
.setTableName(Bytes
.toString(tableAname
));
1830 tce
.setScope(TPermissionScope
.TABLE
);
1831 tce
.setUsername(fakeUser
);
1833 ThriftHBaseServiceHandler handler
= createHandler();
1836 List
<UserPermission
> permissionList
= AccessControlClient
.getUserPermissions(UTIL
.getConnection(),
1837 Bytes
.toString(tableAname
), fakeUser
);
1838 // we only grant one R permission
1839 assertEquals(permissionList
.size(), 1);
1841 Permission
.Action
[] actions
= permissionList
.get(0).getPermission().getActions();
1842 assertEquals(actions
.length
, 1);
1843 assertEquals(actions
[0], Permission
.Action
.READ
);
1845 // than revoke the permission
1846 handler
.revoke(tce
);
1847 permissionList
= AccessControlClient
.getUserPermissions(UTIL
.getConnection(),
1848 Bytes
.toString(tableAname
), fakeUser
);
1850 // it should return an empty list
1851 assertEquals(0, permissionList
.size());
1856 public void testPerformNamespacePermissions() throws Throwable
{
1857 // initialize fake objects. We test the permission grant and revoke on default NS.
1858 String fakeUser
= "user";
1859 String defaultNameSpace
= "default";
1860 TAccessControlEntity tce
= new TAccessControlEntity();
1861 tce
.setActions("R");
1862 tce
.setNsName(defaultNameSpace
);
1863 tce
.setScope(TPermissionScope
.NAMESPACE
);
1864 tce
.setUsername(fakeUser
);
1866 ThriftHBaseServiceHandler handler
= createHandler();
1869 List
<UserPermission
> permissionList
= AccessControlClient
.getUserPermissions(UTIL
.getConnection(),
1870 "@" + defaultNameSpace
, fakeUser
);
1872 // we only grant one R permission
1873 assertEquals(permissionList
.size(), 1);
1875 Permission
.Action
[] actions
= permissionList
.get(0).getPermission().getActions();
1876 assertEquals(actions
.length
, 1);
1877 assertEquals(actions
[0], Permission
.Action
.READ
);
1879 // revoke the permission
1880 handler
.revoke(tce
);
1881 permissionList
= AccessControlClient
.getUserPermissions(UTIL
.getConnection(),
1882 "@" + defaultNameSpace
, fakeUser
);
1884 // it should return an empty list
1885 assertEquals(0, permissionList
.size());
1888 public static class DelayingRegionObserver
implements RegionCoprocessor
, RegionObserver
{
1889 private static final Logger LOG
= LoggerFactory
.getLogger(DelayingRegionObserver
.class);
1890 // sleep time in msec
1891 private long delayMillis
;
1894 public Optional
<RegionObserver
> getRegionObserver() {
1895 return Optional
.of(this);
1899 public void start(CoprocessorEnvironment e
) throws IOException
{
1900 this.delayMillis
= e
.getConfiguration()
1901 .getLong("delayingregionobserver.delay", 3000);
1905 public void preGetOp(ObserverContext
<RegionCoprocessorEnvironment
> e
, Get get
,
1906 List
<Cell
> results
) throws IOException
{
1908 long start
= EnvironmentEdgeManager
.currentTime();
1909 TimeUnit
.MILLISECONDS
.sleep(delayMillis
);
1910 if (LOG
.isTraceEnabled()) {
1911 LOG
.trace("Slept for " + (EnvironmentEdgeManager
.currentTime() - start
) + " msec");
1913 } catch (InterruptedException ie
) {
1914 throw new InterruptedIOException("Interrupted while sleeping");