2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package org
.apache
.hadoop
.hbase
.rest
;
20 import static org
.junit
.Assert
.assertEquals
;
21 import static org
.junit
.Assert
.assertNotNull
;
23 import java
.io
.ByteArrayInputStream
;
24 import java
.io
.IOException
;
25 import java
.io
.StringWriter
;
26 import java
.security
.PrivilegedExceptionAction
;
27 import java
.util
.ArrayList
;
28 import java
.util
.Iterator
;
29 import java
.util
.List
;
30 import javax
.xml
.bind
.JAXBContext
;
31 import javax
.xml
.bind
.JAXBException
;
32 import javax
.xml
.bind
.Marshaller
;
33 import javax
.xml
.bind
.Unmarshaller
;
34 import org
.apache
.hadoop
.conf
.Configuration
;
35 import org
.apache
.hadoop
.hbase
.CellUtil
;
36 import org
.apache
.hadoop
.hbase
.HBaseClassTestRule
;
37 import org
.apache
.hadoop
.hbase
.HBaseTestingUtil
;
38 import org
.apache
.hadoop
.hbase
.TableName
;
39 import org
.apache
.hadoop
.hbase
.client
.Admin
;
40 import org
.apache
.hadoop
.hbase
.client
.ColumnFamilyDescriptor
;
41 import org
.apache
.hadoop
.hbase
.client
.ColumnFamilyDescriptorBuilder
;
42 import org
.apache
.hadoop
.hbase
.client
.Connection
;
43 import org
.apache
.hadoop
.hbase
.client
.ConnectionFactory
;
44 import org
.apache
.hadoop
.hbase
.client
.Durability
;
45 import org
.apache
.hadoop
.hbase
.client
.Put
;
46 import org
.apache
.hadoop
.hbase
.client
.Table
;
47 import org
.apache
.hadoop
.hbase
.client
.TableDescriptorBuilder
;
48 import org
.apache
.hadoop
.hbase
.shaded
.protobuf
.generated
.VisibilityLabelsProtos
.VisibilityLabelsResponse
;
49 import org
.apache
.hadoop
.hbase
.rest
.client
.Client
;
50 import org
.apache
.hadoop
.hbase
.rest
.client
.Cluster
;
51 import org
.apache
.hadoop
.hbase
.rest
.client
.Response
;
52 import org
.apache
.hadoop
.hbase
.rest
.model
.CellModel
;
53 import org
.apache
.hadoop
.hbase
.rest
.model
.CellSetModel
;
54 import org
.apache
.hadoop
.hbase
.rest
.model
.RowModel
;
55 import org
.apache
.hadoop
.hbase
.rest
.model
.ScannerModel
;
56 import org
.apache
.hadoop
.hbase
.security
.User
;
57 import org
.apache
.hadoop
.hbase
.security
.visibility
.CellVisibility
;
58 import org
.apache
.hadoop
.hbase
.security
.visibility
.ScanLabelGenerator
;
59 import org
.apache
.hadoop
.hbase
.security
.visibility
.SimpleScanLabelGenerator
;
60 import org
.apache
.hadoop
.hbase
.security
.visibility
.VisibilityClient
;
61 import org
.apache
.hadoop
.hbase
.security
.visibility
.VisibilityConstants
;
62 import org
.apache
.hadoop
.hbase
.security
.visibility
.VisibilityTestUtil
;
63 import org
.apache
.hadoop
.hbase
.security
.visibility
.VisibilityUtils
;
64 import org
.apache
.hadoop
.hbase
.testclassification
.MediumTests
;
65 import org
.apache
.hadoop
.hbase
.testclassification
.RestTests
;
66 import org
.apache
.hadoop
.hbase
.util
.Bytes
;
67 import org
.junit
.AfterClass
;
68 import org
.junit
.BeforeClass
;
69 import org
.junit
.ClassRule
;
70 import org
.junit
.Test
;
71 import org
.junit
.experimental
.categories
.Category
;
73 @Category({RestTests
.class, MediumTests
.class})
74 public class TestScannersWithLabels
{
76 public static final HBaseClassTestRule CLASS_RULE
=
77 HBaseClassTestRule
.forClass(TestScannersWithLabels
.class);
79 private static final TableName TABLE
= TableName
.valueOf("TestScannersWithLabels");
80 private static final String CFA
= "a";
81 private static final String CFB
= "b";
82 private static final String COLUMN_1
= CFA
+ ":1";
83 private static final String COLUMN_2
= CFB
+ ":2";
84 private final static String TOPSECRET
= "topsecret";
85 private final static String PUBLIC
= "public";
86 private final static String PRIVATE
= "private";
87 private final static String CONFIDENTIAL
= "confidential";
88 private final static String SECRET
= "secret";
89 private static User SUPERUSER
;
91 private static final HBaseTestingUtil TEST_UTIL
= new HBaseTestingUtil();
92 private static final HBaseRESTTestingUtility REST_TEST_UTIL
= new HBaseRESTTestingUtility();
93 private static Client client
;
94 private static JAXBContext context
;
95 private static Marshaller marshaller
;
96 private static Unmarshaller unmarshaller
;
97 private static Configuration conf
;
99 private static int insertData(TableName tableName
, String column
, double prob
)
101 byte[] k
= new byte[3];
102 byte[][] famAndQf
= CellUtil
.parseColumn(Bytes
.toBytes(column
));
104 List
<Put
> puts
= new ArrayList
<>(9);
105 for (int i
= 0; i
< 9; i
++) {
106 Put put
= new Put(Bytes
.toBytes("row" + i
));
107 put
.setDurability(Durability
.SKIP_WAL
);
108 put
.addColumn(famAndQf
[0], famAndQf
[1], k
);
109 put
.setCellVisibility(new CellVisibility("(" + SECRET
+ "|" + CONFIDENTIAL
+ ")" + "&" + "!"
113 try (Table table
= TEST_UTIL
.getConnection().getTable(tableName
)) {
119 private static int countCellSet(CellSetModel model
) {
121 Iterator
<RowModel
> rows
= model
.getRows().iterator();
122 while (rows
.hasNext()) {
123 RowModel row
= rows
.next();
124 Iterator
<CellModel
> cells
= row
.getCells().iterator();
125 while (cells
.hasNext()) {
134 public static void setUpBeforeClass() throws Exception
{
135 SUPERUSER
= User
.createUserForTesting(conf
, "admin",
136 new String
[] { "supergroup" });
137 conf
= TEST_UTIL
.getConfiguration();
138 conf
.setClass(VisibilityUtils
.VISIBILITY_LABEL_GENERATOR_CLASS
,
139 SimpleScanLabelGenerator
.class, ScanLabelGenerator
.class);
140 conf
.set("hbase.superuser", SUPERUSER
.getShortName());
141 VisibilityTestUtil
.enableVisiblityLabels(conf
);
142 TEST_UTIL
.startMiniCluster(1);
143 // Wait for the labels table to become available
144 TEST_UTIL
.waitTableEnabled(VisibilityConstants
.LABELS_TABLE_NAME
.getName(), 50000);
147 REST_TEST_UTIL
.startServletContainer(conf
);
148 client
= new Client(new Cluster().add("localhost", REST_TEST_UTIL
.getServletPort()));
149 context
= JAXBContext
.newInstance(CellModel
.class, CellSetModel
.class, RowModel
.class,
151 marshaller
= context
.createMarshaller();
152 unmarshaller
= context
.createUnmarshaller();
153 Admin admin
= TEST_UTIL
.getAdmin();
154 if (admin
.tableExists(TABLE
)) {
157 TableDescriptorBuilder tableDescriptorBuilder
=
158 TableDescriptorBuilder
.newBuilder(TABLE
);
159 ColumnFamilyDescriptor columnFamilyDescriptor
=
160 ColumnFamilyDescriptorBuilder
.newBuilder(Bytes
.toBytes(CFA
)).build();
161 tableDescriptorBuilder
.setColumnFamily(columnFamilyDescriptor
);
162 columnFamilyDescriptor
=
163 ColumnFamilyDescriptorBuilder
.newBuilder(Bytes
.toBytes(CFB
)).build();
164 tableDescriptorBuilder
.setColumnFamily(columnFamilyDescriptor
);
165 admin
.createTable(tableDescriptorBuilder
.build());
166 insertData(TABLE
, COLUMN_1
, 1.0);
167 insertData(TABLE
, COLUMN_2
, 0.5);
171 public static void tearDownAfterClass() throws Exception
{
172 REST_TEST_UTIL
.shutdownServletContainer();
173 TEST_UTIL
.shutdownMiniCluster();
176 private static void createLabels() throws IOException
, InterruptedException
{
177 PrivilegedExceptionAction
<VisibilityLabelsResponse
> action
= () -> {
178 String
[] labels
= { SECRET
, CONFIDENTIAL
, PRIVATE
, PUBLIC
, TOPSECRET
};
179 try (Connection conn
= ConnectionFactory
.createConnection(conf
)) {
180 VisibilityClient
.addLabels(conn
, labels
);
181 } catch (Throwable t
) {
182 throw new IOException(t
);
186 SUPERUSER
.runAs(action
);
189 private static void setAuths() throws Exception
{
190 String
[] labels
= { SECRET
, CONFIDENTIAL
, PRIVATE
, PUBLIC
, TOPSECRET
};
191 try (Connection conn
= ConnectionFactory
.createConnection(conf
)) {
192 VisibilityClient
.setAuths(conn
, labels
, User
.getCurrent().getShortName());
193 } catch (Throwable t
) {
194 throw new IOException(t
);
199 public void testSimpleScannerXMLWithLabelsThatReceivesNoData() throws IOException
, JAXBException
{
200 final int BATCH_SIZE
= 5;
202 ScannerModel model
= new ScannerModel();
203 model
.setBatch(BATCH_SIZE
);
204 model
.addColumn(Bytes
.toBytes(COLUMN_1
));
205 model
.addLabel(PUBLIC
);
206 StringWriter writer
= new StringWriter();
207 marshaller
.marshal(model
, writer
);
208 byte[] body
= Bytes
.toBytes(writer
.toString());
209 // recall previous put operation with read-only off
210 conf
.set("hbase.rest.readonly", "false");
211 Response response
= client
.put("/" + TABLE
+ "/scanner", Constants
.MIMETYPE_XML
, body
);
212 assertEquals(201, response
.getCode());
213 String scannerURI
= response
.getLocation();
214 assertNotNull(scannerURI
);
217 response
= client
.get(scannerURI
, Constants
.MIMETYPE_XML
);
218 // Respond with 204 as there are no cells to be retrieved
219 assertEquals(204, response
.getCode());
220 // With no content in the payload, the 'Content-Type' header is not echo back
224 public void testSimpleScannerXMLWithLabelsThatReceivesData() throws IOException
, JAXBException
{
226 ScannerModel model
= new ScannerModel();
228 model
.addColumn(Bytes
.toBytes(COLUMN_1
));
229 model
.addLabel(SECRET
);
230 StringWriter writer
= new StringWriter();
231 marshaller
.marshal(model
, writer
);
232 byte[] body
= Bytes
.toBytes(writer
.toString());
234 // recall previous put operation with read-only off
235 conf
.set("hbase.rest.readonly", "false");
236 Response response
= client
.put("/" + TABLE
+ "/scanner", Constants
.MIMETYPE_XML
, body
);
237 assertEquals(201, response
.getCode());
238 String scannerURI
= response
.getLocation();
239 assertNotNull(scannerURI
);
242 response
= client
.get(scannerURI
, Constants
.MIMETYPE_XML
);
243 // Respond with 204 as there are no cells to be retrieved
244 assertEquals(200, response
.getCode());
245 assertEquals(Constants
.MIMETYPE_XML
, response
.getHeader("content-type"));
246 CellSetModel cellSet
= (CellSetModel
) unmarshaller
.unmarshal(new ByteArrayInputStream(response
248 assertEquals(5, countCellSet(cellSet
));