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_NAME;
21 import static org.apache.hadoop.hbase.security.visibility.VisibilityUtils.SYSTEM_LABEL;
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertTrue;
24 import static org.junit.Assert.assertFalse;
25 import static org.junit.Assert.fail;
26
27 import java.io.IOException;
28 import java.security.PrivilegedExceptionAction;
29 import java.util.List;
30 import java.util.concurrent.atomic.AtomicBoolean;
31
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34 import org.apache.hadoop.hbase.HConstants;
35 import org.apache.hadoop.hbase.testclassification.MediumTests;
36 import org.apache.hadoop.hbase.client.Result;
37 import org.apache.hadoop.hbase.client.ResultScanner;
38 import org.apache.hadoop.hbase.client.Scan;
39 import org.apache.hadoop.hbase.client.Table;
40 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
41 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.RegionActionResult;
42 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.NameBytesPair;
43 import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.ListLabelsResponse;
44 import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.VisibilityLabelsResponse;
45 import org.apache.hadoop.hbase.security.User;
46 import org.apache.hadoop.hbase.util.Bytes;
47 import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread;
48 import org.apache.hadoop.hbase.util.Threads;
49 import org.junit.Assert;
50 import org.junit.BeforeClass;
51 import org.junit.Test;
52 import org.junit.experimental.categories.Category;
53 import com.google.protobuf.ByteString;
54
55 @Category(MediumTests.class)
56 public class TestVisibilityLabelsWithDefaultVisLabelService extends TestVisibilityLabels {
57 final Log LOG = LogFactory.getLog(getClass());
58
59 @BeforeClass
60 public static void setupBeforeClass() throws Exception {
61
62 conf = TEST_UTIL.getConfiguration();
63 conf.setBoolean(HConstants.DISTRIBUTED_LOG_REPLAY_KEY, false);
64 conf.setBoolean("hbase.online.schema.update.enable", true);
65 VisibilityTestUtil.enableVisiblityLabels(conf);
66 conf.setClass(VisibilityUtils.VISIBILITY_LABEL_GENERATOR_CLASS, SimpleScanLabelGenerator.class,
67 ScanLabelGenerator.class);
68 conf.set("hbase.superuser", "admin");
69 TEST_UTIL.startMiniCluster(2);
70 SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
71 USER1 = User.createUserForTesting(conf, "user1", new String[] {});
72
73
74 TEST_UTIL.waitTableEnabled(LABELS_TABLE_NAME.getName(), 50000);
75 addLabels();
76 }
77
78 @Test
79 public void testAddLabels() throws Throwable {
80 PrivilegedExceptionAction<VisibilityLabelsResponse> action =
81 new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
82 public VisibilityLabelsResponse run() throws Exception {
83 String[] labels = { "L1", SECRET, "L2", "invalid~", "L3" };
84 VisibilityLabelsResponse response = null;
85 try {
86 response = VisibilityClient.addLabels(conf, labels);
87 } catch (Throwable e) {
88 fail("Should not have thrown exception");
89 }
90 List<RegionActionResult> resultList = response.getResultList();
91 assertEquals(5, resultList.size());
92 assertTrue(resultList.get(0).getException().getValue().isEmpty());
93 assertEquals("org.apache.hadoop.hbase.DoNotRetryIOException", resultList.get(1)
94 .getException().getName());
95 assertTrue(Bytes.toString(resultList.get(1).getException().getValue().toByteArray())
96 .contains(
97 "org.apache.hadoop.hbase.security.visibility.LabelAlreadyExistsException: "
98 + "Label 'secret' already exists"));
99 assertTrue(resultList.get(2).getException().getValue().isEmpty());
100 assertTrue(resultList.get(3).getException().getValue().isEmpty());
101 assertTrue(resultList.get(4).getException().getValue().isEmpty());
102 return null;
103 }
104 };
105 SUPERUSER.runAs(action);
106 }
107
108 @Test(timeout = 60 * 1000)
109 public void testAddVisibilityLabelsOnRSRestart() throws Exception {
110 List<RegionServerThread> regionServerThreads = TEST_UTIL.getHBaseCluster()
111 .getRegionServerThreads();
112 for (RegionServerThread rsThread : regionServerThreads) {
113 rsThread.getRegionServer().abort("Aborting ");
114 }
115
116 RegionServerThread rs = TEST_UTIL.getHBaseCluster().startRegionServer();
117 waitForLabelsRegionAvailability(rs.getRegionServer());
118 final AtomicBoolean vcInitialized = new AtomicBoolean(true);
119 do {
120 PrivilegedExceptionAction<VisibilityLabelsResponse> action =
121 new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
122 public VisibilityLabelsResponse run() throws Exception {
123 String[] labels = { SECRET, CONFIDENTIAL, PRIVATE, "ABC", "XYZ" };
124 try {
125 VisibilityLabelsResponse resp = VisibilityClient.addLabels(conf, labels);
126 List<RegionActionResult> results = resp.getResultList();
127 if (results.get(0).hasException()) {
128 NameBytesPair pair = results.get(0).getException();
129 Throwable t = ProtobufUtil.toException(pair);
130 LOG.debug("Got exception writing labels", t);
131 if (t instanceof VisibilityControllerNotReadyException) {
132 vcInitialized.set(false);
133 LOG.warn("VisibilityController was not yet initialized");
134 Threads.sleep(10);
135 } else {
136 vcInitialized.set(true);
137 }
138 } else LOG.debug("new labels added: " + resp);
139 } catch (Throwable t) {
140 throw new IOException(t);
141 }
142 return null;
143 }
144 };
145 SUPERUSER.runAs(action);
146 } while (!vcInitialized.get());
147
148 Scan s = new Scan();
149 s.setAuthorizations(new Authorizations(VisibilityUtils.SYSTEM_LABEL));
150
151 int i = 0;
152 try (Table ht = TEST_UTIL.getConnection().getTable(LABELS_TABLE_NAME);
153 ResultScanner scanner = ht.getScanner(s)) {
154 while (true) {
155 Result next = scanner.next();
156 if (next == null) {
157 break;
158 }
159 i++;
160 }
161 }
162
163 Assert.assertEquals("The count should be 13", 13, i);
164 }
165
166 @Test
167 public void testListLabels() throws Throwable {
168 PrivilegedExceptionAction<ListLabelsResponse> action =
169 new PrivilegedExceptionAction<ListLabelsResponse>() {
170 public ListLabelsResponse run() throws Exception {
171 ListLabelsResponse response = null;
172 try {
173 response = VisibilityClient.listLabels(conf, null);
174 } catch (Throwable e) {
175 fail("Should not have thrown exception");
176 }
177
178
179
180
181
182 List<ByteString> labels = response.getLabelList();
183 assertEquals(12, labels.size());
184 assertTrue(labels.contains(ByteString.copyFrom(SECRET.getBytes())));
185 assertTrue(labels.contains(ByteString.copyFrom(TOPSECRET.getBytes())));
186 assertTrue(labels.contains(ByteString.copyFrom(CONFIDENTIAL.getBytes())));
187 assertTrue(labels.contains(ByteString.copyFrom("ABC".getBytes())));
188 assertTrue(labels.contains(ByteString.copyFrom("XYZ".getBytes())));
189 assertFalse(labels.contains(ByteString.copyFrom(SYSTEM_LABEL.getBytes())));
190 return null;
191 }
192 };
193 SUPERUSER.runAs(action);
194 }
195
196 @Test
197 public void testListLabelsWithRegEx() throws Throwable {
198 PrivilegedExceptionAction<ListLabelsResponse> action =
199 new PrivilegedExceptionAction<ListLabelsResponse>() {
200 public ListLabelsResponse run() throws Exception {
201 ListLabelsResponse response = null;
202 try {
203 response = VisibilityClient.listLabels(conf, ".*secret");
204 } catch (Throwable e) {
205 fail("Should not have thrown exception");
206 }
207
208 List<ByteString> labels = response.getLabelList();
209 assertEquals(2, labels.size());
210 assertTrue(labels.contains(ByteString.copyFrom(SECRET.getBytes())));
211 assertTrue(labels.contains(ByteString.copyFrom(TOPSECRET.getBytes())));
212 return null;
213 }
214 };
215 SUPERUSER.runAs(action);
216 }
217 }