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 = 080 new HColumnDescriptor[] { new HColumnDescriptor(familyAname).setMaxVersions(3), 081 new HColumnDescriptor(familyBname).setMaxVersions(2) }; 082 083 @BeforeClass 084 public static void beforeClass() throws Exception { 085 UTIL.getConfiguration().setBoolean("hbase.thrift.readonly", true); 086 UTIL.getConfiguration().set("hbase.client.retries.number", "3"); 087 UTIL.startMiniCluster(); 088 Admin admin = UTIL.getAdmin(); 089 HTableDescriptor tableDescriptor = new HTableDescriptor(TableName.valueOf(tableAname)); 090 for (HColumnDescriptor family : families) { 091 tableDescriptor.addFamily(family); 092 } 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, TCompareOp.EQUAL, value, tRowMutations); 340 } catch (TIOError e) { 341 exceptionCaught = true; 342 assertTrue(e.getCause() instanceof DoNotRetryIOException); 343 assertEquals("Thrift Server is in Read-only mode.", e.getMessage()); 344 } finally { 345 assertTrue(exceptionCaught); 346 } 347 } 348 349 @Test 350 public void testCheckAndDeleteWithReadOnly() throws Exception { 351 ThriftHBaseServiceHandler handler = createHandler(); 352 byte[] rowName = Bytes.toBytes("testCheckAndDelete"); 353 ByteBuffer table = wrap(tableAname); 354 355 TDelete delete = new TDelete(wrap(rowName)); 356 357 boolean exceptionCaught = false; 358 try { 359 handler.checkAndDelete(table, wrap(rowName), wrap(familyAname), wrap(qualifierAname), 360 wrap(valueAname), delete); 361 } catch (TIOError e) { 362 exceptionCaught = true; 363 assertTrue(e.getCause() instanceof DoNotRetryIOException); 364 assertEquals("Thrift Server is in Read-only mode.", e.getMessage()); 365 } finally { 366 assertTrue(exceptionCaught); 367 } 368 } 369 370 @Test 371 public void testIncrementWithReadOnly() throws Exception { 372 ThriftHBaseServiceHandler handler = createHandler(); 373 byte[] rowName = Bytes.toBytes("testIncrement"); 374 ByteBuffer table = wrap(tableAname); 375 376 List<TColumnIncrement> incrementColumns = new ArrayList<>(1); 377 incrementColumns.add(new TColumnIncrement(wrap(familyAname), wrap(qualifierAname))); 378 TIncrement increment = new TIncrement(wrap(rowName), incrementColumns); 379 380 boolean exceptionCaught = false; 381 try { 382 handler.increment(table, increment); 383 } catch (TIOError e) { 384 exceptionCaught = true; 385 assertTrue(e.getCause() instanceof DoNotRetryIOException); 386 assertEquals("Thrift Server is in Read-only mode.", e.getMessage()); 387 } finally { 388 assertTrue(exceptionCaught); 389 } 390 } 391 392 @Test 393 public void testAppendWithReadOnly() throws Exception { 394 ThriftHBaseServiceHandler handler = createHandler(); 395 byte[] rowName = Bytes.toBytes("testAppend"); 396 ByteBuffer table = wrap(tableAname); 397 byte[] v1 = Bytes.toBytes("42"); 398 399 List<TColumnValue> appendColumns = new ArrayList<>(1); 400 appendColumns.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(v1))); 401 TAppend append = new TAppend(wrap(rowName), appendColumns); 402 403 boolean exceptionCaught = false; 404 try { 405 handler.append(table, append); 406 } catch (TIOError e) { 407 exceptionCaught = true; 408 assertTrue(e.getCause() instanceof DoNotRetryIOException); 409 assertEquals("Thrift Server is in Read-only mode.", e.getMessage()); 410 } finally { 411 assertTrue(exceptionCaught); 412 } 413 } 414 415 @Test 416 public void testMutateRowWithReadOnly() throws Exception { 417 ThriftHBaseServiceHandler handler = createHandler(); 418 byte[] rowName = Bytes.toBytes("testMutateRow"); 419 ByteBuffer table = wrap(tableAname); 420 421 List<TColumnValue> columnValuesA = new ArrayList<>(1); 422 TColumnValue columnValueA = 423 new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname)); 424 columnValuesA.add(columnValueA); 425 TPut putA = new TPut(wrap(rowName), columnValuesA); 426 putA.setColumnValues(columnValuesA); 427 428 TDelete delete = new TDelete(wrap(rowName)); 429 430 List<TMutation> mutations = new ArrayList<>(2); 431 TMutation mutationA = TMutation.put(putA); 432 mutations.add(mutationA); 433 TMutation mutationB = TMutation.deleteSingle(delete); 434 mutations.add(mutationB); 435 TRowMutations tRowMutations = new TRowMutations(wrap(rowName), mutations); 436 437 boolean exceptionCaught = false; 438 try { 439 handler.mutateRow(table, tRowMutations); 440 } catch (TIOError e) { 441 exceptionCaught = true; 442 assertTrue(e.getCause() instanceof DoNotRetryIOException); 443 assertEquals("Thrift Server is in Read-only mode.", e.getMessage()); 444 } finally { 445 assertTrue(exceptionCaught); 446 } 447 } 448 449 @Test 450 public void testScanWithReadOnly() throws Exception { 451 ThriftHBaseServiceHandler handler = createHandler(); 452 ByteBuffer table = wrap(tableAname); 453 454 TScan scan = new TScan(); 455 boolean exceptionCaught = false; 456 try { 457 int scanId = handler.openScanner(table, scan); 458 handler.getScannerRows(scanId, 10); 459 handler.closeScanner(scanId); 460 } catch (TIOError e) { 461 exceptionCaught = true; 462 } finally { 463 assertFalse(exceptionCaught); 464 } 465 } 466}