1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.hadoop.hbase.rest;
18
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertNotNull;
21
22 import java.io.ByteArrayInputStream;
23 import java.io.IOException;
24 import java.io.StringWriter;
25 import java.security.PrivilegedExceptionAction;
26 import java.util.Iterator;
27 import java.util.Random;
28
29 import javax.xml.bind.JAXBContext;
30 import javax.xml.bind.JAXBException;
31 import javax.xml.bind.Marshaller;
32 import javax.xml.bind.Unmarshaller;
33
34 import org.apache.hadoop.conf.Configuration;
35 import org.apache.hadoop.hbase.HBaseTestingUtility;
36 import org.apache.hadoop.hbase.HColumnDescriptor;
37 import org.apache.hadoop.hbase.HTableDescriptor;
38 import org.apache.hadoop.hbase.KeyValue;
39 import org.apache.hadoop.hbase.testclassification.MediumTests;
40 import org.apache.hadoop.hbase.TableName;
41 import org.apache.hadoop.hbase.client.Durability;
42 import org.apache.hadoop.hbase.client.HBaseAdmin;
43 import org.apache.hadoop.hbase.client.HTable;
44 import org.apache.hadoop.hbase.client.Put;
45 import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.VisibilityLabelsResponse;
46 import org.apache.hadoop.hbase.rest.client.Client;
47 import org.apache.hadoop.hbase.rest.client.Cluster;
48 import org.apache.hadoop.hbase.rest.client.Response;
49 import org.apache.hadoop.hbase.rest.model.CellModel;
50 import org.apache.hadoop.hbase.rest.model.CellSetModel;
51 import org.apache.hadoop.hbase.rest.model.RowModel;
52 import org.apache.hadoop.hbase.rest.model.ScannerModel;
53 import org.apache.hadoop.hbase.security.User;
54 import org.apache.hadoop.hbase.security.visibility.CellVisibility;
55 import org.apache.hadoop.hbase.security.visibility.ScanLabelGenerator;
56 import org.apache.hadoop.hbase.security.visibility.SimpleScanLabelGenerator;
57 import org.apache.hadoop.hbase.security.visibility.VisibilityClient;
58 import org.apache.hadoop.hbase.security.visibility.VisibilityConstants;
59 import org.apache.hadoop.hbase.security.visibility.VisibilityController;
60 import org.apache.hadoop.hbase.security.visibility.VisibilityUtils;
61 import org.apache.hadoop.hbase.util.Bytes;
62 import org.junit.AfterClass;
63 import org.junit.BeforeClass;
64 import org.junit.Test;
65 import org.junit.experimental.categories.Category;
66
67 @Category(MediumTests.class)
68 public class TestScannersWithLabels {
69 private static final String TABLE = "TestScannersWithLabels";
70 private static final String CFA = "a";
71 private static final String CFB = "b";
72 private static final String COLUMN_1 = CFA + ":1";
73 private static final String COLUMN_2 = CFB + ":2";
74 private final static String TOPSECRET = "topsecret";
75 private final static String PUBLIC = "public";
76 private final static String PRIVATE = "private";
77 private final static String CONFIDENTIAL = "confidential";
78 private final static String SECRET = "secret";
79 private static User SUPERUSER;
80
81 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
82 private static final HBaseRESTTestingUtility REST_TEST_UTIL = new HBaseRESTTestingUtility();
83 private static Client client;
84 private static JAXBContext context;
85 private static Marshaller marshaller;
86 private static Unmarshaller unmarshaller;
87 private static Configuration conf;
88
89 private static int insertData(String tableName, String column, double prob) throws IOException {
90 Random rng = new Random();
91 int count = 0;
92 HTable table = new HTable(TEST_UTIL.getConfiguration(), tableName);
93 byte[] k = new byte[3];
94 byte[][] famAndQf = KeyValue.parseColumn(Bytes.toBytes(column));
95
96 for (int i = 0; i < 9; i++) {
97 Put put = new Put(Bytes.toBytes("row" + i));
98 put.setDurability(Durability.SKIP_WAL);
99 put.add(famAndQf[0], famAndQf[1], k);
100 put.setCellVisibility(new CellVisibility("(" + SECRET + "|" + CONFIDENTIAL + ")" + "&" + "!"
101 + TOPSECRET));
102 table.put(put);
103 count++;
104 }
105 table.flushCommits();
106 return count;
107 }
108
109 private static int countCellSet(CellSetModel model) {
110 int count = 0;
111 Iterator<RowModel> rows = model.getRows().iterator();
112 while (rows.hasNext()) {
113 RowModel row = rows.next();
114 Iterator<CellModel> cells = row.getCells().iterator();
115 while (cells.hasNext()) {
116 cells.next();
117 count++;
118 }
119 }
120 return count;
121 }
122
123 @BeforeClass
124 public static void setUpBeforeClass() throws Exception {
125 SUPERUSER = User.createUserForTesting(conf, "admin",
126 new String[] { "supergroup" });
127 conf = TEST_UTIL.getConfiguration();
128 conf.setClass(VisibilityUtils.VISIBILITY_LABEL_GENERATOR_CLASS,
129 SimpleScanLabelGenerator.class, ScanLabelGenerator.class);
130 conf.setInt("hfile.format.version", 3);
131 conf.set("hbase.superuser", SUPERUSER.getShortName());
132 conf.set("hbase.coprocessor.master.classes", VisibilityController.class.getName());
133 conf.set("hbase.coprocessor.region.classes", VisibilityController.class.getName());
134 TEST_UTIL.startMiniCluster(1);
135
136 TEST_UTIL.waitTableEnabled(VisibilityConstants.LABELS_TABLE_NAME.getName(), 50000);
137 createLabels();
138 setAuths();
139 REST_TEST_UTIL.startServletContainer(conf);
140 client = new Client(new Cluster().add("localhost", REST_TEST_UTIL.getServletPort()));
141 context = JAXBContext.newInstance(CellModel.class, CellSetModel.class, RowModel.class,
142 ScannerModel.class);
143 marshaller = context.createMarshaller();
144 unmarshaller = context.createUnmarshaller();
145 HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
146 if (admin.tableExists(TABLE)) {
147 return;
148 }
149 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(TABLE));
150 htd.addFamily(new HColumnDescriptor(CFA));
151 htd.addFamily(new HColumnDescriptor(CFB));
152 admin.createTable(htd);
153 insertData(TABLE, COLUMN_1, 1.0);
154 insertData(TABLE, COLUMN_2, 0.5);
155 }
156
157 @AfterClass
158 public static void tearDownAfterClass() throws Exception {
159 REST_TEST_UTIL.shutdownServletContainer();
160 TEST_UTIL.shutdownMiniCluster();
161 }
162
163 private static void createLabels() throws IOException, InterruptedException {
164 PrivilegedExceptionAction<VisibilityLabelsResponse> action = new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
165 public VisibilityLabelsResponse run() throws Exception {
166 String[] labels = { SECRET, CONFIDENTIAL, PRIVATE, PUBLIC, TOPSECRET };
167 try {
168 VisibilityClient.addLabels(conf, labels);
169 } catch (Throwable t) {
170 throw new IOException(t);
171 }
172 return null;
173 }
174 };
175 SUPERUSER.runAs(action);
176 }
177 private static void setAuths() throws Exception {
178 String[] labels = { SECRET, CONFIDENTIAL, PRIVATE, PUBLIC, TOPSECRET };
179 try {
180 VisibilityClient.setAuths(conf, labels, User.getCurrent().getShortName());
181 } catch (Throwable t) {
182 throw new IOException(t);
183 }
184 }
185 @Test
186 public void testSimpleScannerXMLWithLabelsThatReceivesNoData() throws IOException, JAXBException {
187 final int BATCH_SIZE = 5;
188
189 ScannerModel model = new ScannerModel();
190 model.setBatch(BATCH_SIZE);
191 model.addColumn(Bytes.toBytes(COLUMN_1));
192 model.addLabel(PUBLIC);
193 StringWriter writer = new StringWriter();
194 marshaller.marshal(model, writer);
195 byte[] body = Bytes.toBytes(writer.toString());
196
197 conf.set("hbase.rest.readonly", "false");
198 Response response = client.put("/" + TABLE + "/scanner", Constants.MIMETYPE_XML, body);
199 assertEquals(response.getCode(), 201);
200 String scannerURI = response.getLocation();
201 assertNotNull(scannerURI);
202
203
204 response = client.get(scannerURI, Constants.MIMETYPE_XML);
205
206 assertEquals(response.getCode(), 204);
207 assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
208 }
209
210 @Test
211 public void testSimpleScannerXMLWithLabelsThatReceivesData() throws IOException, JAXBException {
212
213 ScannerModel model = new ScannerModel();
214 model.setBatch(5);
215 model.addColumn(Bytes.toBytes(COLUMN_1));
216 model.addLabel(SECRET);
217 StringWriter writer = new StringWriter();
218 marshaller.marshal(model, writer);
219 byte[] body = Bytes.toBytes(writer.toString());
220
221
222 conf.set("hbase.rest.readonly", "false");
223 Response response = client.put("/" + TABLE + "/scanner", Constants.MIMETYPE_XML, body);
224 assertEquals(response.getCode(), 201);
225 String scannerURI = response.getLocation();
226 assertNotNull(scannerURI);
227
228
229 response = client.get(scannerURI, Constants.MIMETYPE_XML);
230
231 assertEquals(response.getCode(), 200);
232 assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
233 CellSetModel cellSet = (CellSetModel) unmarshaller.unmarshal(new ByteArrayInputStream(response
234 .getBody()));
235 assertEquals(countCellSet(cellSet), 5);
236 }
237
238 }