1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.security.visibility;
19
20 import static org.apache.hadoop.hbase.security.visibility.VisibilityConstants.LABELS_TABLE_FAMILY;
21 import static org.apache.hadoop.hbase.security.visibility.VisibilityConstants.LABELS_TABLE_NAME;
22 import static org.apache.hadoop.hbase.security.visibility.VisibilityConstants.LABEL_QUALIFIER;
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertFalse;
25 import static org.junit.Assert.assertNotNull;
26 import static org.junit.Assert.assertNull;
27 import static org.junit.Assert.assertTrue;
28 import static org.junit.Assert.fail;
29
30 import java.io.IOException;
31 import java.security.PrivilegedExceptionAction;
32 import java.util.ArrayList;
33 import java.util.List;
34
35 import org.apache.hadoop.conf.Configuration;
36 import org.apache.hadoop.hbase.Cell;
37 import org.apache.hadoop.hbase.CellScanner;
38 import org.apache.hadoop.hbase.HBaseTestingUtility;
39 import org.apache.hadoop.hbase.HColumnDescriptor;
40 import org.apache.hadoop.hbase.HConstants;
41 import org.apache.hadoop.hbase.HTableDescriptor;
42 import org.apache.hadoop.hbase.TableName;
43 import org.apache.hadoop.hbase.client.Admin;
44 import org.apache.hadoop.hbase.client.Append;
45 import org.apache.hadoop.hbase.client.Connection;
46 import org.apache.hadoop.hbase.client.ConnectionFactory;
47 import org.apache.hadoop.hbase.client.Get;
48 import org.apache.hadoop.hbase.client.Increment;
49 import org.apache.hadoop.hbase.client.Put;
50 import org.apache.hadoop.hbase.client.Result;
51 import org.apache.hadoop.hbase.client.ResultScanner;
52 import org.apache.hadoop.hbase.client.RowMutations;
53 import org.apache.hadoop.hbase.client.Scan;
54 import org.apache.hadoop.hbase.client.Table;
55 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.RegionActionResult;
56 import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.GetAuthsResponse;
57 import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.VisibilityLabelsResponse;
58 import org.apache.hadoop.hbase.regionserver.BloomType;
59 import org.apache.hadoop.hbase.regionserver.HRegion;
60 import org.apache.hadoop.hbase.regionserver.HRegionServer;
61 import org.apache.hadoop.hbase.security.User;
62 import org.apache.hadoop.hbase.util.Bytes;
63 import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread;
64 import org.junit.After;
65 import org.junit.AfterClass;
66 import org.junit.Rule;
67 import org.junit.Test;
68 import org.junit.rules.TestName;
69
70 import com.google.protobuf.ByteString;
71
72
73
74
75 public abstract class TestVisibilityLabels {
76
77 public static final String TOPSECRET = "topsecret";
78 public static final String PUBLIC = "public";
79 public static final String PRIVATE = "private";
80 public static final String CONFIDENTIAL = "confidential";
81 public static final String SECRET = "secret";
82 public static final String COPYRIGHT = "\u00A9ABC";
83 public static final String ACCENT = "\u0941";
84 public static final String UNICODE_VIS_TAG = COPYRIGHT + "\"" + ACCENT + "\\" + SECRET + "\""
85 + "\u0027&\\";
86 public static final String UC1 = "\u0027\"\u002b";
87 public static final String UC2 = "\u002d\u003f";
88 public static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
89 public static final byte[] row1 = Bytes.toBytes("row1");
90 public static final byte[] row2 = Bytes.toBytes("row2");
91 public static final byte[] row3 = Bytes.toBytes("row3");
92 public static final byte[] row4 = Bytes.toBytes("row4");
93 public final static byte[] fam = Bytes.toBytes("info");
94 public final static byte[] qual = Bytes.toBytes("qual");
95 public final static byte[] value = Bytes.toBytes("value");
96 public static Configuration conf;
97
98 private volatile boolean killedRS = false;
99 @Rule
100 public final TestName TEST_NAME = new TestName();
101 public static User SUPERUSER, USER1;
102
103 @AfterClass
104 public static void tearDownAfterClass() throws Exception {
105 TEST_UTIL.shutdownMiniCluster();
106 }
107
108 @After
109 public void tearDown() throws Exception {
110 killedRS = false;
111 }
112
113 @Test
114 public void testSimpleVisibilityLabels() throws Exception {
115 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
116 try (Table table = createTableAndWriteDataWithLabels(tableName, SECRET + "|" + CONFIDENTIAL,
117 PRIVATE + "|" + CONFIDENTIAL)) {
118 Scan s = new Scan();
119 s.setAuthorizations(new Authorizations(SECRET, CONFIDENTIAL, PRIVATE));
120 ResultScanner scanner = table.getScanner(s);
121 Result[] next = scanner.next(3);
122
123 assertTrue(next.length == 2);
124 CellScanner cellScanner = next[0].cellScanner();
125 cellScanner.advance();
126 Cell current = cellScanner.current();
127 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
128 current.getRowLength(), row1, 0, row1.length));
129 cellScanner = next[1].cellScanner();
130 cellScanner.advance();
131 current = cellScanner.current();
132 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
133 current.getRowLength(), row2, 0, row2.length));
134 }
135 }
136
137 @Test
138 public void testSimpleVisibilityLabelsWithUniCodeCharacters() throws Exception {
139 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
140 try (Table table = createTableAndWriteDataWithLabels(tableName,
141 SECRET + "|" + CellVisibility.quote(COPYRIGHT), "(" + CellVisibility.quote(COPYRIGHT)
142 + "&" + CellVisibility.quote(ACCENT) + ")|" + CONFIDENTIAL,
143 CellVisibility.quote(UNICODE_VIS_TAG) + "&" + SECRET)) {
144 Scan s = new Scan();
145 s.setAuthorizations(new Authorizations(SECRET, CONFIDENTIAL, PRIVATE, COPYRIGHT, ACCENT,
146 UNICODE_VIS_TAG));
147 ResultScanner scanner = table.getScanner(s);
148 Result[] next = scanner.next(3);
149 assertTrue(next.length == 3);
150 CellScanner cellScanner = next[0].cellScanner();
151 cellScanner.advance();
152 Cell current = cellScanner.current();
153 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
154 current.getRowLength(), row1, 0, row1.length));
155 cellScanner = next[1].cellScanner();
156 cellScanner.advance();
157 current = cellScanner.current();
158 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
159 current.getRowLength(), row2, 0, row2.length));
160 cellScanner = next[2].cellScanner();
161 cellScanner.advance();
162 current = cellScanner.current();
163 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
164 current.getRowLength(), row3, 0, row3.length));
165 }
166 }
167
168 @Test
169 public void testAuthorizationsWithSpecialUnicodeCharacters() throws Exception {
170 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
171 try (Table table = createTableAndWriteDataWithLabels(tableName,
172 CellVisibility.quote(UC1) + "|" + CellVisibility.quote(UC2), CellVisibility.quote(UC1),
173 CellVisibility.quote(UNICODE_VIS_TAG))) {
174 Scan s = new Scan();
175 s.setAuthorizations(new Authorizations(UC1, UC2, ACCENT,
176 UNICODE_VIS_TAG));
177 ResultScanner scanner = table.getScanner(s);
178 Result[] next = scanner.next(3);
179 assertTrue(next.length == 3);
180 CellScanner cellScanner = next[0].cellScanner();
181 cellScanner.advance();
182 Cell current = cellScanner.current();
183 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
184 current.getRowLength(), row1, 0, row1.length));
185 cellScanner = next[1].cellScanner();
186 cellScanner.advance();
187 current = cellScanner.current();
188 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
189 current.getRowLength(), row2, 0, row2.length));
190 cellScanner = next[2].cellScanner();
191 cellScanner.advance();
192 current = cellScanner.current();
193 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
194 current.getRowLength(), row3, 0, row3.length));
195 }
196 }
197
198 @Test
199 public void testVisibilityLabelsWithComplexLabels() throws Exception {
200 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
201 try (Table table = createTableAndWriteDataWithLabels(tableName, "(" + SECRET + "|"
202 + CONFIDENTIAL + ")" + "&" + "!" + TOPSECRET, "(" + PRIVATE + "&" + CONFIDENTIAL + "&"
203 + SECRET + ")", "(" + PRIVATE + "&" + CONFIDENTIAL + "&" + SECRET + ")", "(" + PRIVATE
204 + "&" + CONFIDENTIAL + "&" + SECRET + ")")) {
205 Scan s = new Scan();
206 s.setAuthorizations(new Authorizations(TOPSECRET, CONFIDENTIAL, PRIVATE, PUBLIC, SECRET));
207 ResultScanner scanner = table.getScanner(s);
208 Result[] next = scanner.next(4);
209 assertEquals(3, next.length);
210 CellScanner cellScanner = next[0].cellScanner();
211 cellScanner.advance();
212 Cell current = cellScanner.current();
213 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
214 current.getRowLength(), row2, 0, row2.length));
215 cellScanner = next[1].cellScanner();
216 cellScanner.advance();
217 current = cellScanner.current();
218 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
219 current.getRowLength(), row3, 0, row3.length));
220 cellScanner = next[2].cellScanner();
221 cellScanner.advance();
222 current = cellScanner.current();
223 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
224 current.getRowLength(), row4, 0, row4.length));
225 }
226 }
227
228 @Test
229 public void testVisibilityLabelsThatDoesNotPassTheCriteria() throws Exception {
230 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
231 try (Table table = createTableAndWriteDataWithLabels(tableName,
232 "(" + SECRET + "|" + CONFIDENTIAL + ")", PRIVATE)){
233 Scan s = new Scan();
234 s.setAuthorizations(new Authorizations(PUBLIC));
235 ResultScanner scanner = table.getScanner(s);
236 Result[] next = scanner.next(3);
237 assertTrue(next.length == 0);
238 }
239 }
240
241 @Test
242 public void testVisibilityLabelsInPutsThatDoesNotMatchAnyDefinedLabels() throws Exception {
243 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
244 try {
245 createTableAndWriteDataWithLabels(tableName, "SAMPLE_LABEL", "TEST");
246 fail("Should have failed with failed sanity check exception");
247 } catch (Exception e) {
248 }
249 }
250
251 @Test
252 public void testVisibilityLabelsInScanThatDoesNotMatchAnyDefinedLabels() throws Exception {
253 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
254 try ( Table table = createTableAndWriteDataWithLabels(tableName, "(" + SECRET + "|"
255 + CONFIDENTIAL + ")", PRIVATE)){
256 Scan s = new Scan();
257 s.setAuthorizations(new Authorizations("SAMPLE"));
258 ResultScanner scanner = table.getScanner(s);
259 Result[] next = scanner.next(3);
260 assertTrue(next.length == 0);
261 }
262 }
263
264 @Test
265 public void testVisibilityLabelsWithGet() throws Exception {
266 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
267 try (Table table = createTableAndWriteDataWithLabels(tableName, SECRET + "&" + CONFIDENTIAL
268 + "&!" + PRIVATE, SECRET + "&" + CONFIDENTIAL + "&" + PRIVATE)) {
269 Get get = new Get(row1);
270 get.setAuthorizations(new Authorizations(SECRET, CONFIDENTIAL));
271 Result result = table.get(get);
272 assertTrue(!result.isEmpty());
273 Cell cell = result.getColumnLatestCell(fam, qual);
274 assertTrue(Bytes.equals(value, 0, value.length, cell.getValueArray(), cell.getValueOffset(),
275 cell.getValueLength()));
276 }
277 }
278
279 @Test
280 public void testVisibilityLabelsOnKillingOfRSContainingLabelsTable() throws Exception {
281 List<RegionServerThread> regionServerThreads = TEST_UTIL.getHBaseCluster()
282 .getRegionServerThreads();
283 int liveRS = 0;
284 for (RegionServerThread rsThreads : regionServerThreads) {
285 if (!rsThreads.getRegionServer().isAborted()) {
286 liveRS++;
287 }
288 }
289 if (liveRS == 1) {
290 TEST_UTIL.getHBaseCluster().startRegionServer();
291 }
292 Thread t1 = new Thread() {
293 public void run() {
294 List<RegionServerThread> regionServerThreads = TEST_UTIL.getHBaseCluster()
295 .getRegionServerThreads();
296 for (RegionServerThread rsThread : regionServerThreads) {
297 List<HRegion> onlineRegions = rsThread.getRegionServer().getOnlineRegions(
298 LABELS_TABLE_NAME);
299 if (onlineRegions.size() > 0) {
300 rsThread.getRegionServer().abort("Aborting ");
301 killedRS = true;
302 break;
303 }
304 }
305 }
306
307 };
308 t1.start();
309 final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
310 Thread t = new Thread() {
311 public void run() {
312 try {
313 while (!killedRS) {
314 Thread.sleep(1);
315 }
316 createTableAndWriteDataWithLabels(tableName, "(" + SECRET + "|" + CONFIDENTIAL + ")",
317 PRIVATE);
318 } catch (Exception e) {
319 }
320 }
321 };
322 t.start();
323 regionServerThreads = TEST_UTIL.getHBaseCluster().getRegionServerThreads();
324 while (!killedRS) {
325 Thread.sleep(10);
326 }
327 regionServerThreads = TEST_UTIL.getHBaseCluster().getRegionServerThreads();
328 for (RegionServerThread rsThread : regionServerThreads) {
329 while (true) {
330 if (!rsThread.getRegionServer().isAborted()) {
331 List<HRegion> onlineRegions = rsThread.getRegionServer().getOnlineRegions(
332 LABELS_TABLE_NAME);
333 if (onlineRegions.size() > 0) {
334 break;
335 } else {
336 Thread.sleep(10);
337 }
338 } else {
339 break;
340 }
341 }
342 }
343 TEST_UTIL.waitTableEnabled(LABELS_TABLE_NAME.getName(), 50000);
344 t.join();
345 try (Table table = TEST_UTIL.getConnection().getTable(tableName)) {
346 Scan s = new Scan();
347 s.setAuthorizations(new Authorizations(SECRET));
348 ResultScanner scanner = table.getScanner(s);
349 Result[] next = scanner.next(3);
350 assertTrue(next.length == 1);
351 }
352 }
353
354 @Test(timeout = 60 * 1000)
355 public void testVisibilityLabelsOnRSRestart() throws Exception {
356 final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
357 List<RegionServerThread> regionServerThreads = TEST_UTIL.getHBaseCluster()
358 .getRegionServerThreads();
359 for (RegionServerThread rsThread : regionServerThreads) {
360 rsThread.getRegionServer().abort("Aborting ");
361 }
362
363 RegionServerThread rs = TEST_UTIL.getHBaseCluster().startRegionServer();
364 waitForLabelsRegionAvailability(rs.getRegionServer());
365 try (Table table = createTableAndWriteDataWithLabels(tableName, "(" + SECRET + "|" + CONFIDENTIAL
366 + ")", PRIVATE);) {
367 Scan s = new Scan();
368 s.setAuthorizations(new Authorizations(SECRET));
369 ResultScanner scanner = table.getScanner(s);
370 Result[] next = scanner.next(3);
371 assertTrue(next.length == 1);
372 }
373 }
374
375 protected void waitForLabelsRegionAvailability(HRegionServer regionServer) {
376 while (!regionServer.isOnline()) {
377 try {
378 Thread.sleep(10);
379 } catch (InterruptedException e) {
380 }
381 }
382 while (regionServer.getOnlineRegions(LABELS_TABLE_NAME).isEmpty()) {
383 try {
384 Thread.sleep(10);
385 } catch (InterruptedException e) {
386 }
387 }
388 HRegion labelsTableRegion = regionServer.getOnlineRegions(LABELS_TABLE_NAME).get(0);
389 while (labelsTableRegion.isRecovering()) {
390 try {
391 Thread.sleep(10);
392 } catch (InterruptedException e) {
393 }
394 }
395 }
396
397 @Test
398 public void testVisibilityLabelsInGetThatDoesNotMatchAnyDefinedLabels() throws Exception {
399 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
400 try (Table table = createTableAndWriteDataWithLabels(tableName, "(" + SECRET + "|" + CONFIDENTIAL
401 + ")", PRIVATE)) {
402 Get get = new Get(row1);
403 get.setAuthorizations(new Authorizations("SAMPLE"));
404 Result result = table.get(get);
405 assertTrue(result.isEmpty());
406 }
407 }
408
409 @Test
410 public void testSetAndGetUserAuths() throws Throwable {
411 final String user = "user1";
412 PrivilegedExceptionAction<Void> action = new PrivilegedExceptionAction<Void>() {
413 public Void run() throws Exception {
414 String[] auths = { SECRET, CONFIDENTIAL };
415 try {
416 VisibilityClient.setAuths(conf, auths, user);
417 } catch (Throwable e) {
418 }
419 return null;
420 }
421 };
422 SUPERUSER.runAs(action);
423 try (Table ht = TEST_UTIL.getConnection().getTable(LABELS_TABLE_NAME);) {
424 Scan scan = new Scan();
425 scan.setAuthorizations(new Authorizations(VisibilityUtils.SYSTEM_LABEL));
426 ResultScanner scanner = ht.getScanner(scan);
427 Result result = null;
428 List<Result> results = new ArrayList<Result>();
429 while ((result = scanner.next()) != null) {
430 results.add(result);
431 }
432 List<String> auths = extractAuths(user, results);
433 assertTrue(auths.contains(SECRET));
434 assertTrue(auths.contains(CONFIDENTIAL));
435 assertEquals(2, auths.size());
436 }
437
438 action = new PrivilegedExceptionAction<Void>() {
439 public Void run() throws Exception {
440 GetAuthsResponse authsResponse = null;
441 try {
442 authsResponse = VisibilityClient.getAuths(conf, user);
443 } catch (Throwable e) {
444 fail("Should not have failed");
445 }
446 List<String> authsList = new ArrayList<String>();
447 for (ByteString authBS : authsResponse.getAuthList()) {
448 authsList.add(Bytes.toString(authBS.toByteArray()));
449 }
450 assertEquals(2, authsList.size());
451 assertTrue(authsList.contains(SECRET));
452 assertTrue(authsList.contains(CONFIDENTIAL));
453 return null;
454 }
455 };
456 SUPERUSER.runAs(action);
457
458
459 action = new PrivilegedExceptionAction<Void>() {
460 public Void run() throws Exception {
461 String[] auths1 = { SECRET, CONFIDENTIAL };
462 GetAuthsResponse authsResponse = null;
463 try {
464 VisibilityClient.setAuths(conf, auths1, user);
465 try {
466 authsResponse = VisibilityClient.getAuths(conf, user);
467 } catch (Throwable e) {
468 fail("Should not have failed");
469 }
470 } catch (Throwable e) {
471 }
472 List<String> authsList = new ArrayList<String>();
473 for (ByteString authBS : authsResponse.getAuthList()) {
474 authsList.add(Bytes.toString(authBS.toByteArray()));
475 }
476 assertEquals(2, authsList.size());
477 assertTrue(authsList.contains(SECRET));
478 assertTrue(authsList.contains(CONFIDENTIAL));
479 return null;
480 }
481 };
482 SUPERUSER.runAs(action);
483 }
484
485 protected List<String> extractAuths(String user, List<Result> results) {
486 List<String> auths = new ArrayList<String>();
487 for (Result result : results) {
488 Cell labelCell = result.getColumnLatestCell(LABELS_TABLE_FAMILY, LABEL_QUALIFIER);
489 Cell userAuthCell = result.getColumnLatestCell(LABELS_TABLE_FAMILY, user.getBytes());
490 if (userAuthCell != null) {
491 auths.add(Bytes.toString(labelCell.getValueArray(), labelCell.getValueOffset(),
492 labelCell.getValueLength()));
493 }
494 }
495 return auths;
496 }
497
498 @Test
499 public void testClearUserAuths() throws Throwable {
500 PrivilegedExceptionAction<Void> action = new PrivilegedExceptionAction<Void>() {
501 public Void run() throws Exception {
502 String[] auths = { SECRET, CONFIDENTIAL, PRIVATE };
503 String user = "testUser";
504 try {
505 VisibilityClient.setAuths(conf, auths, user);
506 } catch (Throwable e) {
507 fail("Should not have failed");
508 }
509
510
511 auths = new String[] { SECRET, PUBLIC, CONFIDENTIAL };
512 VisibilityLabelsResponse response = null;
513 try {
514 response = VisibilityClient.clearAuths(conf, auths, user);
515 } catch (Throwable e) {
516 fail("Should not have failed");
517 }
518 List<RegionActionResult> resultList = response.getResultList();
519 assertEquals(3, resultList.size());
520 assertTrue(resultList.get(0).getException().getValue().isEmpty());
521 assertEquals("org.apache.hadoop.hbase.DoNotRetryIOException",
522 resultList.get(1).getException().getName());
523 assertTrue(Bytes.toString(resultList.get(1).getException().getValue().toByteArray())
524 .contains(
525 "org.apache.hadoop.hbase.security.visibility.InvalidLabelException: "
526 + "Label 'public' is not set for the user testUser"));
527 assertTrue(resultList.get(2).getException().getValue().isEmpty());
528 try (Connection connection = ConnectionFactory.createConnection(conf);
529 Table ht = connection.getTable(LABELS_TABLE_NAME)) {
530 ResultScanner scanner = ht.getScanner(new Scan());
531 Result result = null;
532 List<Result> results = new ArrayList<Result>();
533 while ((result = scanner.next()) != null) {
534 results.add(result);
535 }
536 List<String> curAuths = extractAuths(user, results);
537 assertTrue(curAuths.contains(PRIVATE));
538 assertEquals(1, curAuths.size());
539 }
540
541 GetAuthsResponse authsResponse = null;
542 try {
543 authsResponse = VisibilityClient.getAuths(conf, user);
544 } catch (Throwable e) {
545 fail("Should not have failed");
546 }
547 List<String> authsList = new ArrayList<String>();
548 for (ByteString authBS : authsResponse.getAuthList()) {
549 authsList.add(Bytes.toString(authBS.toByteArray()));
550 }
551 assertEquals(1, authsList.size());
552 assertTrue(authsList.contains(PRIVATE));
553 return null;
554 }
555 };
556 SUPERUSER.runAs(action);
557 }
558
559 @Test
560 public void testLabelsWithCheckAndPut() throws Throwable {
561 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
562 try (Table table = TEST_UTIL.createTable(tableName, fam)) {
563 byte[] row1 = Bytes.toBytes("row1");
564 Put put = new Put(row1);
565 put.add(fam, qual, HConstants.LATEST_TIMESTAMP, value);
566 put.setCellVisibility(new CellVisibility(SECRET + " & " + CONFIDENTIAL));
567 table.checkAndPut(row1, fam, qual, null, put);
568 byte[] row2 = Bytes.toBytes("row2");
569 put = new Put(row2);
570 put.add(fam, qual, HConstants.LATEST_TIMESTAMP, value);
571 put.setCellVisibility(new CellVisibility(SECRET));
572 table.checkAndPut(row2, fam, qual, null, put);
573
574 Scan scan = new Scan();
575 scan.setAuthorizations(new Authorizations(SECRET));
576 ResultScanner scanner = table.getScanner(scan);
577 Result result = scanner.next();
578 assertTrue(!result.isEmpty());
579 assertTrue(Bytes.equals(row2, result.getRow()));
580 result = scanner.next();
581 assertNull(result);
582 }
583 }
584
585 @Test
586 public void testLabelsWithIncrement() throws Throwable {
587 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
588 try (Table table = TEST_UTIL.createTable(tableName, fam)) {
589 byte[] row1 = Bytes.toBytes("row1");
590 byte[] val = Bytes.toBytes(1L);
591 Put put = new Put(row1);
592 put.add(fam, qual, HConstants.LATEST_TIMESTAMP, val);
593 put.setCellVisibility(new CellVisibility(SECRET + " & " + CONFIDENTIAL));
594 table.put(put);
595 Get get = new Get(row1);
596 get.setAuthorizations(new Authorizations(SECRET));
597 Result result = table.get(get);
598 assertTrue(result.isEmpty());
599 table.incrementColumnValue(row1, fam, qual, 2L);
600 result = table.get(get);
601 assertTrue(result.isEmpty());
602 Increment increment = new Increment(row1);
603 increment.addColumn(fam, qual, 2L);
604 increment.setCellVisibility(new CellVisibility(SECRET));
605 table.increment(increment);
606 result = table.get(get);
607 assertTrue(!result.isEmpty());
608 }
609 }
610
611 @Test
612 public void testLabelsWithAppend() throws Throwable {
613 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
614 try (Table table = TEST_UTIL.createTable(tableName, fam);) {
615 byte[] row1 = Bytes.toBytes("row1");
616 byte[] val = Bytes.toBytes("a");
617 Put put = new Put(row1);
618 put.add(fam, qual, HConstants.LATEST_TIMESTAMP, val);
619 put.setCellVisibility(new CellVisibility(SECRET + " & " + CONFIDENTIAL));
620 table.put(put);
621 Get get = new Get(row1);
622 get.setAuthorizations(new Authorizations(SECRET));
623 Result result = table.get(get);
624 assertTrue(result.isEmpty());
625 Append append = new Append(row1);
626 append.add(fam, qual, Bytes.toBytes("b"));
627 table.append(append);
628 result = table.get(get);
629 assertTrue(result.isEmpty());
630 append = new Append(row1);
631 append.add(fam, qual, Bytes.toBytes("c"));
632 append.setCellVisibility(new CellVisibility(SECRET));
633 table.append(append);
634 result = table.get(get);
635 assertTrue(!result.isEmpty());
636 }
637 }
638
639 @Test
640 public void testUserShouldNotDoDDLOpOnLabelsTable() throws Exception {
641 Admin admin = TEST_UTIL.getHBaseAdmin();
642 try {
643 admin.disableTable(LABELS_TABLE_NAME);
644 fail("Lables table should not get disabled by user.");
645 } catch (Exception e) {
646 }
647 try {
648 admin.deleteTable(LABELS_TABLE_NAME);
649 fail("Lables table should not get disabled by user.");
650 } catch (Exception e) {
651 }
652 try {
653 HColumnDescriptor hcd = new HColumnDescriptor("testFamily");
654 admin.addColumn(LABELS_TABLE_NAME, hcd);
655 fail("Lables table should not get altered by user.");
656 } catch (Exception e) {
657 }
658 try {
659 admin.deleteColumn(LABELS_TABLE_NAME, VisibilityConstants.LABELS_TABLE_FAMILY);
660 fail("Lables table should not get altered by user.");
661 } catch (Exception e) {
662 }
663 try {
664 HColumnDescriptor hcd = new HColumnDescriptor(VisibilityConstants.LABELS_TABLE_FAMILY);
665 hcd.setBloomFilterType(BloomType.ROWCOL);
666 admin.modifyColumn(LABELS_TABLE_NAME, hcd);
667 fail("Lables table should not get altered by user.");
668 } catch (Exception e) {
669 }
670 try {
671 HTableDescriptor htd = new HTableDescriptor(LABELS_TABLE_NAME);
672 htd.addFamily(new HColumnDescriptor("f1"));
673 htd.addFamily(new HColumnDescriptor("f2"));
674 admin.modifyTable(LABELS_TABLE_NAME, htd);
675 fail("Lables table should not get altered by user.");
676 } catch (Exception e) {
677 }
678 }
679
680 @Test
681 public void testMultipleVersions() throws Exception {
682 final byte[] r1 = Bytes.toBytes("row1");
683 final byte[] r2 = Bytes.toBytes("row2");
684 final byte[] v1 = Bytes.toBytes("100");
685 final byte[] v2 = Bytes.toBytes("101");
686 final byte[] fam2 = Bytes.toBytes("info2");
687 final byte[] qual2 = Bytes.toBytes("qual2");
688 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
689 HTableDescriptor desc = new HTableDescriptor(tableName);
690 HColumnDescriptor col = new HColumnDescriptor(fam);
691 desc.addFamily(col);
692 col = new HColumnDescriptor(fam2);
693 col.setMaxVersions(5);
694 desc.addFamily(col);
695 TEST_UTIL.getHBaseAdmin().createTable(desc);
696 try (Table table = TEST_UTIL.getConnection().getTable(tableName)) {
697 Put put = new Put(r1);
698 put.add(fam, qual, 3l, v1);
699 put.add(fam, qual2, 3l, v1);
700 put.add(fam2, qual, 3l, v1);
701 put.add(fam2, qual2, 3l, v1);
702 put.setCellVisibility(new CellVisibility(SECRET));
703 table.put(put);
704 put = new Put(r1);
705 put.add(fam, qual, 4l, v2);
706 put.add(fam, qual2, 4l, v2);
707 put.add(fam2, qual, 4l, v2);
708 put.add(fam2, qual2, 4l, v2);
709 put.setCellVisibility(new CellVisibility(PRIVATE));
710 table.put(put);
711
712 put = new Put(r2);
713 put.add(fam, qual, 3l, v1);
714 put.add(fam, qual2, 3l, v1);
715 put.add(fam2, qual, 3l, v1);
716 put.add(fam2, qual2, 3l, v1);
717 put.setCellVisibility(new CellVisibility(SECRET));
718 table.put(put);
719 put = new Put(r2);
720 put.add(fam, qual, 4l, v2);
721 put.add(fam, qual2, 4l, v2);
722 put.add(fam2, qual, 4l, v2);
723 put.add(fam2, qual2, 4l, v2);
724 put.setCellVisibility(new CellVisibility(SECRET));
725 table.put(put);
726
727 Scan s = new Scan();
728 s.setMaxVersions(1);
729 s.setAuthorizations(new Authorizations(SECRET));
730 ResultScanner scanner = table.getScanner(s);
731 Result result = scanner.next();
732 assertTrue(Bytes.equals(r1, result.getRow()));
733
734
735
736 assertNull(result.getColumnLatestCell(fam, qual));
737 assertNull(result.getColumnLatestCell(fam, qual2));
738
739
740
741
742 Cell cell = result.getColumnLatestCell(fam2, qual);
743 assertNotNull(cell);
744 assertTrue(Bytes.equals(v1, 0, v1.length, cell.getValueArray(), cell.getValueOffset(),
745 cell.getValueLength()));
746 cell = result.getColumnLatestCell(fam2, qual2);
747 assertNotNull(cell);
748 assertTrue(Bytes.equals(v1, 0, v1.length, cell.getValueArray(), cell.getValueOffset(),
749 cell.getValueLength()));
750
751 result = scanner.next();
752 assertTrue(Bytes.equals(r2, result.getRow()));
753 cell = result.getColumnLatestCell(fam, qual);
754 assertNotNull(cell);
755 assertTrue(Bytes.equals(v2, 0, v2.length, cell.getValueArray(), cell.getValueOffset(),
756 cell.getValueLength()));
757 cell = result.getColumnLatestCell(fam, qual2);
758 assertNotNull(cell);
759 assertTrue(Bytes.equals(v2, 0, v2.length, cell.getValueArray(), cell.getValueOffset(),
760 cell.getValueLength()));
761 cell = result.getColumnLatestCell(fam2, qual);
762 assertNotNull(cell);
763 assertTrue(Bytes.equals(v2, 0, v2.length, cell.getValueArray(), cell.getValueOffset(),
764 cell.getValueLength()));
765 cell = result.getColumnLatestCell(fam2, qual2);
766 assertNotNull(cell);
767 assertTrue(Bytes.equals(v2, 0, v2.length, cell.getValueArray(), cell.getValueOffset(),
768 cell.getValueLength()));
769 }
770 }
771
772 @Test
773 public void testMutateRow() throws Exception {
774 final byte[] qual2 = Bytes.toBytes("qual2");
775 TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
776 HTableDescriptor desc = new HTableDescriptor(tableName);
777 HColumnDescriptor col = new HColumnDescriptor(fam);
778 desc.addFamily(col);
779 TEST_UTIL.getHBaseAdmin().createTable(desc);
780 try (Table table = TEST_UTIL.getConnection().getTable(tableName)){
781 Put p1 = new Put(row1);
782 p1.add(fam, qual, value);
783 p1.setCellVisibility(new CellVisibility(CONFIDENTIAL));
784
785 Put p2 = new Put(row1);
786 p2.add(fam, qual2, value);
787 p2.setCellVisibility(new CellVisibility(SECRET));
788
789 RowMutations rm = new RowMutations(row1);
790 rm.add(p1);
791 rm.add(p2);
792
793 table.mutateRow(rm);
794
795 Get get = new Get(row1);
796 get.setAuthorizations(new Authorizations(CONFIDENTIAL));
797 Result result = table.get(get);
798 assertTrue(result.containsColumn(fam, qual));
799 assertFalse(result.containsColumn(fam, qual2));
800
801 get.setAuthorizations(new Authorizations(SECRET));
802 result = table.get(get);
803 assertFalse(result.containsColumn(fam, qual));
804 assertTrue(result.containsColumn(fam, qual2));
805 }
806 }
807
808 static Table createTableAndWriteDataWithLabels(TableName tableName, String... labelExps)
809 throws Exception {
810 List<Put> puts = new ArrayList<Put>();
811 for (int i = 0; i < labelExps.length; i++) {
812 Put put = new Put(Bytes.toBytes("row" + (i+1)));
813 put.add(fam, qual, HConstants.LATEST_TIMESTAMP, value);
814 put.setCellVisibility(new CellVisibility(labelExps[i]));
815 puts.add(put);
816 }
817 Table table = TEST_UTIL.createTable(tableName, fam);
818 table.put(puts);
819 return table;
820 }
821
822 public static void addLabels() throws Exception {
823 PrivilegedExceptionAction<VisibilityLabelsResponse> action =
824 new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
825 public VisibilityLabelsResponse run() throws Exception {
826 String[] labels = { SECRET, TOPSECRET, CONFIDENTIAL, PUBLIC, PRIVATE, COPYRIGHT, ACCENT,
827 UNICODE_VIS_TAG, UC1, UC2 };
828 try {
829 VisibilityClient.addLabels(conf, labels);
830 } catch (Throwable t) {
831 throw new IOException(t);
832 }
833 return null;
834 }
835 };
836 SUPERUSER.runAs(action);
837 }
838 }