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