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 java.nio.ByteBuffer.wrap; 021import static org.junit.Assert.assertEquals; 022import static org.junit.Assert.assertFalse; 023import static org.junit.Assert.assertTrue; 024 025import java.io.IOException; 026import java.nio.ByteBuffer; 027import java.util.ArrayList; 028import java.util.Arrays; 029import java.util.List; 030import org.apache.hadoop.conf.Configuration; 031import org.apache.hadoop.hbase.DoNotRetryIOException; 032import org.apache.hadoop.hbase.HBaseClassTestRule; 033import org.apache.hadoop.hbase.HBaseTestingUtil; 034import org.apache.hadoop.hbase.TableName; 035import org.apache.hadoop.hbase.client.Admin; 036import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor; 037import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; 038import org.apache.hadoop.hbase.client.TableDescriptor; 039import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 040import org.apache.hadoop.hbase.security.UserProvider; 041import org.apache.hadoop.hbase.testclassification.ClientTests; 042import org.apache.hadoop.hbase.testclassification.MediumTests; 043import org.apache.hadoop.hbase.thrift2.generated.TAppend; 044import org.apache.hadoop.hbase.thrift2.generated.TColumnIncrement; 045import org.apache.hadoop.hbase.thrift2.generated.TColumnValue; 046import org.apache.hadoop.hbase.thrift2.generated.TCompareOperator; 047import org.apache.hadoop.hbase.thrift2.generated.TDelete; 048import org.apache.hadoop.hbase.thrift2.generated.TGet; 049import org.apache.hadoop.hbase.thrift2.generated.TIOError; 050import org.apache.hadoop.hbase.thrift2.generated.TIncrement; 051import org.apache.hadoop.hbase.thrift2.generated.TMutation; 052import org.apache.hadoop.hbase.thrift2.generated.TPut; 053import org.apache.hadoop.hbase.thrift2.generated.TRowMutations; 054import org.apache.hadoop.hbase.thrift2.generated.TScan; 055import org.apache.hadoop.hbase.util.Bytes; 056import org.apache.thrift.TException; 057import org.junit.AfterClass; 058import org.junit.Before; 059import org.junit.BeforeClass; 060import org.junit.ClassRule; 061import org.junit.Test; 062import org.junit.experimental.categories.Category; 063 064@Category({ ClientTests.class, MediumTests.class }) 065public class TestThriftHBaseServiceHandlerWithReadOnly { 066 067 @ClassRule 068 public static final HBaseClassTestRule CLASS_RULE = 069 HBaseClassTestRule.forClass(TestThriftHBaseServiceHandlerWithReadOnly.class); 070 071 private static final HBaseTestingUtil UTIL = new HBaseTestingUtil(); 072 073 // Static names for tables, columns, rows, and values 074 private static byte[] tableAname = Bytes.toBytes("tableA"); 075 private static byte[] familyAname = Bytes.toBytes("familyA"); 076 private static byte[] familyBname = Bytes.toBytes("familyB"); 077 private static byte[] qualifierAname = Bytes.toBytes("qualifierA"); 078 private static byte[] qualifierBname = Bytes.toBytes("qualifierB"); 079 private static byte[] valueAname = Bytes.toBytes("valueA"); 080 private static byte[] valueBname = Bytes.toBytes("valueB"); 081 private static ColumnFamilyDescriptor[] families = new ColumnFamilyDescriptor[] { 082 ColumnFamilyDescriptorBuilder.newBuilder(familyAname).setMaxVersions(3).build(), 083 ColumnFamilyDescriptorBuilder.newBuilder(familyBname).setMaxVersions(2).build() }; 084 085 @BeforeClass 086 public static void beforeClass() throws Exception { 087 UTIL.getConfiguration().setBoolean("hbase.thrift.readonly", true); 088 UTIL.getConfiguration().set("hbase.client.retries.number", "3"); 089 UTIL.startMiniCluster(); 090 Admin admin = UTIL.getAdmin(); 091 TableDescriptor tableDescriptor = TableDescriptorBuilder 092 .newBuilder(TableName.valueOf(tableAname)).setColumnFamilies(Arrays.asList(families)).build(); 093 admin.createTable(tableDescriptor); 094 admin.close(); 095 } 096 097 @AfterClass 098 public static void afterClass() throws Exception { 099 UTIL.shutdownMiniCluster(); 100 } 101 102 @Before 103 public void setup() throws Exception { 104 105 } 106 107 private ThriftHBaseServiceHandler createHandler() throws TException { 108 try { 109 Configuration conf = UTIL.getConfiguration(); 110 return new ThriftHBaseServiceHandler(conf, UserProvider.instantiate(conf)); 111 } catch (IOException ie) { 112 throw new TException(ie); 113 } 114 } 115 116 @Test 117 public void testExistsWithReadOnly() throws TException { 118 119 ThriftHBaseServiceHandler handler = createHandler(); 120 byte[] rowName = Bytes.toBytes("testExists"); 121 ByteBuffer table = wrap(tableAname); 122 TGet get = new TGet(wrap(rowName)); 123 124 boolean exceptionCaught = false; 125 try { 126 handler.exists(table, get); 127 } catch (TIOError e) { 128 exceptionCaught = true; 129 } finally { 130 assertFalse(exceptionCaught); 131 } 132 } 133 134 @Test 135 public void testExistsAllWithReadOnly() throws TException { 136 ThriftHBaseServiceHandler handler = createHandler(); 137 byte[] rowName1 = Bytes.toBytes("testExistsAll1"); 138 byte[] rowName2 = Bytes.toBytes("testExistsAll2"); 139 ByteBuffer table = wrap(tableAname); 140 141 List<TGet> gets = new ArrayList<>(); 142 gets.add(new TGet(wrap(rowName1))); 143 gets.add(new TGet(wrap(rowName2))); 144 145 boolean exceptionCaught = false; 146 try { 147 handler.existsAll(table, gets); 148 } catch (TIOError e) { 149 exceptionCaught = true; 150 } finally { 151 assertFalse(exceptionCaught); 152 } 153 } 154 155 @Test 156 public void testGetWithReadOnly() throws Exception { 157 ThriftHBaseServiceHandler handler = createHandler(); 158 byte[] rowName = Bytes.toBytes("testGet"); 159 ByteBuffer table = wrap(tableAname); 160 161 TGet get = new TGet(wrap(rowName)); 162 163 boolean exceptionCaught = false; 164 try { 165 handler.get(table, get); 166 } catch (TIOError e) { 167 exceptionCaught = true; 168 } finally { 169 assertFalse(exceptionCaught); 170 } 171 } 172 173 @Test 174 public void testGetMultipleWithReadOnly() throws Exception { 175 ThriftHBaseServiceHandler handler = createHandler(); 176 ByteBuffer table = wrap(tableAname); 177 byte[] rowName1 = Bytes.toBytes("testGetMultiple1"); 178 byte[] rowName2 = Bytes.toBytes("testGetMultiple2"); 179 180 List<TGet> gets = new ArrayList<>(2); 181 gets.add(new TGet(wrap(rowName1))); 182 gets.add(new TGet(wrap(rowName2))); 183 184 boolean exceptionCaught = false; 185 try { 186 handler.getMultiple(table, gets); 187 } catch (TIOError e) { 188 exceptionCaught = true; 189 } finally { 190 assertFalse(exceptionCaught); 191 } 192 } 193 194 @Test 195 public void testPutWithReadOnly() throws Exception { 196 ThriftHBaseServiceHandler handler = createHandler(); 197 ByteBuffer table = wrap(tableAname); 198 byte[] rowName = Bytes.toBytes("testPut"); 199 200 List<TColumnValue> columnValues = new ArrayList<>(2); 201 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname))); 202 columnValues.add(new TColumnValue(wrap(familyBname), wrap(qualifierBname), wrap(valueBname))); 203 TPut put = new TPut(wrap(rowName), columnValues); 204 205 boolean exceptionCaught = false; 206 try { 207 handler.put(table, put); 208 } catch (TIOError e) { 209 exceptionCaught = true; 210 assertTrue(e.getCause() instanceof DoNotRetryIOException); 211 assertEquals("Thrift Server is in Read-only mode.", e.getMessage()); 212 } finally { 213 assertTrue(exceptionCaught); 214 } 215 } 216 217 @Test 218 public void testCheckAndPutWithReadOnly() throws Exception { 219 ThriftHBaseServiceHandler handler = createHandler(); 220 byte[] rowName = Bytes.toBytes("testCheckAndPut"); 221 ByteBuffer table = wrap(tableAname); 222 223 List<TColumnValue> columnValuesA = new ArrayList<>(1); 224 TColumnValue columnValueA = 225 new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname)); 226 columnValuesA.add(columnValueA); 227 TPut putA = new TPut(wrap(rowName), columnValuesA); 228 putA.setColumnValues(columnValuesA); 229 230 List<TColumnValue> columnValuesB = new ArrayList<>(1); 231 TColumnValue columnValueB = 232 new TColumnValue(wrap(familyBname), wrap(qualifierBname), wrap(valueBname)); 233 columnValuesB.add(columnValueB); 234 TPut putB = new TPut(wrap(rowName), columnValuesB); 235 putB.setColumnValues(columnValuesB); 236 237 boolean exceptionCaught = false; 238 try { 239 handler.checkAndPut(table, wrap(rowName), wrap(familyAname), wrap(qualifierAname), 240 wrap(valueAname), putB); 241 } catch (TIOError e) { 242 exceptionCaught = true; 243 assertTrue(e.getCause() instanceof DoNotRetryIOException); 244 assertEquals("Thrift Server is in Read-only mode.", e.getMessage()); 245 } finally { 246 assertTrue(exceptionCaught); 247 } 248 } 249 250 @Test 251 public void testPutMultipleWithReadOnly() throws Exception { 252 ThriftHBaseServiceHandler handler = createHandler(); 253 ByteBuffer table = wrap(tableAname); 254 byte[] rowName1 = Bytes.toBytes("testPutMultiple1"); 255 byte[] rowName2 = Bytes.toBytes("testPutMultiple2"); 256 257 List<TColumnValue> columnValues = new ArrayList<>(2); 258 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname))); 259 columnValues.add(new TColumnValue(wrap(familyBname), wrap(qualifierBname), wrap(valueBname))); 260 List<TPut> puts = new ArrayList<>(2); 261 puts.add(new TPut(wrap(rowName1), columnValues)); 262 puts.add(new TPut(wrap(rowName2), columnValues)); 263 264 boolean exceptionCaught = false; 265 try { 266 handler.putMultiple(table, puts); 267 } catch (TIOError e) { 268 exceptionCaught = true; 269 assertTrue(e.getCause() instanceof DoNotRetryIOException); 270 assertEquals("Thrift Server is in Read-only mode.", e.getMessage()); 271 } finally { 272 assertTrue(exceptionCaught); 273 } 274 } 275 276 @Test 277 public void testDeleteWithReadOnly() throws Exception { 278 ThriftHBaseServiceHandler handler = createHandler(); 279 byte[] rowName = Bytes.toBytes("testDelete"); 280 ByteBuffer table = wrap(tableAname); 281 282 TDelete delete = new TDelete(wrap(rowName)); 283 284 boolean exceptionCaught = false; 285 try { 286 handler.deleteSingle(table, delete); 287 } catch (TIOError e) { 288 exceptionCaught = true; 289 assertTrue(e.getCause() instanceof DoNotRetryIOException); 290 assertEquals("Thrift Server is in Read-only mode.", e.getMessage()); 291 } finally { 292 assertTrue(exceptionCaught); 293 } 294 } 295 296 @Test 297 public void testDeleteMultipleWithReadOnly() throws Exception { 298 ThriftHBaseServiceHandler handler = createHandler(); 299 ByteBuffer table = wrap(tableAname); 300 byte[] rowName1 = Bytes.toBytes("testDeleteMultiple1"); 301 byte[] rowName2 = Bytes.toBytes("testDeleteMultiple2"); 302 303 List<TDelete> deletes = new ArrayList<>(2); 304 deletes.add(new TDelete(wrap(rowName1))); 305 deletes.add(new TDelete(wrap(rowName2))); 306 307 boolean exceptionCaught = false; 308 try { 309 handler.deleteMultiple(table, deletes); 310 } catch (TIOError e) { 311 exceptionCaught = true; 312 assertTrue(e.getCause() instanceof DoNotRetryIOException); 313 assertEquals("Thrift Server is in Read-only mode.", e.getMessage()); 314 } finally { 315 assertTrue(exceptionCaught); 316 } 317 } 318 319 @Test 320 public void testCheckAndMutateWithReadOnly() throws Exception { 321 ThriftHBaseServiceHandler handler = createHandler(); 322 ByteBuffer table = wrap(tableAname); 323 ByteBuffer row = wrap(Bytes.toBytes("row")); 324 ByteBuffer family = wrap(familyAname); 325 ByteBuffer qualifier = wrap(qualifierAname); 326 ByteBuffer value = wrap(valueAname); 327 328 List<TColumnValue> columnValuesB = new ArrayList<>(1); 329 TColumnValue columnValueB = new TColumnValue(family, wrap(qualifierBname), wrap(valueBname)); 330 columnValuesB.add(columnValueB); 331 TPut putB = new TPut(row, columnValuesB); 332 putB.setColumnValues(columnValuesB); 333 334 TRowMutations tRowMutations = 335 new TRowMutations(row, Arrays.<TMutation> asList(TMutation.put(putB))); 336 337 boolean exceptionCaught = false; 338 try { 339 handler.checkAndMutate(table, row, family, qualifier, TCompareOperator.EQUAL, value, 340 tRowMutations); 341 } catch (TIOError e) { 342 exceptionCaught = true; 343 assertTrue(e.getCause() instanceof DoNotRetryIOException); 344 assertEquals("Thrift Server is in Read-only mode.", e.getMessage()); 345 } finally { 346 assertTrue(exceptionCaught); 347 } 348 } 349 350 @Test 351 public void testCheckAndDeleteWithReadOnly() throws Exception { 352 ThriftHBaseServiceHandler handler = createHandler(); 353 byte[] rowName = Bytes.toBytes("testCheckAndDelete"); 354 ByteBuffer table = wrap(tableAname); 355 356 TDelete delete = new TDelete(wrap(rowName)); 357 358 boolean exceptionCaught = false; 359 try { 360 handler.checkAndDelete(table, wrap(rowName), wrap(familyAname), wrap(qualifierAname), 361 wrap(valueAname), delete); 362 } catch (TIOError e) { 363 exceptionCaught = true; 364 assertTrue(e.getCause() instanceof DoNotRetryIOException); 365 assertEquals("Thrift Server is in Read-only mode.", e.getMessage()); 366 } finally { 367 assertTrue(exceptionCaught); 368 } 369 } 370 371 @Test 372 public void testIncrementWithReadOnly() throws Exception { 373 ThriftHBaseServiceHandler handler = createHandler(); 374 byte[] rowName = Bytes.toBytes("testIncrement"); 375 ByteBuffer table = wrap(tableAname); 376 377 List<TColumnIncrement> incrementColumns = new ArrayList<>(1); 378 incrementColumns.add(new TColumnIncrement(wrap(familyAname), wrap(qualifierAname))); 379 TIncrement increment = new TIncrement(wrap(rowName), incrementColumns); 380 381 boolean exceptionCaught = false; 382 try { 383 handler.increment(table, increment); 384 } catch (TIOError e) { 385 exceptionCaught = true; 386 assertTrue(e.getCause() instanceof DoNotRetryIOException); 387 assertEquals("Thrift Server is in Read-only mode.", e.getMessage()); 388 } finally { 389 assertTrue(exceptionCaught); 390 } 391 } 392 393 @Test 394 public void testAppendWithReadOnly() throws Exception { 395 ThriftHBaseServiceHandler handler = createHandler(); 396 byte[] rowName = Bytes.toBytes("testAppend"); 397 ByteBuffer table = wrap(tableAname); 398 byte[] v1 = Bytes.toBytes("42"); 399 400 List<TColumnValue> appendColumns = new ArrayList<>(1); 401 appendColumns.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(v1))); 402 TAppend append = new TAppend(wrap(rowName), appendColumns); 403 404 boolean exceptionCaught = false; 405 try { 406 handler.append(table, append); 407 } catch (TIOError e) { 408 exceptionCaught = true; 409 assertTrue(e.getCause() instanceof DoNotRetryIOException); 410 assertEquals("Thrift Server is in Read-only mode.", e.getMessage()); 411 } finally { 412 assertTrue(exceptionCaught); 413 } 414 } 415 416 @Test 417 public void testMutateRowWithReadOnly() throws Exception { 418 ThriftHBaseServiceHandler handler = createHandler(); 419 byte[] rowName = Bytes.toBytes("testMutateRow"); 420 ByteBuffer table = wrap(tableAname); 421 422 List<TColumnValue> columnValuesA = new ArrayList<>(1); 423 TColumnValue columnValueA = 424 new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname)); 425 columnValuesA.add(columnValueA); 426 TPut putA = new TPut(wrap(rowName), columnValuesA); 427 putA.setColumnValues(columnValuesA); 428 429 TDelete delete = new TDelete(wrap(rowName)); 430 431 List<TMutation> mutations = new ArrayList<>(2); 432 TMutation mutationA = TMutation.put(putA); 433 mutations.add(mutationA); 434 TMutation mutationB = TMutation.deleteSingle(delete); 435 mutations.add(mutationB); 436 TRowMutations tRowMutations = new TRowMutations(wrap(rowName), mutations); 437 438 boolean exceptionCaught = false; 439 try { 440 handler.mutateRow(table, tRowMutations); 441 } catch (TIOError e) { 442 exceptionCaught = true; 443 assertTrue(e.getCause() instanceof DoNotRetryIOException); 444 assertEquals("Thrift Server is in Read-only mode.", e.getMessage()); 445 } finally { 446 assertTrue(exceptionCaught); 447 } 448 } 449 450 @Test 451 public void testScanWithReadOnly() throws Exception { 452 ThriftHBaseServiceHandler handler = createHandler(); 453 ByteBuffer table = wrap(tableAname); 454 455 TScan scan = new TScan(); 456 boolean exceptionCaught = false; 457 try { 458 int scanId = handler.openScanner(table, scan); 459 handler.getScannerRows(scanId, 10); 460 handler.closeScanner(scanId); 461 } catch (TIOError e) { 462 exceptionCaught = true; 463 } finally { 464 assertFalse(exceptionCaught); 465 } 466 } 467}